Revert "恢复Source Lake滚动因子运行模式"

This reverts commit d0639558b3.
This commit is contained in:
boris
2026-08-27 13:13:50 +08:00
parent d0639558b3
commit 45cafa5c96
+3 -118
View File
@@ -9,8 +9,8 @@ use rhai::{AST, Dynamic, Engine, Map, Scope};
use crate::broker::{MatchingType, RebalanceCashMode, SlippageModel}; use crate::broker::{MatchingType, RebalanceCashMode, SlippageModel};
use crate::cost::ChinaAShareCostModel; use crate::cost::ChinaAShareCostModel;
use crate::data::{ use crate::data::{
DailyMarketSnapshot, EligibleUniverseSnapshot, NumericFactorMap, PriceField, DailyMarketSnapshot, EligibleUniverseSnapshot, PriceField, decision_free_float_cap_bn,
decision_free_float_cap_bn, decision_market_cap_bn, decision_market_cap_bn,
}; };
use crate::engine::BacktestError; use crate::engine::BacktestError;
use crate::events::OrderSide; use crate::events::OrderSide;
@@ -424,11 +424,6 @@ pub struct PlatformExprStrategyConfig {
pub matching_type: MatchingType, pub matching_type: MatchingType,
pub quote_quantity_limit: bool, pub quote_quantity_limit: bool,
pub current_day_precomputed_factors: bool, pub current_day_precomputed_factors: bool,
/// Use audited Strategy Factory Source Lake rolling fields when the
/// runtime intentionally loads only the latest decision rows. This is
/// opt-in; ordinary backtests always recompute rolling values from the
/// canonical market series.
pub prefer_precomputed_rolling_factors: bool,
pub intraday_execution_time: Option<NaiveTime>, pub intraday_execution_time: Option<NaiveTime>,
pub delayed_limit_open_exit_enabled: bool, pub delayed_limit_open_exit_enabled: bool,
pub delayed_limit_open_exit_time: Option<NaiveTime>, pub delayed_limit_open_exit_time: Option<NaiveTime>,
@@ -500,7 +495,6 @@ impl PlatformExprStrategyConfig {
matching_type: MatchingType::CurrentBarClose, matching_type: MatchingType::CurrentBarClose,
quote_quantity_limit: true, quote_quantity_limit: true,
current_day_precomputed_factors: false, current_day_precomputed_factors: false,
prefer_precomputed_rolling_factors: false,
intraday_execution_time: None, intraday_execution_time: None,
delayed_limit_open_exit_enabled: false, delayed_limit_open_exit_enabled: false,
delayed_limit_open_exit_time: None, delayed_limit_open_exit_time: None,
@@ -808,42 +802,6 @@ fn framework_stock_rolling_factor_requirement(key: &str) -> Option<(&'static str
.map(|window| (field, window)) .map(|window| (field, window))
} }
fn precomputed_stock_rolling_mean<F>(get: F, field: &str, lookback: usize) -> Option<f64>
where
F: Fn(&str) -> Option<f64>,
{
if lookback == 0 {
return None;
}
let value_for = |key: String| get(&key).filter(|value| value.is_finite());
match field.trim().to_ascii_lowercase().as_str() {
"close" | "prev_close" | "stock_close" | "price" => {
value_for(format!("ma{lookback}_prev_close"))
.or_else(|| value_for(format!("ma{lookback}")))
}
"volume" | "stock_volume" => value_for(format!("avg_volume{lookback}"))
.or_else(|| value_for(format!("vma{lookback}"))),
_ => None,
}
}
fn precomputed_stock_current_rolling_mean<F>(get: F, field: &str, lookback: usize) -> Option<f64>
where
F: Fn(&str) -> Option<f64>,
{
if lookback == 0 {
return None;
}
let value_for = |key: String| get(&key).filter(|value| value.is_finite());
match field.trim().to_ascii_lowercase().as_str() {
"close" | "prev_close" | "stock_close" | "price" => {
value_for(format!("ma{lookback}_current_back_adjusted_close"))
}
"volume" | "stock_volume" => value_for(format!("avg_volume{lookback}_current")),
_ => None,
}
}
struct SelectiveExpressionScope<'a> { struct SelectiveExpressionScope<'a> {
inner: Scope<'static>, inner: Scope<'static>,
required_identifiers: &'a AHashSet<String>, required_identifiers: &'a AHashSet<String>,
@@ -3817,24 +3775,13 @@ impl PlatformExprStrategy {
date: NaiveDate, date: NaiveDate,
symbol_id: u32, symbol_id: u32,
symbol: &str, symbol: &str,
extra_factors: Option<&NumericFactorMap>,
field: &str, field: &str,
lookback: usize, lookback: usize,
) -> Option<f64> { ) -> Option<f64> {
let computed = || {
ctx.data ctx.data
.market_decision_numeric_moving_average_by_symbol_id( .market_decision_numeric_moving_average_by_symbol_id(
date, symbol_id, symbol, field, lookback, date, symbol_id, symbol, field, lookback,
) )
};
let precomputed = extra_factors.and_then(|factors| {
precomputed_stock_rolling_mean(|key| factors.get(key).copied(), field, lookback)
});
if self.config.prefer_precomputed_rolling_factors {
precomputed.or_else(computed)
} else {
computed().or(precomputed)
}
} }
fn stock_current_rolling_mean( fn stock_current_rolling_mean(
@@ -3843,23 +3790,12 @@ impl PlatformExprStrategy {
date: NaiveDate, date: NaiveDate,
symbol_id: u32, symbol_id: u32,
symbol: &str, symbol: &str,
extra_factors: Option<&NumericFactorMap>,
field: &str, field: &str,
lookback: usize, lookback: usize,
) -> Option<f64> { ) -> Option<f64> {
let computed = || {
ctx.data.market_current_numeric_moving_average_by_symbol_id( ctx.data.market_current_numeric_moving_average_by_symbol_id(
date, symbol_id, symbol, field, lookback, date, symbol_id, symbol, field, lookback,
) )
};
let precomputed = extra_factors.and_then(|factors| {
precomputed_stock_current_rolling_mean(|key| factors.get(key).copied(), field, lookback)
});
if self.config.prefer_precomputed_rolling_factors {
precomputed.or_else(computed)
} else {
computed().or(precomputed)
}
} }
fn stock_state_at_time( fn stock_state_at_time(
@@ -3984,15 +3920,7 @@ impl PlatformExprStrategy {
if !self.stock_rolling_requirements.requires(field, lookback) { if !self.stock_rolling_requirements.requires(field, lookback) {
return f64::NAN; return f64::NAN;
} }
self.stock_decision_rolling_mean( self.stock_decision_rolling_mean(ctx, date, symbol_id, symbol, field, lookback)
ctx,
date,
symbol_id,
symbol,
Some(&factor.extra_factors),
field,
lookback,
)
.unwrap_or(f64::NAN) .unwrap_or(f64::NAN)
}; };
let stock_ma_short = rolling("close", self.config.stock_short_ma_days); let stock_ma_short = rolling("close", self.config.stock_short_ma_days);
@@ -6109,9 +6037,6 @@ impl PlatformExprStrategy {
day.date, day.date,
stock.symbol_id, stock.symbol_id,
&stock.symbol, &stock.symbol,
ctx.data
.factor_by_symbol_id(day.date, stock.symbol_id)
.map(|factor| &factor.extra_factors),
field, field,
lookback, lookback,
) )
@@ -6767,9 +6692,6 @@ impl PlatformExprStrategy {
day.date, day.date,
stock.symbol_id, stock.symbol_id,
&stock.symbol, &stock.symbol,
ctx.data
.factor_by_symbol_id(day.date, stock.symbol_id)
.map(|factor| &factor.extra_factors),
other, other,
lookback, lookback,
) )
@@ -6819,9 +6741,6 @@ impl PlatformExprStrategy {
day.date, day.date,
stock.symbol_id, stock.symbol_id,
&stock.symbol, &stock.symbol,
ctx.data
.factor_by_symbol_id(day.date, stock.symbol_id)
.map(|factor| &factor.extra_factors),
other, other,
lookback, lookback,
) )
@@ -12173,7 +12092,6 @@ mod tests {
PlatformRebalanceSchedule, PlatformScheduleFrequency, PlatformStopTakeReferencePriceMode, PlatformRebalanceSchedule, PlatformScheduleFrequency, PlatformStopTakeReferencePriceMode,
PlatformTradeAction, PlatformUniverseActionKind, RuntimeHelperResolution, PlatformTradeAction, PlatformUniverseActionKind, RuntimeHelperResolution,
SelectionRiskDeferral, StockFilterQuoteUsage, framework_stock_rolling_factor_requirement, SelectionRiskDeferral, StockFilterQuoteUsage, framework_stock_rolling_factor_requirement,
precomputed_stock_current_rolling_mean, precomputed_stock_rolling_mean,
}; };
use crate::{ use crate::{
AlgoOrderStyle, BenchmarkSnapshot, CandidateEligibility, CorporateAction, AlgoOrderStyle, BenchmarkSnapshot, CandidateEligibility, CorporateAction,
@@ -12241,39 +12159,6 @@ mod tests {
assert_eq!(framework_stock_rolling_factor_requirement("alpha001"), None); assert_eq!(framework_stock_rolling_factor_requirement("alpha001"), None);
} }
#[test]
fn source_lake_precomputed_rolling_aliases_use_only_canonical_fields() {
let factors = BTreeMap::from([
("ma5_prev_close".to_string(), 11.0),
("ma5".to_string(), 12.0),
("ma5_current_close".to_string(), 99.0),
("ma5_current_back_adjusted_close".to_string(), 13.0),
("avg_volume5".to_string(), 100.0),
("avg_volume5_current".to_string(), 120.0),
]);
let get = |key: &str| factors.get(key).copied();
assert_eq!(precomputed_stock_rolling_mean(get, "close", 5), Some(11.0));
assert_eq!(
precomputed_stock_current_rolling_mean(get, "close", 5),
Some(13.0)
);
assert_eq!(
precomputed_stock_rolling_mean(get, "volume", 5),
Some(100.0)
);
assert_eq!(
precomputed_stock_current_rolling_mean(get, "volume", 5),
Some(120.0)
);
// A source row that only has a raw current-close alias must not be
// mistaken for the adjusted rolling value.
let raw_only = BTreeMap::from([("ma5_current_close".to_string(), 99.0)]);
assert_eq!(
precomputed_stock_current_rolling_mean(|key| raw_only.get(key).copied(), "close", 5,),
None
);
}
#[test] #[test]
fn typed_runtime_numbers_preserve_legacy_rhai_formatting() { fn typed_runtime_numbers_preserve_legacy_rhai_formatting() {
let RuntimeHelperResolution::Number(value) = let RuntimeHelperResolution::Number(value) =