区分次日回放调度标签与实际日线可见时点

This commit is contained in:
boris
2026-09-09 07:21:13 +08:00
parent 3b5a7cd318
commit 2811886a52
@@ -5671,8 +5671,9 @@ impl PlatformExprStrategy {
return Err(BacktestError::Execution("daily_pattern_requires_next_bar_open: 完整日线形态只能在下一交易日执行".into()));
}
let date = day.date.min(ctx.decision_date);
if ctx.active_datetime.is_some_and(|t| t.date() == date && t.time() < NaiveTime::from_hms_opt(16, 0, 0).unwrap()) {
return Err(BacktestError::Execution("daily_pattern_not_yet_visible: 不允许使用未完成的当日日线".into()));
// Lagged replay retains the decision day's schedule label; execution is on a later session.
if !ctx.is_lagged_execution() && ctx.active_datetime.is_some_and(|t| t.date() == date && t.time() < NaiveTime::from_hms_opt(16, 0, 0).unwrap()) {
return Err(BacktestError::Execution(format!("daily_pattern_not_yet_visible: 不允许使用未完成的当日日线; decision_date={date}, execution_date={}, active_datetime={:?}",ctx.execution_date,ctx.active_datetime)));
}
let stock = stock.ok_or_else(|| BacktestError::Execution("pattern_signal requires stock context".into()))?;
let key = (date, stock.symbol.to_string(), serde_json::to_string(spec).unwrap());
@@ -14163,7 +14164,9 @@ mod tests {
let expression=r#"pattern_signal("{\"template\":\"ma_below\",\"parameters\":{\"ma_window\":20}}")"#;
let day=strategy.day_state(&ctx,dates[19]).unwrap();let stock=strategy.stock_state(&ctx,dates[19],symbol).unwrap();
assert!(!strategy.eval_bool(&ctx,expression,&day,Some(&stock),None).unwrap());
ctx.active_datetime=dates[19].and_hms_opt(10,0,0);
ctx.active_datetime=dates[19].and_hms_opt(10,18,0);
assert!(!strategy.eval_bool(&ctx,expression,&day,Some(&stock),None).unwrap());
ctx.execution_date=dates[19];
assert!(strategy.eval_bool(&ctx,expression,&day,Some(&stock),None).unwrap_err().to_string().contains("not_yet_visible"));
ctx.active_datetime=None;strategy.config.matching_type=MatchingType::CurrentBarClose;
assert!(strategy.eval_bool(&ctx,expression,&day,Some(&stock),None).unwrap_err().to_string().contains("requires_next_bar_open"));