test: align minute fixtures and missing-data assertions with strict contracts

This commit is contained in:
boris
2026-09-11 04:56:25 +08:00
parent 4f4c1ab7e0
commit e42dc6938b
+15 -23
View File
@@ -2143,15 +2143,15 @@ fn strategy_context_exposes_advanced_data_helpers() {
fn engine_runs_minute_hooks_and_executes_minute_orders() { fn engine_runs_minute_hooks_and_executes_minute_orders() {
let date = d(2025, 1, 2); let date = d(2025, 1, 2);
let data = DataSet::from_components_with_actions_and_quotes( let data = DataSet::from_components_with_actions_and_quotes(
vec![Instrument { ["000001.SZ", "000002.SZ"].into_iter().map(|symbol| Instrument {
symbol: "000001.SZ".to_string(), symbol: symbol.to_string(),
name: "Anchor".to_string(), name: "Anchor".to_string(),
board: "SZ".to_string(), board: "SZ".to_string(),
round_lot: 100, round_lot: 100,
listed_at: Some(d(2020, 1, 1)), listed_at: Some(d(2020, 1, 1)),
delisted_at: None, delisted_at: None,
status: "active".to_string(), status: "active".to_string(),
}], }).collect(),
vec![DailyMarketSnapshot { vec![DailyMarketSnapshot {
date, date,
symbol: "000001.SZ".to_string(), symbol: "000001.SZ".to_string(),
@@ -4162,7 +4162,7 @@ impl Strategy for BuyMissingRowThenHoldStrategy {
} }
#[test] #[test]
fn engine_carries_position_price_when_current_market_row_is_missing() { fn engine_rejects_an_unexplained_missing_holding_close() {
let date1 = d(2025, 5, 26); let date1 = d(2025, 5, 26);
let date2 = d(2025, 5, 27); let date2 = d(2025, 5, 27);
let data = DataSet::from_components( let data = DataSet::from_components(
@@ -4230,20 +4230,16 @@ fn engine_carries_position_price_when_current_market_row_is_missing() {
}, },
); );
let result = engine let error = engine
.run() .run()
.expect("backtest should not fail on one missing holding row"); .expect_err("unknown missing market data must not become a carried close");
assert_eq!(result.equity_curve.len(), 2); let detail = format!("{error:?}");
assert!( assert!(detail.contains("MissingSnapshot") && detail.contains("close price"));
result assert!(detail.contains("601028.SH") && detail.contains("2025-05-27"));
.daily_holdings
.iter()
.any(|holding| holding.date == date2 && holding.symbol == "601028.SH")
);
} }
#[test] #[test]
fn platform_strategy_skips_position_stop_take_when_current_market_row_is_missing() { fn platform_strategy_cannot_hide_missing_valuation_by_skipping_stop_take() {
let date1 = d(2025, 5, 26); let date1 = d(2025, 5, 26);
let date2 = d(2025, 5, 27); let date2 = d(2025, 5, 27);
let data = DataSet::from_components( let data = DataSet::from_components(
@@ -4333,14 +4329,10 @@ fn platform_strategy_skips_position_stop_take_when_current_market_row_is_missing
}, },
); );
let result = engine let error = engine
.run() .run()
.expect("platform strategy should hold through a missing current market row"); .expect_err("skipping a stop condition cannot fabricate the missing valuation");
assert_eq!(result.equity_curve.len(), 2); let detail = format!("{error:?}");
assert!( assert!(detail.contains("MissingSnapshot") && detail.contains("close price"));
result assert!(detail.contains("601028.SH") && detail.contains("2025-05-27"));
.daily_holdings
.iter()
.any(|holding| holding.date == date2 && holding.symbol == "601028.SH")
);
} }