rustrade-backtest
Deterministic backtest engine for rustrade Brains.
The same Brain trait used by rustrade for live trading drives the
backtest — no special "backtest-mode" code paths in the strategy, no
duplicate decision logic to keep in sync.
What's in this crate
| Type | Purpose |
|---|---|
Backtest |
The replay loop — feeds candles to a Brain and accumulates fills |
BacktestConfig |
Symbols, sizing config, slippage / fee models, initial cash, Sharpe annualisation |
SlippageModel |
Zero, FixedBps. Applied between the brain's signal and the simulated fill price |
FeeModel |
Zero, Flat, MakerTaker. Applied to every simulated fill |
load_csv / load_csv_str |
CSV → Vec<Candle> with a fixed time,open,high,low,close,volume layout |
sort_chronological |
Stable ascending-time sort for loaders that hand you newest-first |
BacktestResult |
Final stats: return %, win rate, max drawdown, equity curve, Sharpe, Sortino, # trades |
Quickstart
use Arc;
use ;
let candles = load_csv?;
let result = new
.with_candles
.run
.await?;
println!;
println!;
println!;
Multi-symbol replay
For portfolio strategies, attach a candle series per symbol. The engine
merges all series chronologically before replay and maintains
independent Position state per symbol against a single shared cash
balance.
let result = new
.with_symbol_candles
.with_symbol_candles
.run
.await?;
Brain parity
Any impl rustrade_core::Brain that runs through the live rustrade::Bot
runs in this engine unchanged. See tests/sma_replay.rs for the
regression test that pins this down: the same brain emits the same
sequence of decisions for the same candle series in both code paths.
Status
Phase 4b — adds CSV candle loader, Sharpe / Sortino, and multi-symbol
replay. Parquet loaders and book-walk slippage remain deferred. See the
workspace TODO.md.
Licence
MIT.