fix(backtest): inspect the authoritative strategy inside runner bundles
This commit is contained in:
@@ -212,6 +212,11 @@ pub fn build_dataset_context(
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn specs_in_value(value: &Value) -> Result<Vec<PatternSpec>, String> {
|
pub fn specs_in_value(value: &Value) -> Result<Vec<PatternSpec>, String> {
|
||||||
|
// A runner bundle also contains source/extract copies. Follow the same
|
||||||
|
// authoritative spec selection as the execution loader, not those copies.
|
||||||
|
if let Some(spec) = value.get("strategySpec").or_else(|| value.get("strategy_spec")) {
|
||||||
|
return specs_in_value(spec);
|
||||||
|
}
|
||||||
let mut specs = Vec::new();
|
let mut specs = Vec::new();
|
||||||
match value {
|
match value {
|
||||||
Value::String(text) => specs.extend(crate::daily_patterns::expression_specs(text)?),
|
Value::String(text) => specs.extend(crate::daily_patterns::expression_specs(text)?),
|
||||||
@@ -268,9 +273,15 @@ mod tests {
|
|||||||
for (pool_key, source_key) in [("stockPool", "sourceCode"), ("stock_pool", "source_code")] {
|
for (pool_key, source_key) in [("stockPool", "sourceCode"), ("stock_pool", "source_code")] {
|
||||||
let value = json!({pool_key:pool,source_key:source,"runtimeExpressions":{"trading":{"buyFilterExpr":expr}}});
|
let value = json!({pool_key:pool,source_key:source,"runtimeExpressions":{"trading":{"buyFilterExpr":expr}}});
|
||||||
assert_eq!(specs_in_value(&value).unwrap().len(), 2);
|
assert_eq!(specs_in_value(&value).unwrap().len(), 2);
|
||||||
|
for wrapper in ["strategySpec", "strategy_spec"] {
|
||||||
|
let bundle = json!({wrapper:value,"strategy_source":{"source_code":source},
|
||||||
|
"strategy_extract":{"parameters":{"source_code":source}}});
|
||||||
|
assert_eq!(specs_in_value(&bundle).unwrap().len(), 2);
|
||||||
|
}
|
||||||
let mut invalid = value.clone();
|
let mut invalid = value.clone();
|
||||||
invalid[pool_key]["exit_signals"][0]["when_expr"] = json!("pattern_signal(not-json)");
|
invalid[pool_key]["exit_signals"][0]["when_expr"] = json!("pattern_signal(not-json)");
|
||||||
assert!(specs_in_value(&invalid).is_err(), "invalid actual conditions must still fail");
|
assert!(specs_in_value(&invalid).is_err(), "invalid actual conditions must still fail");
|
||||||
|
assert!(specs_in_value(&json!({"strategySpec":invalid})).is_err());
|
||||||
}
|
}
|
||||||
assert_eq!(specs_in_value(&json!({"sourceCode":format!("risk.stop_loss({expr})")})).unwrap().len(),1);
|
assert_eq!(specs_in_value(&json!({"sourceCode":format!("risk.stop_loss({expr})")})).unwrap().len(),1);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user