补齐回测交易日期审计字段

This commit is contained in:
boris
2026-07-05 08:47:52 +08:00
parent 8543c3ab6d
commit ba2470aefe
4 changed files with 330 additions and 14 deletions
+89 -13
View File
@@ -1192,6 +1192,9 @@ where
});
report.order_events.push(OrderEvent {
date,
decision_date: None,
order_created_date: None,
execution_date: None,
order_id: Some(order_id),
symbol: self
.futures_open_orders
@@ -1229,6 +1232,9 @@ where
let mut report = FuturesExecutionReport::default();
report.order_events.push(OrderEvent {
date,
decision_date: None,
order_created_date: None,
execution_date: None,
order_id: Some(order_id),
symbol: intent.symbol.clone(),
side,
@@ -1704,27 +1710,52 @@ where
&mut portfolio,
&mut corporate_action_notes,
);
self.extend_result(&mut result, pending_cash_flow_report);
self.extend_result(
&mut result,
pending_cash_flow_report,
execution_date,
execution_date,
);
let corporate_action_report = self.apply_corporate_actions(
execution_date,
&mut portfolio,
&mut corporate_action_notes,
)?;
self.extend_result(&mut result, corporate_action_report);
self.extend_result(
&mut result,
corporate_action_report,
execution_date,
execution_date,
);
let receivable_report = self.settle_cash_receivables(
execution_date,
&mut portfolio,
&mut corporate_action_notes,
)?;
self.extend_result(&mut result, receivable_report);
self.extend_result(
&mut result,
receivable_report,
execution_date,
execution_date,
);
let delisting_report = self.settle_delisted_positions(
execution_date,
&mut portfolio,
&mut corporate_action_notes,
)?;
self.extend_result(&mut result, delisting_report);
self.extend_result(
&mut result,
delisting_report,
execution_date,
execution_date,
);
let futures_open_order_report = self.process_futures_open_orders(execution_date);
self.extend_result(&mut result, futures_open_order_report);
self.extend_result(
&mut result,
futures_open_order_report,
execution_date,
execution_date,
);
let decision_slot = execution_idx
.checked_sub(self.config.decision_lag_trading_days)
@@ -1750,7 +1781,7 @@ where
let day_fills = report.fill_events.clone();
let broker_diagnostics = report.diagnostics.clone();
let execution_risk_decisions = risk_decisions_from_order_events(&day_orders);
self.extend_result(&mut result, report);
self.extend_result(&mut result, report, execution_date, execution_date);
result.risk_decisions.extend(execution_risk_decisions);
let benchmark =
@@ -2014,8 +2045,10 @@ where
None,
None,
)?;
let mut report = self.broker.execute(
let mut report = self.broker.execute_with_event_dates(
execution_date,
decision_date,
decision_date,
&mut portfolio,
&self.data,
&auction_decision,
@@ -2260,9 +2293,14 @@ where
None,
None,
)?;
let mut intraday_report =
self.broker
.execute(execution_date, &mut portfolio, &self.data, &decision)?;
let mut intraday_report = self.broker.execute_with_event_dates(
execution_date,
decision_date,
decision_date,
&mut portfolio,
&self.data,
&decision,
)?;
let post_intraday_open_orders = self.open_order_views();
publish_process_events(
&mut self.strategy,
@@ -2426,8 +2464,10 @@ where
Some(minute_time),
Some(minute_time),
)?;
let mut minute_report = self.broker.execute_between(
let mut minute_report = self.broker.execute_between_with_event_dates(
execution_date,
decision_date,
decision_date,
&mut portfolio,
&self.data,
&minute_decision,
@@ -2750,7 +2790,7 @@ where
let day_fills = report.fill_events.clone();
let broker_diagnostics = report.diagnostics.clone();
let execution_risk_decisions = risk_decisions_from_order_events(&day_orders);
self.extend_result(&mut result, report);
self.extend_result(&mut result, report, decision_date, execution_date);
result.risk_decisions.extend(decision.risk_decisions);
result.risk_decisions.extend(execution_risk_decisions);
@@ -2838,8 +2878,11 @@ where
fn extend_result(
&self,
result: &mut BacktestResult,
report: BrokerExecutionReport,
mut report: BrokerExecutionReport,
decision_date: NaiveDate,
execution_date: NaiveDate,
) -> BrokerExecutionReport {
annotate_broker_report_dates(&mut report, decision_date, decision_date, execution_date);
result.order_events.extend(report.order_events.clone());
result.fills.extend(report.fill_events.clone());
result
@@ -3063,6 +3106,9 @@ where
);
report.fill_events.push(FillEvent {
date,
decision_date: None,
order_created_date: None,
execution_date: None,
order_id: None,
symbol: receivable.symbol.clone(),
side: OrderSide::Buy,
@@ -3366,6 +3412,9 @@ where
notes.push(reason.clone());
report.order_events.push(OrderEvent {
date,
decision_date: None,
order_created_date: None,
execution_date: None,
order_id: None,
symbol: symbol.clone(),
side: OrderSide::Sell,
@@ -3376,6 +3425,9 @@ where
});
report.fill_events.push(FillEvent {
date,
decision_date: None,
order_created_date: None,
execution_date: None,
order_id: None,
symbol: symbol.clone(),
side: OrderSide::Sell,
@@ -3827,6 +3879,24 @@ fn merge_futures_report(target: &mut BrokerExecutionReport, incoming: FuturesExe
target.diagnostics.extend(incoming.diagnostics);
}
fn annotate_broker_report_dates(
report: &mut BrokerExecutionReport,
decision_date: NaiveDate,
order_created_date: NaiveDate,
execution_date: NaiveDate,
) {
for event in &mut report.order_events {
event.decision_date.get_or_insert(decision_date);
event.order_created_date.get_or_insert(order_created_date);
event.execution_date.get_or_insert(execution_date);
}
for fill in &mut report.fill_events {
fill.decision_date.get_or_insert(decision_date);
fill.order_created_date.get_or_insert(order_created_date);
fill.execution_date.get_or_insert(execution_date);
}
}
fn risk_decisions_from_order_events(order_events: &[OrderEvent]) -> Vec<FidcRiskDecisionAudit> {
order_events
.iter()
@@ -4021,6 +4091,9 @@ fn futures_cancel_report(
});
report.order_events.push(OrderEvent {
date,
decision_date: None,
order_created_date: None,
execution_date: None,
order_id: Some(order.order_id),
symbol: order.intent.symbol.clone(),
side,
@@ -4779,6 +4852,9 @@ mod tests {
assert_eq!(result.fills.len(), 1);
assert_eq!(result.fills[0].date, d(2025, 1, 3));
assert_eq!(result.fills[0].decision_date, Some(d(2025, 1, 2)));
assert_eq!(result.fills[0].order_created_date, Some(d(2025, 1, 2)));
assert_eq!(result.fills[0].execution_date, Some(d(2025, 1, 3)));
assert_eq!(result.fills[0].price, 12.0);
}