按策略引用投影额外因子字段
This commit is contained in:
@@ -990,6 +990,7 @@ pub struct PlatformExprStrategy {
|
|||||||
stock_rolling_requirements: StockRollingRequirements,
|
stock_rolling_requirements: StockRollingRequirements,
|
||||||
stock_extra_factors_required: bool,
|
stock_extra_factors_required: bool,
|
||||||
stock_extra_factor_identifiers: BTreeSet<String>,
|
stock_extra_factor_identifiers: BTreeSet<String>,
|
||||||
|
stock_extra_factor_map_required: bool,
|
||||||
stock_text_factors_required: bool,
|
stock_text_factors_required: bool,
|
||||||
stock_state_cache_date: RefCell<Option<NaiveDate>>,
|
stock_state_cache_date: RefCell<Option<NaiveDate>>,
|
||||||
stock_state_cache: RefCell<
|
stock_state_cache: RefCell<
|
||||||
@@ -1267,6 +1268,7 @@ impl PlatformExprStrategy {
|
|||||||
Self::stock_extra_factors_required_for_config(&config, &prelude_declared_identifiers);
|
Self::stock_extra_factors_required_for_config(&config, &prelude_declared_identifiers);
|
||||||
let stock_extra_factor_identifiers =
|
let stock_extra_factor_identifiers =
|
||||||
Self::stock_extra_factor_identifiers_for_config(&config, &prelude_declared_identifiers);
|
Self::stock_extra_factor_identifiers_for_config(&config, &prelude_declared_identifiers);
|
||||||
|
let stock_extra_factor_map_required = Self::stock_extra_factor_map_required_for_config(&config);
|
||||||
let stock_text_factors_required = Self::stock_text_factors_required_for_config(
|
let stock_text_factors_required = Self::stock_text_factors_required_for_config(
|
||||||
&config,
|
&config,
|
||||||
&normalized_stock_filter_expr,
|
&normalized_stock_filter_expr,
|
||||||
@@ -1304,6 +1306,7 @@ impl PlatformExprStrategy {
|
|||||||
stock_rolling_requirements,
|
stock_rolling_requirements,
|
||||||
stock_extra_factors_required,
|
stock_extra_factors_required,
|
||||||
stock_extra_factor_identifiers,
|
stock_extra_factor_identifiers,
|
||||||
|
stock_extra_factor_map_required,
|
||||||
stock_text_factors_required,
|
stock_text_factors_required,
|
||||||
stock_state_cache_date: RefCell::new(None),
|
stock_state_cache_date: RefCell::new(None),
|
||||||
stock_state_cache: RefCell::new(AHashMap::new()),
|
stock_state_cache: RefCell::new(AHashMap::new()),
|
||||||
@@ -4055,6 +4058,10 @@ impl PlatformExprStrategy {
|
|||||||
factor
|
factor
|
||||||
.extra_factors
|
.extra_factors
|
||||||
.iter()
|
.iter()
|
||||||
|
.filter(|(field, _)| {
|
||||||
|
self.stock_extra_factor_map_required
|
||||||
|
|| self.stock_extra_factor_identifiers.contains(field.as_ref())
|
||||||
|
})
|
||||||
.map(|(field, value)| (field.to_string(), *value))
|
.map(|(field, value)| (field.to_string(), *value))
|
||||||
.collect()
|
.collect()
|
||||||
} else {
|
} else {
|
||||||
@@ -9665,6 +9672,30 @@ impl PlatformExprStrategy {
|
|||||||
.any(|expr| Self::expr_requires_stock_extra_factors(expr, prelude_declared_identifiers))
|
.any(|expr| Self::expr_requires_stock_extra_factors(expr, prelude_declared_identifiers))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn stock_extra_factor_map_required_for_config(config: &PlatformExprStrategyConfig) -> bool {
|
||||||
|
// A dynamic factors/factor map is part of the expression contract: its
|
||||||
|
// caller may access any published field by key. Keep the full map for
|
||||||
|
// that case and for explicit actions whose predicates are evaluated at
|
||||||
|
// runtime; direct field references use the projected identifier set.
|
||||||
|
if Self::has_stock_explicit_actions(config) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
[
|
||||||
|
config.prelude.as_str(),
|
||||||
|
config.stock_filter_expr.as_str(),
|
||||||
|
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()
|
||||||
|
.map(Self::normalize_expr)
|
||||||
|
.map(|expr| Self::extract_identifier_candidates(&expr))
|
||||||
|
.any(|identifiers| identifiers.contains("factors") || identifiers.contains("factor"))
|
||||||
|
}
|
||||||
|
|
||||||
fn stock_extra_factor_identifiers_for_config(
|
fn stock_extra_factor_identifiers_for_config(
|
||||||
config: &PlatformExprStrategyConfig,
|
config: &PlatformExprStrategyConfig,
|
||||||
prelude_declared_identifiers: &BTreeSet<String>,
|
prelude_declared_identifiers: &BTreeSet<String>,
|
||||||
@@ -13921,7 +13952,10 @@ mod tests {
|
|||||||
pe_ttm: 8.0,
|
pe_ttm: 8.0,
|
||||||
turnover_ratio: Some(1.0),
|
turnover_ratio: Some(1.0),
|
||||||
effective_turnover_ratio: Some(1.0),
|
effective_turnover_ratio: Some(1.0),
|
||||||
extra_factors: BTreeMap::from([("model_score".into(), 2.0)]),
|
extra_factors: BTreeMap::from([
|
||||||
|
("model_score".into(), 2.0),
|
||||||
|
("unused_factor".into(), 9.0),
|
||||||
|
]),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
symbols
|
symbols
|
||||||
@@ -13991,6 +14025,25 @@ mod tests {
|
|||||||
.stock_passes_expr(&ctx, &day, &present_stock)
|
.stock_passes_expr(&ctx, &day, &present_stock)
|
||||||
.expect("present stock filter")
|
.expect("present stock filter")
|
||||||
);
|
);
|
||||||
|
assert!(!strategy.stock_extra_factor_map_required);
|
||||||
|
assert!(present_stock.extra_factors.contains_key("model_score"));
|
||||||
|
assert!(!present_stock.extra_factors.contains_key("unused_factor"));
|
||||||
|
|
||||||
|
let mut map_cfg = PlatformExprStrategyConfig::microcap_rotation();
|
||||||
|
map_cfg.signal_symbol = present_symbol.to_string();
|
||||||
|
map_cfg.stock_filter_expr = "factors[\"unused_factor\"] > 0".to_string();
|
||||||
|
let map_strategy = PlatformExprStrategy::new(map_cfg);
|
||||||
|
assert!(map_strategy.stock_extra_factor_map_required);
|
||||||
|
let map_stock = map_strategy
|
||||||
|
.stock_state_with_factor_date(&ctx, date, date, present_symbol)
|
||||||
|
.expect("factor map stock state");
|
||||||
|
assert!(map_stock.extra_factors.contains_key("unused_factor"));
|
||||||
|
let map_day = map_strategy.day_state(&ctx, date).expect("factor map day state");
|
||||||
|
assert!(
|
||||||
|
map_strategy
|
||||||
|
.stock_passes_expr(&ctx, &map_day, &map_stock)
|
||||||
|
.expect("factor map filter")
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
Reference in New Issue
Block a user