---
title: Slippage and Costs
description: Commission, flat slippage, and slippageModel="bookEstimate", which prices fills from recorded order-book depth where the platform has it.
---

> **Since engine 3.0.61; verified against engine 3.0.61.** Every example on this page is an executed probe against that build.

## Commission

`commissionPercent` is charged on every fill as a percent of the fill's notional value, on entries and exits alike. Fees reduce equity immediately and are reported per trade and in the totals.

## Flat slippage (the default)

`slippageBps` applies adversely to every fill that crosses the market: market entries, stop entries, protective stops, and trailing stops. Buys fill at `price * (1 + bps/10000)`, sells mirror. Limit fills, including take-profit legs, are exempt: a limit price is a bound and can fill better but never worse.

Flat slippage is honest about being a constant: it neither grows with your order size nor tightens on liquid pairs. When you want size-aware and pair-aware slippage, opt into the book estimate.

## Order-book slippage: slippageModel="bookEstimate"

```javascript title="scripts/probes/strategies/book-estimate.ks"
//@version=2
strategy(title="Book Estimate Demo", initialCapital=10000, qtyType="fixed", qtyValue=1, slippageBps=5, slippageModel="bookEstimate")

timeseries bars = ohlcv(symbol=currentSymbol, exchange=currentExchange)
timeseries fast = sma(source=bars.close, period=5)
timeseries slow = sma(source=bars.close, period=20)

if (crossover(fast, slow)) {
  strategy.entry("L", "long")
}
if (crossunder(fast, slow)) {
  strategy.closeAll()
}

plotLine(value=fast, width=1, colors=["#4f8cff"], label=["Fast SMA"], desc=["5-period SMA of close"])
plotLine(value=slow, width=1, colors=["#f59e0b"], label=["Slow SMA"], desc=["20-period SMA of close"])
```

With `slippageModel="bookEstimate"`, backtests load the pair's recorded order-book snapshots (one per chart bar) and price every market-crossing fill by walking that depth:

- **The walk.** A buy consumes the ask side from the best level down, a sell consumes bids, for the order's quantity. The resulting volume-weighted price versus the best level gives an impact fraction, which is applied to the bar-derived fill price. The book contributes its depth shape, never its absolute price levels, so a modestly stale snapshot degrades gracefully instead of teleporting your fill.
- **Size awareness.** Reversals walk the full quantity they actually cross (the closing leg plus the opening leg). Fills that land on the same bar share that bar's displayed liquidity: a later fill starts below what earlier fills consumed, and exhausting the visible book sends the fill to the declared fallback rather than pretending depth was infinite.
- **Adverse-moment stress.** Protective stop and trailing fills consume twice their quantity from the book. They execute into adverse moments, and a calm snapshot understates that cost.
- **Limit exemption.** Limit fills, including take-profit legs, remain exempt, same as the flat model.

### When the book cannot answer

The walk refuses to invent numbers. A fill falls back to the declared `slippageBps` and is counted when:

- the pair has no recorded book history at all (the run details say so),
- no snapshot covers that bar (gaps, or the most recent minutes of a live chart),
- the order's (stressed) quantity exceeds the visible depth,
- the snapshot's best level sits more than 5% from the fill price (a stale or mismatched book is worse than no book).

This is an estimate by construction: aggregated snapshots cannot express queue dynamics or replenishment. That is exactly why the counts ship next to the number.

### Reading the slippage disclosure

The Strategy Tester's run-details popover discloses how slippage was priced:

- **"Slippage: order-book depth estimate, avg N bps across M fills"**: every market-crossing fill was priced from recorded depth.
- **"Slippage: order-book depth estimate on N of M fills, declared rate for the rest"**: partial book coverage over the replay window.
- **"Slippage: order-book depth not recorded for this pair, declared rate applied"**: the model fell back entirely; the result is equivalent to `slippageModel="fixed"`.

The model is declared in the script, not toggled in the UI, so a shared strategy reproduces the same way for everyone who runs it. Book data loads for plus-tier backtests; pairs and epochs without recorded books degrade to the declared rate with the disclosure above.

## Practical guidance

- Set `slippageBps` even when using `bookEstimate`: it is your fallback rate wherever the book cannot answer, so make it realistic for the pair.
- Size matters now. A strategy that trades 0.1% of equity and one that trades 50x leverage will see very different book impacts on the same signals, which is the point.
- If the disclosure reports mostly fallback fills on a pair you care about, prefer the flat model with a defensible `slippageBps` instead of an estimate that rarely engaged.
