pub mod delta_hedge;
#[derive(Debug, Clone, Copy)]
pub struct MarketBar {
pub t: f64,
pub price: f64,
}
#[derive(Debug, Clone)]
pub struct StrategyAction {
pub target_position: f64,
pub signal: Option<String>,
}
pub trait Strategy {
fn name(&self) -> &'static str;
fn reset(&mut self) {}
fn on_bar(&mut self, bar: MarketBar) -> StrategyAction;
}
#[derive(Debug, Clone)]
pub struct BacktestResult {
pub equity: Vec<f64>,
pub positions: Vec<f64>,
pub trades: Vec<f64>,
}
pub struct Backtest {
pub cost_per_unit: f64,
}
impl Backtest {
pub fn new(cost_per_unit: f64) -> Self {
Self { cost_per_unit }
}
pub fn run<S: Strategy>(&self, strategy: &mut S, bars: &[MarketBar]) -> BacktestResult {
strategy.reset();
let n = bars.len();
let mut equity = Vec::with_capacity(n);
let mut positions = Vec::with_capacity(n);
let mut trades = Vec::with_capacity(n);
let mut cash = 0.0_f64;
let mut position = 0.0_f64;
for &bar in bars.iter() {
let action = strategy.on_bar(bar);
let trade = action.target_position - position;
cash -= trade * bar.price;
cash -= trade.abs() * self.cost_per_unit;
position = action.target_position;
trades.push(trade);
positions.push(position);
equity.push(cash + position * bar.price);
}
BacktestResult {
equity,
positions,
trades,
}
}
}