← Back to Algorithmic Glossary

Brokerage Slippage in Python

The difference between the expected execution price of a trade and the actual price at which it is filled, eroding real-world strategy returns.

Definition

Brokerage Slippage is the aggregate of all transaction costs that separate a theoretical backtest from live trading reality. It encompasses three distinct components: the bid-ask spread (the cost of immediacy), market impact (the price movement caused by your own order in the order book), and commission fees. Slippage is not constant — it scales with order size relative to market liquidity, is dramatically higher in illiquid assets or at market open/close, and spikes during volatility events. Strategies that appear highly profitable in frictionless backtests frequently become breakeven or loss-making once realistic slippage is applied.

Quantitative Formula

Slippage=PfillPsignalPsignal×sideSlippage = \frac{P_{fill} - P_{signal}}{P_{signal}} \times \text{side}

Where PfillP_{fill} is the actual execution price, PsignalP_{signal} is the theoretical price at which the signal was generated (typically prior close or VWAP), and side\text{side} is +1+1 for long entries (higher fill price is worse) and 1-1 for short entries. Total slippage cost per trade is expressed in basis points (bps): Slippagebps=PfillPsignalPsignal×10000Slippage_{bps} = \frac{|P_{fill} - P_{signal}|}{P_{signal}} \times 10000.

Why It Matters in Backtesting

A high-frequency mean-reversion strategy generating 0.05% per trade with a theoretical Sharpe of 3.2 may generate zero alpha after 0.03% per-side slippage and 0.01% commission — costs that are perfectly normal in institutional execution. In backtesting, slippage must be modeled as a function of liquidity (ADV — Average Daily Volume), with larger orders receiving exponentially worse fills. Any backtest that uses exact close prices for execution without applying at minimum 5–15 basis points of round-trip slippage is producing fiction rather than analysis.

Python Implementation

import numpy as np
    import pandas as pd

    def apply_realistic_slippage(signals: pd.Series, prices: pd.DataFrame,
                                  commission_bps: float = 5.0,
                                  spread_bps: float = 3.0,
                                  market_impact_factor: float = 0.1) -> dict:
        """
        Applies a realistic 3-component slippage model to a signal series.
        signals: +1 (long), -1 (short), 0 (flat) for each period.
        prices: DataFrame with 'Close', 'Volume', 'ADV_20' (20-day avg daily volume).
        commission_bps: Round-trip commission in basis points.
        spread_bps: Half-spread cost per side in basis points.
        market_impact_factor: Scales market impact with order size vs ADV.
        """
        trades = signals.diff().fillna(0).abs()  # 1 where position changes
        # Market impact: larger trades relative to ADV create more impact
        order_size_ratio = 1.0  # Assume fixed 1% of ADV; adjust per strategy
        market_impact_bps = market_impact_factor * order_size_ratio * np.sqrt(
            prices.get("ADV_20", pd.Series(1, index=prices.index)) /
            prices.get("Volume", pd.Series(1, index=prices.index))
        ) * 10000
        total_slippage_bps = trades * (commission_bps + spread_bps + market_impact_bps)
        slippage_as_return = -total_slippage_bps / 10000
        return {
            "slippage_series_bps": total_slippage_bps,
            "slippage_as_return": slippage_as_return,
            "total_cost_bps": total_slippage_bps.sum(),
            "avg_cost_per_trade_bps": total_slippage_bps[trades > 0].mean(),
            "total_trades": int(trades.sum()),
            "annualized_drag": slippage_as_return.sum() * (252 / len(signals))
        }

Test this in a live environment

Stop running Jupyter notebooks locally. Paste this Brokerage Slippage code directly into Valetha's Strategy Lab and run a full historical backtest in seconds.

Open the Python Strategy Lab

Ready to find your edge ?

Start for Free