Concept · The simulator
The gap between the price you expected to fill at and the price you actually filled at — caused by the market moving against you between the moment you placed the order and the moment it was executed.
You see BTC at $30,000 and click "buy." By the time the exchange processes your order, BTC is at $30,012. That $12 gap is slippage. It always pushes your fill price in the unfavorable direction: higher for buys, lower for sells.
Slippage has two root causes:
Config-knob slippage — a fixed bps (basis points; 1 bps = 0.01%) penalty applied per fill, e.g. "add 3 bps to every buy, subtract 3 bps from every sell." This approximates the average expected slippage without modeling the underlying cause. TradingView's Strategy Tester and 3Commas both expose this as a user-facing config option.
Realistic slippage from order book depth — derived from historical L2 (level-2 order book — the full ladder of bids and asks at every price level, captured every 100ms or so) data. You simulate: "given my order size and the available book depth at this timestamp, where would I actually have filled?" No hosted perp-capable backtest tool currently does this — it requires a fundamentally different data pipeline.
fill-resolver.ts:54: slippageBps: 0 on every backtest fill. The field exists in the Fill interface and is returned in every resolved fill — it simply always returns zero. The plumbing for a config-knob implementation already exists; only the value is hardcoded.
// fill-resolver.ts:54 (current backtest path)
return {
fillPrice: price,
slippageBps: 0, // field exists — always zero
feeBps: cfg.feeBps,
...
}
| Tool | Slippage modeled? | Type |
|---|---|---|
| TradingView Strategy Tester | Yes | Config-knob fixed bps |
| 3Commas | Yes | Config-knob fixed bps |
| PerpForge | No | slippageBps: 0 always |
| Any hosted perp backtest tool | No | Requires L2 — nobody has it |
Config-knob slippage is a catch-up gap for PerpForge — both major competitors have it and users may notice its absence. Realistic L2-based slippage is a frontier feature no tool offers.
Compare maker taker fees: no competitor models it, making it a frontier feature. Slippage is in the opposite category — an existing gap against established tools.
Slippage pushes real-account costs above simulator costs for every strategy, at every timeframe. Unlike funding rate (which penalizes hold-heavy strategies disproportionately), config-knob slippage affects all strategies proportionally — it is a uniform friction increase.
However: the current fleet's strategies hold for 1h–4h on average. Slippage is most painful for high-frequency strategies (scalpers) where it can consume most of the per-trade target. For swing strategies with 2–10% targets, a 3–5 bps slippage config has a meaningful but not dominant effect on results.
A working real order-book depth-walk model exists in apps/backend/src/orderbook/fill-calculator.ts (calculateFill / vwapDepthWalk). It walks actual order-book levels, computes a VWAP (volume-weighted average price — a fill spread across multiple price levels as liquidity is consumed), and reports slippageBps. It is called on the source === 'live' branch in fill-resolver.ts.
Live strategy evaluation has been inert since Phase 213. Every backtest result is source === 'backtest', which hardcodes slippageBps: 0. The slippage machinery is not missing — it is bypassed.
This model cannot replay history (no historical L2 data was ever captured), but it is the calibration oracle: collect live order-book snapshots going forward, measure realized slippage vs order size, fit the k parameter, apply that parameterization to historical candle data.
Since no historical L2 data exists, backtest slippage must be parametric — a calibrated formula applied to each fill. Three rungs of increasing fidelity, all using candle data already in Postgres:
| Rung | Formula | Lift | Limitation |
|---|---|---|---|
| 1 — config knob | fillPrice × (1 ± slippageBps/10k) |
Kills zero-slippage bias; afternoon of work; plumbing half-built | Flat rate — same charge on a deep BTC book as a thin altcoin |
| 2 — volatility-scaled | k × (candleRange / close) × 10k |
Charges more on the wide breakout candles where EMA-cross entries cluster | Still blind to order size |
| 3 — Almgren (target) | k × σ × √(orderNotional / candleVolumeNotional) |
Size-aware: distinguishes a $500 from a $50k order on a thin altcoin | Requires fitting k from live data |
σ = volatility in bps (approximated from candle range or ATR — average true range); candleVolumeNotional = candle volume already stored.
The Almgren-Chriss square-root market impact model (2001) is the industry standard for parametric slippage. It captures the key intuition: moving a large order through a thin book costs more than moving a small order through a deep one, and the relationship scales with the square root of size.
Build order: Rung 1 now (kills the zero-slippage optimism with no structural change), design config + trade-row fields toward Rung 3, Rung 2 as intermediate.
Stop-loss exits deserve extra adverse slippage. Real stops gap through the level — filling exactly at the stop price is a classic optimistic backtest assumption. Rung 1+ should apply an additional penalty on exit_reason: 'stop_loss' fills.
Zero-slippage flatters high-turnover strategies most (slippage paid per fill). The leaderboard selects from a large variant pool — the winner is disproportionately high-frequency, high-fill-count. That is the exact cohort zero-slippage inflates. Adding realistic slippage will reorder the leaderboard toward low-turnover survivors. That reordering is not a side effect — it is the honest result.
Minimal change: add slippageBps to SimulationConfig, pass it into fill-resolver.ts, and apply it as fillPrice × (1 + slippageBps/10000) for buys and fillPrice × (1 - slippageBps/10000) for sells, before the fill price is returned. The price adjustment must reach computePnl via the fill price — the slippageBps display field alone does not dent PnL.
wiki/qa-sessions/2026-06-29-session.md#q3 (first asked here)apps/backend/src/evaluation/position/fill-resolver.ts:54growth/research/market-competitors.md §4 (competitive landscape)Related concepts
See it in a real result →Put it to the test
Spawn your variant, run it on the same engine, and read the edge-significance verdict — before you risk real money.