Pine Script Slippage & Spread Guard
Adds per-contract commission and tick slippage to the strategy declaration, plus a wide-bar skip, so a backtest matches live prop-firm fills.
Pine Script
//@version=6
// Commission and slippage must be literal values in the strategy() call —
// Pine does not allow inputs there. Slippage is in ticks; commission
// here is a flat $ per contract, per side.
strategy("Target Filled - Slippage Guard Example", overlay=true, calc_on_every_tick=false,
commission_type=strategy.commission.cash_per_contract, commission_value=0.62, slippage=1)
// --- Inputs ---------------------------------------------------
maxBarTicks = input.int(40, "Max Bar Range (ticks)", minval=1,
tooltip="Skip entries on bars wider than this — a wide bar usually means a bad fill.")
// --- Wide-bar skip ---------------------------------------------------
barTicks = (high - low) / syminfo.mintick
tightBar = barTicks <= maxBarTicks
// --- Sample signal — replace with your own entry logic ---------
fastMA = ta.ema(close, 9)
slowMA = ta.ema(close, 21)
canLong = ta.crossover(fastMA, slowMA) and tightBar
canShort = ta.crossunder(fastMA, slowMA) and tightBar
if canLong
strategy.entry("Long", strategy.long)
strategy.exit("Long Exit", "Long", profit=20, loss=10)
if canShort
strategy.entry("Short", strategy.short)
strategy.exit("Short Exit", "Short", profit=20, loss=10)
// Visual
bgcolor(not tightBar ? color.new(color.purple, 90) : na, title="Wide Bar Skipped") Settings
| Input | Default | Purpose |
|---|---|---|
| commission_value | $0.62 | Per-contract, per-side cost, set in the declaration. 0.62 is a typical micro all-in figure. |
| slippage | 1 | Ticks lost per fill, set in the declaration. |
| maxBarTicks | 40 | Skip entries on bars wider than this. |
How to use
- Copy the
strategy()declaration parameters into your own script — commission and slippage have to be literals there, never inputs. - Set
commission_valueto your broker's all-in round-turn cost, divided by two. - Swap the EMA-crossover placeholder for your own entry conditions.
- Re-run the backtest once costs are on — if the edge disappears, it was never really there.
Frequently Asked Questions
How do I add slippage to a Pine Script backtest?
Set the
slippage parameter inside the strategy() declaration — it is measured in ticks and applies against you on every fill, entry or exit. Add commission_type=strategy.commission.cash_per_contract with a per-side dollar figure as commission_value. Both need to be literal values in the declaration; Pine will not accept inputs there.Why does my backtest differ from live fills?
A zero-cost backtest assumes every trade fills at the exact signal-bar close. Live, you pay the spread, a commission, and occasional slippage on fast bars. One tick of slippage plus a realistic commission is enough to flip a marginal scalping system from profitable to losing — which is exactly why a strategy should be tested with these costs turned on before it ever touches an evaluation.