Slippage¶
The backtest engine applies slippage to market-style fills: market orders, triggered stop-market orders, and triggered trailing stops. Limit orders trade at their posted price; queue simulation handles their realism separately.
Slippage is configured per BacktestConfig with a default profile and optional per-symbol overrides.
SlippageProfile¶
enum class SlippageModel : uint8_t { NONE, FIXED_TICKS, FIXED_BPS, VOLUME_IMPACT };
struct SlippageProfile
{
SlippageModel model{SlippageModel::NONE};
int32_t ticks{0}; // FIXED_TICKS: number of ticks against the taker
Price tickSize{}; // FIXED_TICKS: price per tick; zero falls back to one raw price unit
double bps{0.0}; // FIXED_BPS: basis points against the taker
double impactCoeff{0.0}; // VOLUME_IMPACT: coeff * (orderQty / levelQty)
};
| Model | Meaning |
|---|---|
NONE |
Fill at the book-reported best price. |
FIXED_TICKS |
Shift the fill by ticks * tickSize against the taker (buys pay more, sells receive less). Set tickSize to the venue's minimum price increment; leaving it zero falls back to one raw price unit, which is rarely what you want for real instruments. |
FIXED_BPS |
Shift the fill by bps basis points of the fill price. bps = 10.0 is 10 bps = 0.10%. |
VOLUME_IMPACT |
Shift proportional to impactCoeff * (orderQty / levelQty). Larger orders relative to top-of-book size move the price more. |
Applying slippage¶
BacktestConfig cfg;
cfg.defaultSlippage = {SlippageModel::FIXED_BPS, 0, Price{}, 5.0, 0.0}; // 5 bps default
cfg.perSymbolSlippage.emplace_back(
kBtcUsd, SlippageProfile{SlippageModel::VOLUME_IMPACT, 0, Price{}, 0.0, 0.01});
BacktestRunner runner(cfg); // config is forwarded to the simulated executor
For direct-executor use:
SimulatedExecutor exec(clock);
exec.setDefaultSlippage({SlippageModel::FIXED_BPS, 0, Price{}, 5.0, 0.0});
exec.setSymbolSlippage(kBtcUsd,
{SlippageModel::FIXED_TICKS, 3, Price::fromDouble(0.25), 0.0, 0.0});
Bindings¶
| Language | Entry point |
|---|---|
| Python | SimulatedExecutor.set_default_slippage(model, ticks, tick_size, bps, impact_coeff) / set_symbol_slippage(symbol, ...) |
| C API | flox_executor_set_default_slippage(exec, model, ticks, tick_size, bps, impact) |
| Codon | SimulatedExecutor.set_default_slippage(model, ticks, tick_size, bps, impact_coeff) |
| JavaScript | executor.setDefaultSlippage("fixed_bps", 0, 0, 5.0, 0) |
All bindings accept the same model values (none, fixed_ticks, fixed_bps, volume_impact) either as strings (Python, JS, Codon enum constants) or as the FloxSlippageModel enum in the C API. Pass tick_size = 0.0 for NONE / FIXED_BPS / VOLUME_IMPACT; it is only meaningful for FIXED_TICKS.