pub trait Strategy: Send + Sync {
// Required methods
fn name(&self) -> &str;
fn required_indicators(&self) -> Vec<(String, Indicator)>;
fn on_candle(&self, ctx: &StrategyContext<'_>) -> Signal;
// Provided method
fn warmup_period(&self) -> usize { ... }
}Expand description
Core strategy trait - implement this for custom strategies.
§Example
ⓘ
use finance_query::backtesting::{Strategy, StrategyContext, Signal};
use finance_query::indicators::Indicator;
struct MyStrategy {
sma_period: usize,
}
impl Strategy for MyStrategy {
fn name(&self) -> &str {
"My Custom Strategy"
}
fn required_indicators(&self) -> Vec<(String, Indicator)> {
vec![
(format!("sma_{}", self.sma_period), Indicator::Sma(self.sma_period)),
]
}
fn on_candle(&self, ctx: &StrategyContext) -> Signal {
let sma = ctx.indicator(&format!("sma_{}", self.sma_period));
let close = ctx.close();
match sma {
Some(sma_val) if close > sma_val && !ctx.has_position() => {
Signal::long(ctx.timestamp(), close)
}
Some(sma_val) if close < sma_val && ctx.is_long() => {
Signal::exit(ctx.timestamp(), close)
}
_ => Signal::hold(),
}
}
}Required Methods§
Sourcefn required_indicators(&self) -> Vec<(String, Indicator)>
fn required_indicators(&self) -> Vec<(String, Indicator)>
Required indicators this strategy needs.
Returns list of (indicator_name, Indicator) pairs.
The engine will pre-compute these and make them available via StrategyContext::indicator().
Sourcefn on_candle(&self, ctx: &StrategyContext<'_>) -> Signal
fn on_candle(&self, ctx: &StrategyContext<'_>) -> Signal
Called on each candle to generate a signal.
Return Signal::hold() for no action, Signal::long() to enter long,
Signal::short() to enter short, or Signal::exit() to close position.
Provided Methods§
Sourcefn warmup_period(&self) -> usize
fn warmup_period(&self) -> usize
Optional: minimum candles required before strategy can generate signals. Default is 1 (strategy can run from first candle).