初始化回测核心引擎骨架
This commit is contained in:
58
crates/fidc-core/src/calendar.rs
Normal file
58
crates/fidc-core/src/calendar.rs
Normal file
@@ -0,0 +1,58 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use chrono::NaiveDate;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct TradingCalendar {
|
||||
days: Vec<NaiveDate>,
|
||||
index: HashMap<NaiveDate, usize>,
|
||||
}
|
||||
|
||||
impl TradingCalendar {
|
||||
pub fn new(mut days: Vec<NaiveDate>) -> Self {
|
||||
days.sort_unstable();
|
||||
days.dedup();
|
||||
|
||||
let index = days
|
||||
.iter()
|
||||
.copied()
|
||||
.enumerate()
|
||||
.map(|(idx, day)| (day, idx))
|
||||
.collect();
|
||||
|
||||
Self { days, index }
|
||||
}
|
||||
|
||||
pub fn days(&self) -> &[NaiveDate] {
|
||||
&self.days
|
||||
}
|
||||
|
||||
pub fn iter(&self) -> impl Iterator<Item = NaiveDate> + '_ {
|
||||
self.days.iter().copied()
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize {
|
||||
self.days.len()
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.days.is_empty()
|
||||
}
|
||||
|
||||
pub fn index_of(&self, date: NaiveDate) -> Option<usize> {
|
||||
self.index.get(&date).copied()
|
||||
}
|
||||
|
||||
pub fn previous_day(&self, date: NaiveDate) -> Option<NaiveDate> {
|
||||
let idx = self.index_of(date)?;
|
||||
idx.checked_sub(1).and_then(|prev| self.days.get(prev).copied())
|
||||
}
|
||||
|
||||
pub fn trailing_days(&self, end: NaiveDate, lookback: usize) -> Vec<NaiveDate> {
|
||||
let Some(end_idx) = self.index_of(end) else {
|
||||
return Vec::new();
|
||||
};
|
||||
let start = end_idx.saturating_add(1).saturating_sub(lookback);
|
||||
self.days[start..=end_idx].to_vec()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user