How to exit trades with a stop-loss order in Pine Script?
How to exit trades with a stop-loss order in Pine Script?
Section titled “How to exit trades with a stop-loss order in Pine Script?”TL;DR
Usestrategy.exit(id, from_entry, loss|stop)right afterstrategy.entry()so TradingView queues a protective stop-loss the instant the position fills.
At a Glance
Section titled “At a Glance”| Difficulty | Intermediate |
| Time to implement | 15-20 min |
| Category | Order Management |
Quick Actions
Section titled “Quick Actions”Quick Start
Section titled “Quick Start”//@version=5strategy("Stop-loss demo", overlay=true)
if ta.crossover(close, ta.highest(high, 20)) strategy.entry("Long", strategy.long) strategy.exit("Long SL", from_entry="Long", loss=150)Why It Matters
Section titled “Why It Matters”Stop-loss exits are the safety net for every automated strategy. Pairing entries with immediate stops locks in risk per-trade, keeps performance metrics honest, and mirrors how real brokers manage OCO orders. Without them your backtests understate drawdowns and invite outsized losses when the market gaps.
What You’ll Learn
Section titled “What You’ll Learn”- Choose between tick-distance (
loss) and absolute-price (stop) exits. - Attach stops to specific entries so multi-leg systems stay organised.
- Update or cancel stops safely when market structure changes.
- Backtest risk reliably by reflecting real-world order timing.
Quick Reference
Section titled “Quick Reference”| Call | Purpose |
|---|---|
strategy.exit(id, from_entry, loss, stop) | Generates a protective exit for a named entry using ticks or explicit price. |
strategy.entry(id, direction) | Opens positions to which your stop will attach. |
strategy.position_size | Confirms whether a position exists before modifying exits. |
ta.crossover(series1, series2) | Common trigger for long entries used in the examples. |
ta.atr(length) | Produces volatility-based stop distances. |
Implementation Blueprint
Section titled “Implementation Blueprint”-
Decide how to measure risk
Uselossfor tick offsets orstopfor absolute prices. You can derive either from volatility or structure.lossTicks = input.int(150, "Tick stop distance", minval=1)stopPercent = input.float(2.0, "Percent stop", step=0.1)atrLength = input.int(14, "ATR length")atrStops = ta.atr(atrLength) * 1.5 -
Submit the stop alongside the entry
Immediately afterstrategy.entry()callstrategy.exit()so the stop queues when the entry fills.if ta.crossover(close, ta.highest(high, 20))strategy.entry("Long", strategy.long)strategy.exit("Long SL", "Long", loss=lossTicks)if ta.crossunder(close, ta.lowest(low, 20))strategy.entry("Short", strategy.short)strategy.exit("Short SL", "Short", loss=lossTicks) -
Update or replace stops when conditions change
Cancelling or reissuing exits lets you trail stops or switch from tick-based to price-based logic mid-trade.if strategy.position_size > 0newStopPrice = close - atrStopsstrategy.exit("Long SL", from_entry="Long", stop=newStopPrice)
Example Playbook
Section titled “Example Playbook”//@version=5strategy("Breakout with protective stops", overlay=true, initial_capital=50_000, default_qty_type=strategy.percent_of_equity, default_qty_value=5)
lengthHigh = input.int(40, "Breakout length", minval=2)lengthLow = input.int(40, "Breakdown length", minval=2)lossTicks = input.int(200, "Initial tick stop", minval=1)trailATRMult = input.float(1.8, "ATR trail multiplier", step=0.1)atrLength = input.int(14, "ATR length", minval=1)
highestHigh = ta.highest(high, lengthHigh)lowestLow = ta.lowest(low, lengthLow)atrValue = ta.atr(atrLength)
enterLong = ta.crossover(high, highestHigh)enterShort = ta.crossunder(low, lowestLow)
if enterLong strategy.entry("Long", strategy.long) strategy.exit("Long SL", from_entry="Long", loss=lossTicks)
if enterShort strategy.entry("Short", strategy.short) strategy.exit("Short SL", from_entry="Short", loss=lossTicks)
// Trail stops using ATR once in the tradeif strategy.position_size > 0 longStop = close - atrValue * trailATRMult strategy.exit("Long SL", from_entry="Long", stop=longStop)
if strategy.position_size < 0 shortStop = close + atrValue * trailATRMult strategy.exit("Short SL", from_entry="Short", stop=shortStop)
plot(highestHigh, "Breakout high", color=color.new(color.green, 60))plot(lowestLow, "Breakout low", color=color.new(color.red, 60))- Entries and stops trigger together so the trade is never unprotected.
- ATR-based updates replace the original tick stop, mirroring a broker-side trailing stop.
- Named exits ("Long SL", "Short SL") attach to matching entries, preventing cross-contamination between long and short risk.
Pro Tips & Pitfalls
Section titled “Pro Tips & Pitfalls”- Use unique
idvalues per exit so you can update or cancel them later without confusion. - When pyramiding, pass
qty_percentorqtyinstrategy.exit()if each leg needs different stop sizing. strategy.cancel(id)removes a pending exit. Always reissue a new stop on the same bar to avoid gaps.- Combine stop-loss orders with alerts so live trading and webhook integrations stay in sync.
Troubleshooting & FAQ
Section titled “Troubleshooting & FAQ”I see “Cannot set loss to negative value” errors
Section titled “I see “Cannot set loss to negative value” errors”Double-check calculations that feed loss or stop. Clamp values or guard with math.max(value, minAllowed) before passing them to strategy.exit().
My stop fires on the same bar as the entry
Section titled “My stop fires on the same bar as the entry”strategy.exit() uses stop orders. If price gaps through the stop level intra-bar, the order fills immediately. Consider strategy.order() with stop and limit for staged exits if you need more control.
Do I need to cancel stops manually?
Section titled “Do I need to cancel stops manually?”Not when you provide from_entry. TradingView automatically removes the exit when that entry closes. Only call strategy.cancel() if you want to replace or trail the stop mid-position.
Key Takeaways
Section titled “Key Takeaways”- Call
strategy.exit()on the same bar as the entry so every trade is protected. - Choose between tick (
loss) and price (stop) inputs depending on how you size risk. - Update or cancel stops intentionally—TradingView cleans up exits tied to closed entries for you.
- Consistent stop placement gives you realistic drawdowns and better strategy confidence.
Keep Going
Section titled “Keep Going”- Open AI Editor to apply the pattern with guided assistance
- Browse Strategy Examples for ready-to-run templates
- Connect to Live Trading when you are ready to automate
Adapted from tradingcode.net, optimised for Algo Trade Analytics users.