懒加载策略额外因子状态

This commit is contained in:
boris
2026-06-21 01:42:06 +08:00
parent 5b34f3b55b
commit d264e39285
+78 -19
View File
@@ -556,6 +556,7 @@ pub struct PlatformExprStrategy {
selection_quote_usage: StockFilterQuoteUsage,
stock_rolling_requirements: StockRollingRequirements,
stock_extra_factors_required: bool,
stock_text_factors_required: bool,
stock_state_cache_date: RefCell<Option<NaiveDate>>,
stock_state_cache: RefCell<
HashMap<(NaiveDate, NaiveDate, String, Option<NaiveTime>, bool), StockExpressionState>,
@@ -656,6 +657,11 @@ impl PlatformExprStrategy {
&normalized_stock_filter_expr,
&prelude_declared_identifiers,
);
let stock_text_factors_required = Self::stock_text_factors_required_for_config(
&config,
&normalized_stock_filter_expr,
&prelude_declared_identifiers,
);
Self {
config,
engine,
@@ -675,6 +681,7 @@ impl PlatformExprStrategy {
selection_quote_usage,
stock_rolling_requirements,
stock_extra_factors_required,
stock_text_factors_required,
stock_state_cache_date: RefCell::new(None),
stock_state_cache: RefCell::new(HashMap::new()),
}
@@ -2162,18 +2169,24 @@ impl PlatformExprStrategy {
weekday: date.weekday().number_from_monday() as i64,
is_month_start: date.day() == 1,
is_month_end,
available_factor_names: ctx
.data
.factor_snapshots_on(date)
.into_iter()
.flat_map(|row| row.extra_factors.keys().cloned())
.collect(),
available_text_factor_names: ctx
.data
.factor_text_snapshots_on(date)
.into_iter()
.map(|row| row.field.clone())
.collect(),
available_factor_names: if self.stock_extra_factors_required {
ctx.data
.factor_snapshots_on(date)
.into_iter()
.flat_map(|row| row.extra_factors.keys().cloned())
.collect()
} else {
BTreeSet::new()
},
available_text_factor_names: if self.stock_text_factors_required {
ctx.data
.factor_text_snapshots_on(date)
.into_iter()
.map(|row| row.field.clone())
.collect()
} else {
BTreeSet::new()
},
})
}
@@ -2506,13 +2519,16 @@ impl PlatformExprStrategy {
} else {
BTreeMap::new()
},
extra_text_factors: ctx
.data
.factor_text_snapshots_on(date)
.into_iter()
.filter(|row| row.symbol == symbol)
.map(|row| (row.field.clone(), row.value.clone()))
.collect(),
extra_text_factors: if self.stock_text_factors_required {
ctx.data
.factor_text_snapshots_on(date)
.into_iter()
.filter(|row| row.symbol == symbol)
.map(|row| (row.field.clone(), row.value.clone()))
.collect()
} else {
BTreeMap::new()
},
};
self.stock_state_cache
.borrow_mut()
@@ -6403,6 +6419,49 @@ impl PlatformExprStrategy {
})
}
fn stock_text_factors_required_for_config(
config: &PlatformExprStrategyConfig,
normalized_stock_filter_expr: &str,
prelude_declared_identifiers: &BTreeSet<String>,
) -> bool {
if !config.explicit_actions.is_empty() {
return true;
}
[
config.prelude.as_str(),
normalized_stock_filter_expr,
config.buy_scale_expr.as_str(),
config.stop_loss_expr.as_str(),
config.take_profit_expr.as_str(),
config.rank_expr.as_str(),
config.market_cap_field.as_str(),
config.rank_by.as_str(),
]
.into_iter()
.any(|expr| Self::expr_may_use_stock_text_factors(expr, prelude_declared_identifiers))
}
fn expr_may_use_stock_text_factors(
expr: &str,
prelude_declared_identifiers: &BTreeSet<String>,
) -> bool {
let normalized = Self::normalize_expr(expr);
let identifiers = Self::extract_identifier_candidates(&normalized);
if identifiers.contains("factors")
|| identifiers.contains("factor")
|| identifiers.contains("factor_text")
|| identifiers.contains("get_factor_text")
{
return true;
}
identifiers.into_iter().any(|name| {
!Self::is_expression_keyword(&name)
&& !Self::is_runtime_helper(&name)
&& !Self::is_reserved_scope_name(&name)
&& !prelude_declared_identifiers.contains(&name)
})
}
fn expr_requires_stock_extra_factors(
expr: &str,
prelude_declared_identifiers: &BTreeSet<String>,