Add daily strategy lifecycle hooks

This commit is contained in:
boris
2026-04-22 22:15:55 -07:00
parent 32e29fdf9a
commit 34e16520fa
3 changed files with 263 additions and 3 deletions

View File

@@ -190,10 +190,22 @@ where
)?;
self.extend_result(&mut result, delisting_report);
let decision = execution_idx
let decision_slot = execution_idx
.checked_sub(self.config.decision_lag_trading_days)
.map(|decision_idx| {
let decision_date = execution_dates[decision_idx];
.map(|decision_idx| (decision_idx, execution_dates[decision_idx]));
let (decision_index, decision_date) =
decision_slot.unwrap_or((execution_idx, execution_date));
let daily_context = StrategyContext {
execution_date,
decision_date,
decision_index,
data: &self.data,
portfolio: &portfolio,
};
self.strategy.before_trading(&daily_context)?;
let decision = decision_slot
.map(|(decision_idx, decision_date)| {
self.strategy.on_day(&StrategyContext {
execution_date,
decision_date,
@@ -215,6 +227,16 @@ where
portfolio.update_prices(execution_date, &self.data, PriceField::Close)?;
let post_trade_context = StrategyContext {
execution_date,
decision_date,
decision_index,
data: &self.data,
portfolio: &portfolio,
};
self.strategy.after_trading(&post_trade_context)?;
self.strategy.on_settlement(&post_trade_context)?;
let benchmark =
self.data
.benchmark(execution_date)

View File

@@ -15,7 +15,16 @@ use crate::universe::{DynamicMarketCapBandSelector, SelectionContext, UniverseSe
pub trait Strategy {
fn name(&self) -> &str;
fn before_trading(&mut self, _ctx: &StrategyContext<'_>) -> Result<(), BacktestError> {
Ok(())
}
fn on_day(&mut self, ctx: &StrategyContext<'_>) -> Result<StrategyDecision, BacktestError>;
fn after_trading(&mut self, _ctx: &StrategyContext<'_>) -> Result<(), BacktestError> {
Ok(())
}
fn on_settlement(&mut self, _ctx: &StrategyContext<'_>) -> Result<(), BacktestError> {
Ok(())
}
}
pub struct StrategyContext<'a> {