From ef491340f621d80a2ab064563dc5a556f65fe71b Mon Sep 17 00:00:00 2001 From: boris Date: Fri, 17 Jul 2026 14:54:25 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E6=8C=81=E8=BF=90=E8=A1=8C=E6=80=81?= =?UTF-8?q?=E9=A2=84=E8=AE=A1=E7=AE=97=E6=BB=9A=E5=8A=A8=E5=9D=87=E7=BA=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fidc-core/src/platform_expr_strategy.rs | 39 ++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/crates/fidc-core/src/platform_expr_strategy.rs b/crates/fidc-core/src/platform_expr_strategy.rs index df09067..90186e4 100644 --- a/crates/fidc-core/src/platform_expr_strategy.rs +++ b/crates/fidc-core/src/platform_expr_strategy.rs @@ -3298,6 +3298,27 @@ impl PlatformExprStrategy { } } + fn stock_current_rolling_mean( + &self, + ctx: &StrategyContext<'_>, + date: NaiveDate, + symbol: &str, + extra_factors: &BTreeMap, + field: &str, + lookback: usize, + ) -> Option { + let precomputed = precomputed_stock_rolling_mean(extra_factors, field, lookback); + let computed = || { + ctx.data + .market_current_numeric_moving_average(date, symbol, field, lookback) + }; + if self.config.prefer_precomputed_rolling_factors { + precomputed.or_else(computed) + } else { + computed().or(precomputed) + } + } + fn stock_state_at_time( &self, ctx: &StrategyContext<'_>, @@ -5466,9 +5487,11 @@ impl PlatformExprStrategy { "rolling_mean_current(\"{other}\", {lookback}) requires stock context" )) })?; - ctx.data.market_current_numeric_moving_average( + self.stock_current_rolling_mean( + ctx, day.date, &stock.symbol, + &stock.extra_factors, other, lookback, ) @@ -28351,6 +28374,7 @@ mod tests { fills: &[], }; let mut cfg = PlatformExprStrategyConfig::microcap_rotation(); + cfg.signal_symbol = symbol.to_string(); cfg.prefer_precomputed_rolling_factors = true; cfg.stock_filter_expr = "stock_ma5 > 0 && stock_volume_ma5 > 0".to_string(); let strategy = PlatformExprStrategy::new(cfg); @@ -28359,6 +28383,19 @@ mod tests { .expect("stock state"); assert_eq!(stock.stock_ma5, 99.0); assert_eq!(stock.stock_volume_ma5, 88.0); + let day = strategy.day_state(&ctx, date).expect("day state"); + assert_eq!( + strategy + .resolve_current_rolling_mean(&ctx, &day, Some(&stock), "close", 5) + .expect("precomputed current close rolling mean"), + 99.0 + ); + assert_eq!( + strategy + .resolve_current_rolling_mean(&ctx, &day, Some(&stock), "volume", 5) + .expect("precomputed current volume rolling mean"), + 88.0 + ); let mut cfg = PlatformExprStrategyConfig::microcap_rotation(); cfg.stock_filter_expr = "stock_ma5 > 0 && stock_volume_ma5 > 0".to_string();