diff --git a/crates/fidc-core/src/platform_expr_strategy.rs b/crates/fidc-core/src/platform_expr_strategy.rs index c910f15..c96325a 100644 --- a/crates/fidc-core/src/platform_expr_strategy.rs +++ b/crates/fidc-core/src/platform_expr_strategy.rs @@ -4415,8 +4415,10 @@ impl PlatformExprStrategy { let include_day_factors = normalized_identifiers.contains("day_factors") || normalized_identifiers.contains("day_factor") || prelude_identifiers.contains("day_factors"); - let include_factors_map = - normalized_identifiers.contains("factors") || normalized_identifiers.contains("factor"); + let include_factors_map = normalized_identifiers.contains("factors") + || normalized_identifiers.contains("factor") + || prelude_identifiers.contains("factors") + || prelude_identifiers.contains("factor"); let include_process_event_counts = include_day_factors || normalized_identifiers.contains("process_event_counts") || prelude_identifiers.contains("process_event_counts"); @@ -4430,10 +4432,14 @@ impl PlatformExprStrategy { include_factors_map, include_process_event_counts, ); + let expanded_prelude = + self.expand_runtime_helpers(ctx, day, stock, &self.normalized_prelude, &mut scope)?; let expanded_expr = self.expand_runtime_helpers(ctx, day, stock, &normalized_expr, &mut scope)?; if let Some(item) = stock { - for identifier in Self::extract_identifier_candidates(&expanded_expr) { + let mut expanded_identifiers = Self::extract_identifier_candidates(&expanded_prelude); + expanded_identifiers.extend(Self::extract_identifier_candidates(&expanded_expr)); + for identifier in expanded_identifiers { if Self::is_reserved_scope_name(identifier.as_str()) || self.prelude_declared_identifiers.contains(&identifier) || (!self.stock_extra_factor_identifiers.contains(&identifier) @@ -4456,8 +4462,8 @@ impl PlatformExprStrategy { } } let mut script_parts = Vec::with_capacity(2); - if !self.normalized_prelude.trim().is_empty() { - script_parts.push(self.normalized_prelude.as_str()); + if !expanded_prelude.trim().is_empty() { + script_parts.push(expanded_prelude.as_str()); } script_parts.push(expanded_expr.as_str()); let script = script_parts.join("\n"); @@ -21639,7 +21645,11 @@ mod tests { cfg.rotation_enabled = false; cfg.benchmark_short_ma_days = 1; cfg.benchmark_long_ma_days = 1; - cfg.prelude = "let blackout = trade_date >= \"2025-01-06\";".to_string(); + cfg.prelude = concat!( + "let signal_current_ma = rolling_mean_current(\"signal_close\", 2);", + " let blackout = trade_date >= \"2025-01-06\";" + ) + .to_string(); cfg.explicit_actions = vec![PlatformTradeAction::Order { kind: PlatformExplicitOrderKind::Value, symbol: "000001.SZ".to_string(), @@ -21663,6 +21673,7 @@ mod tests { " && rolling_zscore(\"close\", 2) > 0.9", " && pct_change(\"close\", 1) > 0.09", " && factor_value(\"mixed_factor\") == 7.0", + " && signal_current_ma == 11.7", " && trade_date == \"2025-01-06\"", " && blackout" )