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