Backtesting

The engine provides a Monte Carlo backtest runner that evaluates a strategy across many independent market paths.

Single-path metrics

run_backtest drives Engine::step for a single path and computes:

MetricDescription
Total returnCumulative PnL / initial capital
Annualized returnReturn scaled to annual basis
VolatilityStandard deviation of returns
Sharpe ratioReturn / volatility (excess over risk-free)
Sortino ratioReturn / downside deviation
Max drawdownLargest peak-to-trough decline
Total tradesNumber of fills
Mean / max / min inventoryPosition statistics
Adverse selection (bps)Price movement against fills after N seconds
Realized edge (bps)Captured spread vs theoretical mid at execution
PnL spread / directionalDecomposition of PnL into spread capture and directional
Fill asymmetryRatio of buy to sell fills
Mean hold timeAverage time between opposing fills
Terminal liquidation costCost to flatten position at end of simulation
Inventory varianceVariance of position over the path

Multi-path summary

BacktestSummary aggregates these metrics across multiple Monte Carlo runs, reporting mean and standard deviation for each metric.

Usage

#![allow(unused)]
fn main() {
use engine::backtest::run_backtest;
use engine::data_source::SimulatedDataSource;
use engine::matcher::SimpleMatcher;
use engine::strategies::AvellanedaStoikovStrategy;

let gbm = GeometricBrownianMotion::new(0.0, 0.2, 100.0);
let source = SimulatedDataSource::new(gbm, 100.0, dt, spread, n_steps, 0.0);
let strategy = AvellanedaStoikovStrategy::new(params);

let result = run_backtest(
    &SimpleMatcher::new(),
    &strategy,
    source,
    initial_cash,
    transaction_cost_rate,
);
println!("Sharpe: {:.2}, Sortino: {:.2}", result.sharpe_ratio, result.sortino_ratio);
}

VecEnv for RL training

VecEnv runs multiple engine instances in parallel for reinforcement learning. Each slot is an independent simulation episode. The environment returns states (mid-price, position, time, spread, volatility, intensities), rewards, dones, and metadata.

Reward functions:

  • PnL: change in total equity (cash + position * mid).
  • DiffSharpe: differential Sharpe ratio, encouraging smooth risk-adjusted returns rather than absolute PnL.