From 7f7fce1fc359ac62fda72d4f2eb1fa3e631453c8 Mon Sep 17 00:00:00 2001 From: boris Date: Sat, 5 Sep 2026 05:19:33 +0800 Subject: [PATCH] perf: keep ranked candidate states transient --- .../fidc-core/src/platform_expr_strategy.rs | 76 +++++++------------ 1 file changed, 29 insertions(+), 47 deletions(-) diff --git a/crates/fidc-core/src/platform_expr_strategy.rs b/crates/fidc-core/src/platform_expr_strategy.rs index 282fe76..1c49e1e 100644 --- a/crates/fidc-core/src/platform_expr_strategy.rs +++ b/crates/fidc-core/src/platform_expr_strategy.rs @@ -3981,32 +3981,6 @@ impl PlatformExprStrategy { ) } - fn selection_stock_state_with_factor_date_from_views<'a>( - &self, - ctx: &StrategyContext<'a>, - date: NaiveDate, - factor_date: NaiveDate, - symbol: &str, - execution_day: &DailySnapshotView<'a>, - factor_day: &DailySnapshotView<'a>, - ) -> Result, BacktestError> { - let source = ViewStockStateSnapshotSource { - execution: execution_day, - factor: factor_day, - same_date: factor_date == date, - }; - let use_intraday_quote = self.selection_quote_usage != StockFilterQuoteUsage::DailyOnly; - self.stock_state_with_factor_date_and_time_from_source( - ctx, - date, - factor_date, - symbol, - None, - use_intraday_quote, - &source, - ) - } - #[allow(clippy::too_many_arguments)] fn uncached_selection_stock_state_from_views_by_symbol_id<'a>( &self, @@ -9497,6 +9471,7 @@ impl PlatformExprStrategy { ) } + #[cfg(test)] fn selectable_universe_on_with_options( &self, ctx: &StrategyContext<'_>, @@ -9514,6 +9489,7 @@ impl PlatformExprStrategy { .0 } + #[cfg(test)] fn selection_universe_and_risk_decisions_with_options( &self, ctx: &StrategyContext<'_>, @@ -10190,28 +10166,23 @@ impl PlatformExprStrategy { return Ok((selected, diagnostics, risk_decisions)); } - let universe = universe_symbol_ids - .into_iter() - .map(|symbol_id| { - let factor = universe_factor_day - .factor(symbol_id) - .expect("market-cap order references missing factor row"); - EligibleUniverseSnapshot { - symbol: factor.symbol.clone(), - market_cap_bn: decision_market_cap_bn(factor), - free_float_cap_bn: decision_free_float_cap_bn(factor), - } - }) - .collect::>(); - let mut candidates = Vec::new(); let mut missing_rank_count = 0usize; let mut missing_rank_examples = Vec::new(); - for candidate in universe { - let stock = self.selection_stock_state_with_factor_date_from_views( + for symbol_id in universe_symbol_ids { + let factor = universe_factor_day + .factor(symbol_id) + .expect("market-cap order references missing factor row"); + let candidate = EligibleUniverseSnapshot { + symbol: factor.symbol.clone(), + market_cap_bn: decision_market_cap_bn(factor), + free_float_cap_bn: decision_free_float_cap_bn(factor), + }; + let stock = self.uncached_selection_stock_state_from_views_by_symbol_id( ctx, date, stock_factor_date, + symbol_id, &candidate.symbol, &execution_day, &factor_day, @@ -10926,20 +10897,31 @@ impl PlatformExprStrategy { } else { SelectionRiskDeferral::None }; - let universe = self.selectable_universe_on_with_options( + let (universe_symbol_ids, _) = self.selection_symbol_ids_and_risk_decisions_with_options( ctx, date, universe_factor_date, selection_risk_deferral, + false, ); let execution_day = ctx.data.daily_snapshot_view(date); + let universe_factor_day = ctx.data.daily_snapshot_view(universe_factor_date); let factor_day = ctx.data.daily_snapshot_view(stock_factor_date); let quote_candidate_limit = self.quote_plan_candidate_limit(selection_limit); - for candidate in universe { - let stock = self.selection_stock_state_with_factor_date_from_views( + for symbol_id in universe_symbol_ids { + let factor = universe_factor_day + .factor(symbol_id) + .expect("market-cap order references missing factor row"); + let candidate = EligibleUniverseSnapshot { + symbol: factor.symbol.clone(), + market_cap_bn: decision_market_cap_bn(factor), + free_float_cap_bn: decision_free_float_cap_bn(factor), + }; + let stock = self.uncached_selection_stock_state_from_views_by_symbol_id( ctx, date, stock_factor_date, + symbol_id, &candidate.symbol, &execution_day, &factor_day, @@ -11001,7 +10983,7 @@ impl PlatformExprStrategy { let mut processed_scope = 0usize; for (symbol, _, stock) in &candidates { processed_scope += 1; - if !self.stock_passes_quote_plan_filter(ctx, day, &stock, quote_usage)? { + if !self.stock_passes_quote_plan_filter(ctx, day, stock, quote_usage)? { if diagnostics.len() < 12 { diagnostics.push(format!("{symbol} quote_plan rejected by stock_expr")); } @@ -11019,7 +11001,7 @@ impl PlatformExprStrategy { continue; } if quote_usage == StockFilterQuoteUsage::IntradayQuote - && !self.stock_passes_expr(ctx, day, &stock)? + && !self.stock_passes_expr(ctx, day, stock)? { if diagnostics.len() < 12 { diagnostics.push(format!("{symbol} quote_plan rejected by stock_expr"));