Short answer: Slippage in crypto is the difference between the price you expected and the average price you actually got, usually in basis points. On an order book it comes from walking through price levels and from the book moving before your order arrives; on an AMM pool, "slippage tolerance" is a different thing, a limit on how far the result may move before the swap reverts. It is a cost to measure, and every example figure below is hypothetical.
The number only means something once you fix a sign, a reference price and an order size, which this page does with tested Python on a synthetic book. To compute one order without code, use the slippage calculator. Facts were read on official pages on 5 November 2026.
This is general education, not a recommendation of any platform, strategy or setting, and no method here is claimed to lower costs enough to make money. Trading can lose money. Rules depend on your jurisdiction and each platform's terms. Article 99/A of Capital Markets Law No. 6362 treats activity by foreign crypto-asset platforms directed at Turkish residents as unauthorized.
Slippage crypto meaning: the formula and its sign
Slippage is the average fill price measured against a reference price, signed so that a positive number always means a worse result for you.
buy: slippage_bps = (average_fill - reference) / reference * 10000
sell: slippage_bps = (reference - average_fill) / reference * 10000In price terms, it is the same difference without the division. One basis point is 0.01%. A negative number means a better price than the reference, which some platforms call positive slippage, as Binance Academy's glossary (opens in a new tab) does, so check the convention before comparing figures. Spread is separate: it is the gap between best bid and best ask, and you cross it even with a very small market order.
Which reference price: mid, arrival or decision?
Use the reference that matches your question, because the same fill can show very different slippage against different prices.
| Reference | Value | Slippage | What it includes |
|---|---|---|---|
| Best ask on arrival | 100.00 | 5.62 bps | Walking the book only |
| Mid on arrival | 99.95 | 10.63 bps | Walking the book plus half the spread |
| Mid at decision | 99.80 | 25.68 bps | All of that plus price movement between decision and arrival |
Say which one you report: 5 bps against the best ask and 5 bps against the decision price describe different systems. Logging decision time, arrival time and each fill is covered in transaction cost analysis.
Slippage crypto example: walking an order book
A market order takes the best level, then the next, so its average price weights each level's price by the quantity taken there.
| Price | Available | Taken | Cost |
|---|---|---|---|
| 100.00 | 2 | 2 | 200.00 |
| 100.05 | 3 | 3 | 300.15 |
| 100.10 | 5 | 3 | 300.30 |
| Total | 8 | 800.45 | |
The average is 800.45 / 8 = 100.05625. In code, with Decimal so that prices stay exact, saved as slip_final.py:
from decimal import Decimal as D
ASKS = [("100.00", "2"), ("100.05", "3"), ("100.10", "5"), ("100.30", "10"), ("101.00", "20")]
BIDS = [("99.90", "4"), ("99.85", "3"), ("99.70", "8"), ("99.40", "15")] # hypothetical book
MID = (D(ASKS[0][0]) + D(BIDS[0][0])) / 2
SIGN = {"buy": 1, "sell": -1}
def walk(levels, qty):
"""Fill qty against levels, best first. Returns average price and filled quantity."""
want = D(str(qty))
if not want.is_finite() or want <= 0:
raise ValueError(f"bad quantity {qty}")
cost = filled = D(0)
for price, available in levels:
take = min(want - filled, D(available))
cost += take * D(price)
filled += take
if filled == want:
break
if filled == 0:
raise ValueError("empty book")
return cost / filled, filled
def slippage_bps(side, average, reference):
"""Positive means worse than the reference, for buys and for sells."""
return SIGN[side] * (D(average) - D(reference)) / D(reference) * 10000
def total_cost(side, qty, reference, fee_bps):
average, filled = walk(ASKS if SIGN[side] == 1 else BIDS, qty)
slip_cash = SIGN[side] * (average - D(reference)) * filled
fee_cash = average * filled * D(str(fee_bps)) / 10000
bps = (slip_cash + fee_cash) / (D(reference) * filled) * 10000
return filled, round(slip_cash, 4), round(fee_cash, 4), round(bps, 2)
if __name__ == "__main__":
print("mid", MID)
for side, qty in [("buy", 8), ("sell", 8), ("buy", 50)]:
book = ASKS if side == "buy" else BIDS
average, filled = walk(book, qty)
print(f"{side} {qty}: average {average:.4f}, filled {filled}, "
f"{slippage_bps(side, average, MID):.2f} bps vs mid, "
f"{slippage_bps(side, average, book[0][0]):.2f} bps vs best")
average, _ = walk(ASKS, 8)
print(f"buy 8 vs a decision mid of 99.80: {slippage_bps('buy', average, '99.80'):.2f} bps")
print("filled, slippage cash, fee cash, total bps:", total_cost("buy", 8, MID, 10))
for bad in (lambda: walk(ASKS, -5), lambda: walk([], 1), lambda: slippage_bps("Buy", 1, 1)):
try:
bad()
except (ValueError, KeyError) as error:
print("rejected:", repr(error))Output (Python 3.11.3, synthetic book):
mid 99.95
buy 8: average 100.0562, filled 8, 10.63 bps vs mid, 5.62 bps vs best
sell 8: average 99.8562, filled 8, 9.38 bps vs mid, 4.38 bps vs best
buy 50: average 100.5912, filled 40, 64.16 bps vs mid, 59.12 bps vs best
buy 8 vs a decision mid of 99.80: 25.68 bps
filled, slippage cash, fee cash, total bps: (Decimal('8'), Decimal('0.8500'), Decimal('0.8004'), Decimal('20.64'))
rejected: ValueError('bad quantity -5')
rejected: ValueError('empty book')
rejected: KeyError('Buy')The last three lines are deliberate failures: without the checks, -5 would return an average of 100.00 and "Buy" would flip the sign silently. The buy of 50 filled only 40, because the book ended there: a depth snapshot is finite. The same walk reads a public snapshot unchanged, since Binance's depth endpoint (opens in a new tab) returns [price, quantity] strings (default 100 levels, maximum 5,000). It ran against the public Spot Testnet on 5 November 2026; that output is not shown, because exchange data terms can limit display, as the crypto price API guide notes. A snapshot also goes stale at once, so this is an estimate of cost, not a quote.
Slippage plus fees: total cost of a fill
Add the fee to slippage to get what the fill really cost, and count both on each side of a round trip.
Hypothetical example. The buy of 8 with a 10 bps fee: slippage against mid is 8 x (100.05625 - 99.95) = 0.85, the fee is 800.45 x 0.001 = 0.80, and the total is 1.65, or 20.64 bps of the 799.60 reference value. Selling later costs its own slippage and fee again.
Fees vary by platform, account and order type, so take them from your own account's fee page; the crypto trading fee calculator works out the maker, taker and round-trip figures.
What is slippage in crypto on an AMM? Tolerance is a limit
On an automated market maker the words change: Uniswap's documentation (opens in a new tab) calls the effect of your own size price impact, uses slippage for changes while your transaction is pending, and makes tolerance a limit, past which the swap reverts.
| Question | Order book | AMM pool (Uniswap) |
|---|---|---|
| Effect of your own size | Part of slippage: walking levels | Price impact, from x * y = k |
| Change before execution | Also slippage, from latency | Slippage, while the transaction is pending |
| Your protection | Limit price, such as limit IOC | Tolerance, enforced through amountOutMinimum, plus a deadline |
| If it is breached | The rest does not fill | The whole transaction reverts |
def swap_out(reserve_in, reserve_out, amount_in, fee=0.003):
"""Constant product (x * y = k) with the fee taken from the input."""
net = amount_in * (1 - fee)
return reserve_out * net / (reserve_in + net)
QUOTE, BASE = 100_000.0, 1_000.0 # hypothetical pool: spot 100 QUOTE per BASE
for amount in (100, 1_000, 10_000):
out = swap_out(QUOTE, BASE, amount)
print(f"swap {amount} QUOTE: average {amount / out:.2f}, {(amount / out / 100 - 1) * 1e4:.0f} bps above spot")
quote = swap_out(QUOTE, BASE, 1_000)
minimum = quote * (1 - 0.005) # hypothetical 0.5% tolerance
print(f"quoted {quote:.4f} BASE, minimum accepted {minimum:.4f}")
for earlier in (100, 300): # another swap lands first
out = swap_out(QUOTE + earlier, BASE - swap_out(QUOTE, BASE, earlier), 1_000)
print(f"{earlier} QUOTE swap lands first: {out:.4f} BASE, {'executes' if out >= minimum else 'reverts'}")Output, for a hypothetical pool with a 0.3% fee (swap fees differ by pool):
swap 100 QUOTE: average 100.40, 40 bps above spot
swap 1000 QUOTE: average 101.30, 130 bps above spot
swap 10000 QUOTE: average 110.30, 1030 bps above spot
quoted 9.8716 BASE, minimum accepted 9.8222
100 QUOTE swap lands first: 9.8520 BASE, executes
300 QUOTE swap lands first: 9.8130 BASE, revertsA 0.5% tolerance did not make the first quote cost 0.5% more: it only set the worst acceptable result. Concentrated liquidity in Uniswap v3 and v4 applies the formula within each position's price range, so this constant-product math is a simplification there.
Slippage backtest: flat basis points or depth?
A flat assumption is quick and hides size, while a depth-based one needs order book history, so run several cost levels instead of trusting one.
from slip_final import ASKS, MID, slippage_bps, walk
GROSS = [45, -20, 30, 12, -35, 60, 8, -10] # hypothetical round trips in bps, not a result
FEE = 5 # hypothetical fee per fill in bps
print("flat assumption")
for slip in (0, 1, 5, 10):
net = [g - 2 * (FEE + slip) for g in GROSS]
print(f"{slip:>2} bps per fill: sum {sum(net):>5} bps, above zero {sum(n > 0 for n in net)} of {len(net)}")
print("depth-based, same book")
for qty in (1, 10, 20, 40):
average, _ = walk(ASKS, qty)
print(f"size {qty:>2}: {slippage_bps('buy', average, MID):6.2f} bps vs mid")Output, on hypothetical round trips that are not a strategy result:
flat assumption
0 bps per fill: sum 10 bps, above zero 4 of 8
1 bps per fill: sum -6 bps, above zero 3 of 8
5 bps per fill: sum -70 bps, above zero 3 of 8
10 bps per fill: sum -150 bps, above zero 2 of 8
depth-based, same book
size 1: 5.00 bps vs mid
size 10: 11.51 bps vs mid
size 20: 23.26 bps vs mid
size 40: 64.16 bps vs midOne extra basis point per fill turns the hypothetical sum negative. The depth table shows why one number cannot fit all sizes: the same book charges 5 bps at size 1 and 64 bps at size 40, so a backtest that scales up size at flat cost overstates itself. Historical depth is often unavailable or restricted by data terms, so flat costs are common; say which you used. Other assumptions that fake results are in backtesting pitfalls. A good result under every cost level is not evidence of future profit.
TradingView backtest slippage: the setting is in ticks
The slippage argument of strategy() is a whole number of ticks, per TradingView's Pine Script v6 User Manual read on 5 November 2026, so it is not a percentage and its cost in basis points depends on the symbol and price.
| Price | Tick | 5 ticks in price | 5 ticks in bps | Ticks needed for 5 bps |
|---|---|---|---|---|
| 80,000 | 0.01 | 0.05 | 0.006 | 4,000 |
| 100 | 0.01 | 0.05 | 5.000 | 5 |
| 0.25 | 0.0001 | 0.0005 | 20.000 | 1 (rounded) |
TradingView's Declaration statements page (opens in a new tab) (const int, default 0) and Strategy properties article (opens in a new tab) apply the ticks to market and stop orders; limit orders have a separate setting, Verify Price For Limit Orders. The Strategies page (opens in a new tab) says all order fills, in a market-order example, and warns that some fills can land outside the candle range. Because the value is fixed, the same setting drifts in basis points as price moves over a long test. Other properties are in the Strategy Tester guide.
Slippage crypto trading: measuring your real fills
Real slippage comes from your fills, not from a model, so record the reference price before sending and compare it with what the exchange reports.
On Binance Spot, as documented on 5 November 2026, a MARKET or LIMIT order response defaults to FULL, whose fills array lists each fill's price, quantity, commission and commission asset, and cummulativeQuoteQty / executedQty gives the average. Other venues name these fields differently. Signed orders need an API key, even on the Spot Testnet, so none were sent. For integration work in general, see algorithmic trading; naming Binance or Uniswap here does not mean Fincode integrates them or has built on them.
Frequently asked questions
What does slippage mean in crypto?
The gap between the price you expected and the average price you got, caused by your size against available depth, the spread, and prices moving before execution.
Is slippage tolerance the same as slippage?
No. On a swap, tolerance is a limit you set, and the transaction reverts past it. It is not what you pay, and this page recommends no value.
What slippage should I use in a backtest?
There is no single right number. Run several cost levels, use depth where you have it, and report the assumption. No backtest result guarantees future results.
What unit is TradingView's slippage setting?
Ticks, as a fixed whole number, per TradingView's Pine Script v6 User Manual and Help Center, read 5 November 2026. Convert it to basis points for your symbol and price.
Sources
- Binance Academy glossary: Slippage (opens in a new tab)
- Binance Spot API documentation: Market data endpoints (order book, weights) (opens in a new tab)
- Binance Spot API documentation: Trade endpoints (newOrderRespType defaults) (opens in a new tab)
- Uniswap documentation: Swaps (price impact, slippage, amountOutMinimum) (opens in a new tab)
- Uniswap documentation: How Uniswap works (constant product formula) (opens in a new tab)
- Binance Spot API docs repository on GitHub: rest-api.md (New order, FULL response with fills) (opens in a new tab)
- TradingView: Pine Script v6 User Manual, Declaration statements (strategy() slippage) (opens in a new tab)
- TradingView Help Center: Strategy properties (slippage, verify price for limit orders) (opens in a new tab)
- TradingView: Pine Script User Manual, Strategies (slippage and unfilled limits) (opens in a new tab)
- Capital Markets Law No. 6362, consolidated text, Article 99/A (Turkish) (opens in a new tab)
This guide is general information about software and markets, not investment, legal or tax advice. Automated trading can lose money, past or backtested performance does not guarantee future results, and the rules that apply depend on your jurisdiction and your exchange's terms. Sources, checks and corrections: see the editorial policy.