Realistic backtest fills¶
Configure a backtest with realistic execution: slippage on market orders, queue simulation for limit orders, and an exported equity curve. Same model in every binding.
1. Configure the simulator¶
#include "flox/backtest/backtest_config.h"
#include "flox/backtest/backtest_runner.h"
flox::BacktestConfig cfg;
cfg.initialCapital = 100'000.0;
cfg.feeRate = 0.0002; // 2 bps per fill
cfg.defaultSlippage = { flox::SlippageModel::FIXED_BPS, 0, flox::Price{}, 1.0, 0.0 }; // 1 bps default
cfg.queueModel = flox::QueueModel::TOB;
cfg.riskFreeRate = 0.0;
cfg.metricsAnnualizationFactor = 252.0;
flox::BacktestRunner runner(cfg);
cfg.perSymbolSlippage.emplace_back(
kEthUsd, flox::SlippageProfile{flox::SlippageModel::VOLUME_IMPACT, 0, 0.0, 0.01});
2. Run it¶
3. Inspect stats¶
The same fields are returned by every binding (snake_case in Python/Codon, camelCase in Node, BacktestStats struct in C++).
| Field | Description |
|---|---|
total_trades / totalTrades |
Number of closed trades |
net_pnl / netPnl |
Total P&L net of fees |
return_pct / returnPct |
Total return % |
sharpe / sharpeRatio |
Annualised Sharpe |
sortino / sortinoRatio |
Annualised Sortino |
max_drawdown_pct / maxDrawdownPct |
Worst drawdown |
win_rate / winRate |
Win rate |
profit_factor / profitFactor |
Gross profit / gross loss |
4. Export the equity curve¶
CSV header: timestamp_ns,equity,drawdown_pct. One row per closed trade.