use std::collections::HashMap; use chrono::NaiveDate; #[derive(Debug, Clone)] pub struct TradingCalendar { days: Vec, index: HashMap, } impl TradingCalendar { pub fn new(mut days: Vec) -> 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 + '_ { 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 { self.index.get(&date).copied() } pub fn previous_day(&self, date: NaiveDate) -> Option { 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 { 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() } }