Files
fidc-backtest-engine/crates/fidc-core/src/calendar.rs
2026-04-18 18:02:50 +08:00

60 lines
1.4 KiB
Rust

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()
}
}