Add rqalpha-style scheduler time rules

This commit is contained in:
boris
2026-04-23 06:34:07 -07:00
parent fae09afb86
commit 5265f82fef
10 changed files with 557 additions and 233 deletions

View File

@@ -13,7 +13,7 @@ use crate::events::{
use crate::metrics::{BacktestMetrics, compute_backtest_metrics};
use crate::portfolio::{CashReceivable, HoldingSummary, PortfolioState};
use crate::rules::EquityRuleHooks;
use crate::scheduler::{ScheduleRule, ScheduleStage, Scheduler};
use crate::scheduler::{ScheduleRule, ScheduleStage, Scheduler, default_stage_time};
use crate::strategy::{Strategy, StrategyContext};
#[derive(Debug, Error)]
@@ -274,6 +274,21 @@ where
ProcessEventKind::BeforeTrading,
"before_trading",
)?;
let _ = collect_scheduled_decisions(
&mut self.strategy,
&scheduler,
execution_date,
ScheduleStage::BeforeTrading,
&schedule_rules,
decision_date,
decision_index,
&self.data,
&portfolio,
&pre_open_orders,
&mut process_events,
&mut self.process_event_bus,
default_stage_time(ScheduleStage::BeforeTrading),
)?;
publish_phase_event(
&mut self.strategy,
&mut self.process_event_bus,
@@ -315,6 +330,7 @@ where
&pre_open_orders,
&mut process_events,
&mut self.process_event_bus,
default_stage_time(ScheduleStage::OpenAuction),
)?;
auction_decision.merge_from(self.strategy.open_auction(&StrategyContext {
execution_date,
@@ -417,6 +433,7 @@ where
&on_day_open_orders,
&mut process_events,
&mut self.process_event_bus,
default_stage_time(ScheduleStage::OnDay),
)?);
publish_phase_event(
&mut self.strategy,
@@ -512,6 +529,21 @@ where
ProcessEventKind::AfterTrading,
"after_trading",
)?;
let _ = collect_scheduled_decisions(
&mut self.strategy,
&scheduler,
execution_date,
ScheduleStage::AfterTrading,
&schedule_rules,
decision_date,
decision_index,
&self.data,
&portfolio,
&post_trade_open_orders,
&mut process_events,
&mut self.process_event_bus,
default_stage_time(ScheduleStage::AfterTrading),
)?;
let mut close_report = self.broker.after_trading(execution_date);
publish_process_events(
&mut self.strategy,
@@ -583,6 +615,21 @@ where
ProcessEventKind::Settlement,
"settlement",
)?;
let _ = collect_scheduled_decisions(
&mut self.strategy,
&scheduler,
execution_date,
ScheduleStage::Settlement,
&schedule_rules,
decision_date,
decision_index,
&self.data,
&portfolio,
&post_close_open_orders,
&mut process_events,
&mut self.process_event_bus,
default_stage_time(ScheduleStage::Settlement),
)?;
publish_phase_event(
&mut self.strategy,
&mut self.process_event_bus,
@@ -1094,9 +1141,10 @@ fn collect_scheduled_decisions<S: Strategy>(
open_orders: &[crate::strategy::OpenOrderView],
process_events: &mut Vec<ProcessEvent>,
process_event_bus: &mut ProcessEventBus,
current_time: Option<chrono::NaiveTime>,
) -> Result<crate::strategy::StrategyDecision, BacktestError> {
let mut combined = crate::strategy::StrategyDecision::default();
for rule in scheduler.triggered_rules(execution_date, stage, rules) {
for rule in scheduler.triggered_rules_at(execution_date, stage, current_time, rules) {
publish_phase_event(
strategy,
process_event_bus,
@@ -1214,8 +1262,11 @@ fn publish_process_events<S: Strategy>(
fn stage_label(stage: ScheduleStage) -> &'static str {
match stage {
ScheduleStage::BeforeTrading => "before_trading",
ScheduleStage::OpenAuction => "open_auction",
ScheduleStage::OnDay => "on_day",
ScheduleStage::AfterTrading => "after_trading",
ScheduleStage::Settlement => "settlement",
}
}