Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 98732bbc46 |
@@ -1298,6 +1298,7 @@ where
|
|||||||
submission_time,
|
submission_time,
|
||||||
);
|
);
|
||||||
if self.broker.execution_price_field() != PriceField::Last
|
if self.broker.execution_price_field() != PriceField::Last
|
||||||
|
&& !self.broker.matching_type_uses_intraday_quotes()
|
||||||
&& !decision_has_algo_execution(decision)
|
&& !decision_has_algo_execution(decision)
|
||||||
&& post_close_window.is_none()
|
&& post_close_window.is_none()
|
||||||
{
|
{
|
||||||
@@ -8941,6 +8942,47 @@ mod tests {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn next_open_observation_loads_quotes_even_when_execution_price_is_open() {
|
||||||
|
use crate::execution_capacity::VolumeCapacityMode;
|
||||||
|
let date = d(2025, 1, 3);
|
||||||
|
let signal = d(2025, 1, 2);
|
||||||
|
let open = NaiveTime::from_hms_opt(9, 30, 0).unwrap();
|
||||||
|
for mode in [VolumeCapacityMode::ExecutionObservation, VolumeCapacityMode::SessionCapacityAudit] {
|
||||||
|
let mut broker = BrokerSimulator::new_with_execution_price(
|
||||||
|
ChinaAShareCostModel::default(), ChinaEquityRuleHooks, PriceField::Open,
|
||||||
|
).with_matching_type(MatchingType::NextBarOpen)
|
||||||
|
.with_volume_limit(true).with_volume_capacity_mode(mode).with_liquidity_limit(false);
|
||||||
|
if mode == VolumeCapacityMode::ExecutionObservation {
|
||||||
|
broker = broker.with_intraday_execution_start_time(open);
|
||||||
|
}
|
||||||
|
let calls = Arc::new(Mutex::new(Vec::new()));
|
||||||
|
let captured = calls.clone();
|
||||||
|
let mut engine = BacktestEngine::new(dataset(), BuyWhenDecisionDateStrategy { decision_date: signal }, broker,
|
||||||
|
BacktestConfig { initial_cash: 100_000., benchmark_code: "000852.SH".into(),
|
||||||
|
start_date: Some(signal), end_date: Some(date), decision_lag_trading_days: 1,
|
||||||
|
execution_price_field: PriceField::Open })
|
||||||
|
.with_execution_quote_loader(move |request| {
|
||||||
|
captured.lock().unwrap().push(request.clone());
|
||||||
|
Ok(clock_probe_data(request.date, &[(9,30,10.)]).snapshot_components().execution_quotes)
|
||||||
|
});
|
||||||
|
let decision = StrategyDecision { order_intents: vec![OrderIntent::Shares {
|
||||||
|
symbol: SYMBOL.into(), quantity: 100, reason: "next-open-loader-regression".into(),
|
||||||
|
}], ..Default::default() };
|
||||||
|
engine.ensure_execution_quotes_for_decision(date, signal, &PortfolioState::new(100_000.), &[], &decision, None, None).unwrap();
|
||||||
|
let calls = calls.lock().unwrap();
|
||||||
|
if mode == VolumeCapacityMode::ExecutionObservation {
|
||||||
|
assert_eq!(calls.len(), 1);
|
||||||
|
assert_eq!(calls[0].date, date);
|
||||||
|
assert_eq!(calls[0].start_time, Some(open));
|
||||||
|
assert_eq!(calls[0].symbols, BTreeSet::from([SYMBOL.to_string()]));
|
||||||
|
assert_eq!(engine.data.execution_quotes_on(date, SYMBOL).len(), 1);
|
||||||
|
} else {
|
||||||
|
assert!(calls.is_empty(), "daily audit must not silently become an opening-liquidity model");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn full_minute_coverage_rejects_missing_active_bars_but_allows_paused_or_zero_volume() {
|
fn full_minute_coverage_rejects_missing_active_bars_but_allows_paused_or_zero_volume() {
|
||||||
let first = d(2025, 1, 2);
|
let first = d(2025, 1, 2);
|
||||||
|
|||||||
@@ -9,3 +9,5 @@
|
|||||||
执行状态新增 `last_target_weight_ratios`,首次记录精确比例升级schema2。旧schema1可读但不得携带新比例字段;旧消费者应拒绝新状态,回滚不能删除或降精度重写状态。回测、Paper、Live及Strategy Runtime都必须共同消费该比例,ETF顺延目标也携带相同比例。
|
执行状态新增 `last_target_weight_ratios`,首次记录精确比例升级schema2。旧schema1可读但不得携带新比例字段;旧消费者应拒绝新状态,回滚不能删除或降精度重写状态。回测、Paper、Live及Strategy Runtime都必须共同消费该比例,ETF顺延目标也携带相同比例。
|
||||||
|
|
||||||
新增临界100股补仓、调序不改变等权金额、停牌/候补、显式部分预算、状态序列化回读回归。当前为候选:本机Rust语法检查通过,类型/运行测试受Xcode许可阻断,转177验证;未通过Linux测试前不得发布。
|
新增临界100股补仓、调序不改变等权金额、停牌/候补、显式部分预算、状态序列化回读回归。当前为候选:本机Rust语法检查通过,类型/运行测试受Xcode许可阻断,转177验证;未通过Linux测试前不得发布。
|
||||||
|
|
||||||
|
后续真实Source回放补充:原始报价门禁打开后,Engine仍因PriceField::Open提前跳过行情加载;不能把此错误标成原始数据缺失。补充按实际撮合是否需要盘中观测判断加载路径,测试验证NextBarOpen加载执行日09:30报价、日终审计保持不加载。实际发布、回放及缺数清单以工作区`docs/fidc/stock-pool-precision-correction-20260919.md`为准。
|
||||||
|
|||||||
Reference in New Issue
Block a user