From 99188487b837e11e330f3e517ad6203260d4e716 Mon Sep 17 00:00:00 2001 From: boris Date: Fri, 24 Apr 2026 04:24:32 -0700 Subject: [PATCH] perf: cache daily history by symbol --- crates/fidc-core/src/data.rs | 46 +++++++++++++++++++++--------------- 1 file changed, 27 insertions(+), 19 deletions(-) diff --git a/crates/fidc-core/src/data.rs b/crates/fidc-core/src/data.rs index 777f789..3c518d3 100644 --- a/crates/fidc-core/src/data.rs +++ b/crates/fidc-core/src/data.rs @@ -446,6 +446,7 @@ pub struct EligibleUniverseSnapshot { #[derive(Debug, Clone)] struct SymbolPriceSeries { + snapshots: Vec, dates: Vec, opens: Vec, closes: Vec, @@ -479,6 +480,7 @@ impl SymbolPriceSeries { let volume_prefix = prefix_sums(&volumes); Self { + snapshots: sorted, dates, opens, closes, @@ -514,6 +516,27 @@ impl SymbolPriceSeries { self.values_for(field)[start..end].to_vec() } + fn trailing_snapshots( + &self, + date: NaiveDate, + lookback: usize, + include_now: bool, + ) -> Vec { + if lookback == 0 { + return Vec::new(); + } + let end = if include_now { + self.end_index(date) + } else { + self.previous_completed_end_index(date) + }; + let Some(end) = end else { + return Vec::new(); + }; + let start = end.saturating_sub(lookback); + self.snapshots[start..end].to_vec() + } + fn decision_price_on_or_before(&self, date: NaiveDate) -> Option { let end = self.decision_end_index(date)?; if end == 0 { @@ -1173,25 +1196,10 @@ impl DataSet { bar_count: usize, include_now: bool, ) -> Vec { - if bar_count == 0 { - return Vec::new(); - } - let mut snapshots = self - .market_by_date - .iter() - .filter(|(day, _)| { - if include_now { - **day <= date - } else { - **day < date - } - }) - .flat_map(|(_, rows)| rows.iter()) - .filter(|row| row.symbol == symbol) - .cloned() - .collect::>(); - snapshots.sort_by_key(|row| row.date); - take_last(snapshots, bar_count) + self.market_series_by_symbol + .get(symbol) + .map(|series| series.trailing_snapshots(date, bar_count, include_now)) + .unwrap_or_default() } pub fn history_intraday_quotes(