qs_backtest/strategy.rs
1//! Strategy trait for strategy-driven backtests.
2//!
3//! Implement [`Strategy`] to define custom trading logic that reacts to
4//! market events and produces [`Action`]s for the engine to process.
5
6use qs_core::types::Action;
7
8use crate::data_feed::MarketEvent;
9
10/// A trading strategy that reacts to market events.
11///
12/// The backtest runner calls [`on_event`](Strategy::on_event) for every
13/// market event (tick or bar) in the data feed. The strategy inspects the
14/// event and returns zero or more [`Action`]s that the engine will process.
15///
16/// # Example
17///
18/// ```ignore
19/// use qs_backtest::{Strategy, MarketEvent};
20/// use qs_core::types::{Action, OrderType, Side};
21///
22/// struct BuyAndHold { entered: bool }
23///
24/// impl Strategy for BuyAndHold {
25/// fn on_event(&mut self, event: &MarketEvent) -> Vec<Action> {
26/// if self.entered { return vec![]; }
27/// if let MarketEvent::Tick { symbol, ask, .. } = event {
28/// self.entered = true;
29/// return vec![Action::Open {
30/// symbol: symbol.clone(),
31/// side: Side::Buy,
32/// order_type: OrderType::Market,
33/// price: Some(*ask),
34/// size: 1.0,
35/// stoploss: None,
36/// targets: vec![],
37/// rules: vec![],
38/// group: None,
39/// }];
40/// }
41/// vec![]
42/// }
43///
44/// fn on_finished(&mut self) -> Vec<Action> {
45/// vec![Action::CloseAll]
46/// }
47/// }
48/// ```
49pub trait Strategy {
50 /// Called for every market event in the data feed.
51 ///
52 /// Return an empty `Vec` to take no action on this event.
53 fn on_event(&mut self, event: &MarketEvent) -> Vec<Action>;
54
55 /// Called once after the data feed is exhausted.
56 ///
57 /// Use this to emit final actions such as closing all remaining
58 /// positions. The default implementation does nothing.
59 fn on_finished(&mut self) -> Vec<Action> {
60 vec![]
61 }
62}