From cb2319cd22ea728e176f374589cd05835e833276 Mon Sep 17 00:00:00 2001 From: boris Date: Fri, 28 Aug 2026 08:23:04 +0800 Subject: [PATCH] Revert "perf(core): reuse rolling endpoints per stock state" This reverts commit 732c3cfbf57500925e1dc7b2b876e58473f3fa9c. --- crates/fidc-core/src/data.rs | 141 +----------------- .../fidc-core/src/platform_expr_strategy.rs | 6 +- 2 files changed, 6 insertions(+), 141 deletions(-) diff --git a/crates/fidc-core/src/data.rs b/crates/fidc-core/src/data.rs index 49f9d70..4725d40 100644 --- a/crates/fidc-core/src/data.rs +++ b/crates/fidc-core/src/data.rs @@ -646,22 +646,14 @@ impl AdjustedCloseSeries { } fn decision_moving_average(&self, date: NaiveDate, lookback: usize) -> Option { - let end = self.decision_end_index(date)?; - self.decision_moving_average_at_end(end, lookback) - } - - fn decision_end_index(&self, date: NaiveDate) -> Option { - match self.dates.binary_search(&date) { - Ok(index) => Some(index), - Err(0) => None, - Err(index) => Some(index), - } - } - - fn decision_moving_average_at_end(&self, end: usize, lookback: usize) -> Option { if lookback == 0 { return None; } + let end = match self.dates.binary_search(&date) { + Ok(index) => index, + Err(0) => return None, + Err(index) => index, + }; if end < lookback { return None; } @@ -953,14 +945,6 @@ impl SymbolPriceSeries { fn decision_volume_moving_average(&self, date: NaiveDate, lookback: usize) -> Option { let end = self.previous_completed_end_index(date)?; - self.decision_volume_moving_average_at_end(end, lookback) - } - - fn decision_volume_moving_average_at_end( - &self, - end: usize, - lookback: usize, - ) -> Option { self.valid_volume_window(end, lookback).map(|(start, end)| { normalize_rolling_factor( (self.valid_volume_sum_prefix[end] - self.valid_volume_sum_prefix[start]) @@ -1262,28 +1246,6 @@ pub(crate) struct SymbolSnapshotRefs<'a> { pub candidate: Option<&'a CandidateEligibility>, } -#[derive(Debug, Clone, Copy)] -pub(crate) struct DecisionRollingCursor<'a> { - adjusted_close: Option<(&'a AdjustedCloseSeries, usize)>, - volume: Option<(&'a SymbolPriceSeries, usize)>, -} - -impl DecisionRollingCursor<'_> { - pub(crate) fn moving_average(&self, field: &str, lookback: usize) -> Option { - match field { - "close" => self - .adjusted_close - .and_then(|(series, end)| series.decision_moving_average_at_end(end, lookback)), - "volume" => self - .volume - .and_then(|(series, end)| { - series.decision_volume_moving_average_at_end(end, lookback) - }), - _ => None, - } - } -} - impl DataSet { pub fn with_additional_trading_dates( mut self, @@ -2919,27 +2881,6 @@ impl DataSet { } } - pub(crate) fn market_decision_rolling_cursor_by_symbol_id( - &self, - date: NaiveDate, - symbol_id: u32, - ) -> DecisionRollingCursor<'_> { - let adjusted_close = self - .adjusted_close_series_by_symbol_id(symbol_id) - .and_then(|series| series.decision_end_index(date).map(|end| (series, end))); - let volume = self - .market_series_by_symbol_id(symbol_id) - .and_then(|series| { - series - .previous_completed_end_index(date) - .map(|end| (series, end)) - }); - DecisionRollingCursor { - adjusted_close, - volume, - } - } - pub fn market_current_numeric_moving_average( &self, date: NaiveDate, @@ -4191,78 +4132,6 @@ mod tests { assert!(signal.candidate.is_none()); } - #[test] - fn decision_rolling_cursor_matches_existing_close_and_volume_contract() { - let dates = ["2025-01-02", "2025-01-03", "2025-01-06", "2025-01-07"]; - let market = dates - .iter() - .enumerate() - .map(|(index, date)| market_row(date, 10.0 + index as f64, 1_000 + index as u64 * 100)) - .collect::>(); - let factors = dates - .iter() - .map(|date| DailyFactorSnapshot { - date: NaiveDate::parse_from_str(date, "%Y-%m-%d").unwrap(), - symbol: "000001.SZ".to_string(), - market_cap_bn: 100.0, - free_float_cap_bn: 80.0, - pe_ttm: 0.0, - turnover_ratio: None, - effective_turnover_ratio: None, - extra_factors: NumericFactorMap::from([( - Cow::Borrowed(BACKWARD_ADJUSTMENT_FACTOR_FIELD), - 1.0, - )]), - }) - .collect::>(); - let benchmarks = dates - .iter() - .enumerate() - .map(|(index, date)| benchmark_row(date, 20.0 + index as f64)) - .collect::>(); - let data = DataSet::from_components( - vec![Instrument { - symbol: "000001.SZ".to_string(), - name: "000001.SZ".to_string(), - board: "SZ".to_string(), - round_lot: 100, - listed_at: None, - delisted_at: None, - status: "active".to_string(), - }], - market, - factors, - Vec::new(), - benchmarks, - ) - .unwrap(); - let symbol_id = data.symbol_id("000001.SZ").unwrap(); - let date = NaiveDate::parse_from_str("2025-01-07", "%Y-%m-%d").unwrap(); - let cursor = data.market_decision_rolling_cursor_by_symbol_id(date, symbol_id); - for lookback in [1, 2, 3] { - assert_eq!( - cursor.moving_average("close", lookback), - data.market_decision_numeric_moving_average_by_symbol_id( - date, - symbol_id, - "000001.SZ", - "close", - lookback, - ) - ); - assert_eq!( - cursor.moving_average("volume", lookback), - data.market_decision_numeric_moving_average_by_symbol_id( - date, - symbol_id, - "000001.SZ", - "volume", - lookback, - ) - ); - } - } - #[test] fn additional_terminal_calendar_dates_are_isolated_from_shared_market_data() { let date = NaiveDate::parse_from_str("2025-01-02", "%Y-%m-%d").unwrap(); diff --git a/crates/fidc-core/src/platform_expr_strategy.rs b/crates/fidc-core/src/platform_expr_strategy.rs index 9fc6fd6..b7abec7 100644 --- a/crates/fidc-core/src/platform_expr_strategy.rs +++ b/crates/fidc-core/src/platform_expr_strategy.rs @@ -3935,15 +3935,11 @@ impl PlatformExprStrategy { None }; let instrument = ctx.data.instrument(symbol); - let rolling_cursor = ctx - .data - .market_decision_rolling_cursor_by_symbol_id(date, symbol_id); let rolling = |field: &'static str, lookback: usize| -> f64 { if !self.stock_rolling_requirements.requires(field, lookback) { return f64::NAN; } - rolling_cursor - .moving_average(field, lookback) + self.stock_decision_rolling_mean(ctx, date, symbol_id, symbol, field, lookback) .unwrap_or(f64::NAN) }; let stock_ma_short = rolling("close", self.config.stock_short_ma_days);