Pine Script trailing stop: 2 ways to code one in v6
A trailing stop follows price as a trade moves your way, and stays put when it doesn't. Pine Script gives you a built-in one, and you can build your own. Here are both, and when each fits.
What a trailing stop does
A normal Stop loss sits at one price. A Trailing stop moves.
In a buy trade, it follows price up at a set distance. When price falls back, the stop stays where it is. If price falls far enough, the stop is hit and the trade closes.
The idea: keep some of a move without guessing where it ends. The cost: a normal pullback can close the trade early. There's no free lunch here.
This page uses strategy scripts, which place pretend trades on past candles. If that's new, read Pine Script strategy backtest first.
Way 1: the built-in trail
strategy.exit() has a trailing stop built in. You give it 2 distances, in ticks (a tick is the smallest price step the symbol can move):
//@version=6
strategy("Built-in trail test", overlay=true, initial_capital=10000, commission_type=strategy.commission.percent, commission_value=0.05, slippage=2)
fast = ta.ema(close, 20)
slow = ta.ema(close, 50)
crossUp = ta.crossover(fast, slow)
if crossUp and strategy.position_size == 0
strategy.entry("Long", strategy.long)
strategy.exit("Exit", from_entry="Long", loss=300, trail_points=300, trail_offset=150)
Line by line:
- Line 1 says this is Pine Script version 6.
- Line 2 makes it a strategy with a 10,000 test account, a small cost per trade and 2 ticks of Slippage.
- Lines 3 and 4 work out a fast and a slow EMA (averages that lean toward recent candles).
- Line 5 is true when the fast one crosses above the slow one.
- Lines 6 and 7 buy on that cross, if we're not already in a trade.
- Line 8 sets the exit. loss=300 is a first stop, 300 ticks under the entry. trail_points=300 says "start trailing once the trade is 300 ticks in profit". trail_offset=150 says "then follow price 150 ticks behind the best price reached".
The catch: ticks mean very different things on different charts. 300 ticks on a stock with a 0.01 step is 3.00. On a futures contract it could be far more. Check the tick size before picking numbers. Our futures tick value calculator helps there.
Way 2: an ATR trail you build yourself
Fixed ticks ignore how much a market is moving. A trail based on the ATR (the average size of recent candles) adjusts by itself. Wide when candles are big, tight when they're small.
//@version=6
strategy("ATR trail test", overlay=true, initial_capital=10000, commission_type=strategy.commission.percent, commission_value=0.05, slippage=2)
atrLen = input.int(14, "ATR length", minval=1)
mult = input.float(3.0, "ATR multiple", minval=0.5, step=0.5)
fast = ta.ema(close, 20)
slow = ta.ema(close, 50)
atr = ta.atr(atrLen)
crossUp = ta.crossover(fast, slow)
var float trail = na
if crossUp and strategy.position_size == 0
strategy.entry("Long", strategy.long)
trail := close - mult * atr
if strategy.position_size > 0
trail := math.max(trail, close - mult * atr)
strategy.exit("Trail exit", from_entry="Long", stop=trail)
plot(strategy.position_size > 0 ? trail : na, "Trail", color=color.red, style=plot.style_linebr)
Every line, in plain words
- Lines 3 and 4 make the ATR length and the multiple settings. See Pine Script inputs.
- Lines 5 to 8 work out the averages, the ATR and the cross.
- Line 9 makes a box called trail that keeps its value from candle to candle. var does that.
- Lines 10 and 11 buy on a cross when flat.
- Line 12 sets the first stop: the close minus 3 ATRs.
- Line 13 says "while we're in a trade…"
- Line 14 is the heart of it. math.max picks the bigger of 2 numbers: the old stop, or a new one 3 ATRs under this close. So the stop can only go up, never down.
- Line 15 tells the strategy to exit at the trail price.
- Line 16 draws the trail in red while a trade is open. plot.style_linebr leaves gaps when there's no trade.
Why line 14 matters: without math.max, the stop would drop whenever the ATR grows. A trailing stop that moves away from price isn't trailing. It's widening your risk.
A worked example in units of risk
Say the close is 100 and 3 ATRs is 6. The first stop is 94. Risk = 6 points = 1 unit.
- Price climbs to a close of 112. New stop: 112 − 6 = 106. That's above the entry, so the worst case is now about +1 unit.
- Price dips to 109. 109 − 6 = 103, which is lower than 106. math.max keeps 106.
- Price falls to 106. The stop is hit: about +1 unit, before costs.
Had price fallen straight to 94 after entry, the result would be −1 unit. Losses happen; the stop just keeps each one known in advance. A math example, not a promise.
Which one to use?
| Built-in trail | ATR trail | |
|---|---|---|
| Distance in | Ticks | ATRs |
| Adjusts to how much price moves | No | Yes |
| Starts trailing | After a set profit | Right away |
| Lines of code | 1 | About 5 |
| Easy to see on the chart | No | Yes, with plot() |
A simple rule: use the ATR trail when you'll test it on many markets. One tick number rarely fits all of them.
The tester's blind spot
The Strategy Tester only knows each candle's open, high, low and close. It doesn't know which came first, the high or the low. So on a big candle that touches both your stop and a new high, it has to assume an order. Real price may have moved the other way round.
Also, the ATR trail above updates on the close. On a live chart, a broker's real trailing stop updates as price moves inside the candle. The two won't match exactly.
Results are hypothetical. Treat them as a first look at an idea, then replay it by hand with bar replay.
A trailing stop doesn't replace a first stop. Every trade still needs a stop from the chart and a size from the math, before entry. See how to set a stop loss and Pine Script position size.
Try it today
- Paste the ATR trail into the Pine Editor on a computer. Save and add it to a daily chart.
- Find the red trail line. Watch it step up and flatten.
- Change the multiple from 3 to 1.5. Count how many trades close on small dips now.
- Try the same setting on 3 different charts. Write down what you see in a trading journal.
Pick the multiple for a reason. "3 ATRs, so normal candles don't knock me out" is a reason. "2.7 because it tested best" is overfitting.
Learning from a real script
Our course includes the full source code of the StructureX chart tool. You could build your own exit tests on top of it. It's source code, not a ready-made trading bot.
Common mistakes
- Letting the trail move down. Always use math.max for buys (math.min for sells).
- Picking tick numbers without checking the tick size. 100 ticks can be tiny or huge.
- Trailing too tight. Normal pullbacks close the trade.
- No first stop. The built-in trail only starts after profit; add loss= so the trade is protected from the start.
- Mixing ticks and prices. stop= takes a price; loss= and trail_offset= take ticks.
Questions
How do I add a trailing stop in Pine Script?
Use strategy.exit() with trail_points and trail_offset in ticks, or work out your own trail price and pass it to stop=. Keep it moving one way with math.max.
What is trail_offset in Pine Script?
The distance, in ticks, that the trailing stop follows behind the best price reached once trailing has started.
What is a good ATR multiple for a trailing stop?
There's no single right number. Many traders start between 2 and 3 ATRs, then test it on past charts. Wider means fewer early exits but bigger losses when hit.
Does a trailing stop work in the Strategy Tester like it does live?
Not exactly. The tester only sees each candle's open, high, low and close, so it assumes an order inside each candle. Live fills and slippage differ too.
Want the next step? We'll walk you through it.
Four free lessons by email, one every few days — each with a 10-minute exercise on a real chart.
Send Me the Free Lessons 4 short emails · No spam · Unsubscribe anytimeOr see the whole method, step by step:
See What’s Inside the Course Try everything free first. Decide when you're ready. · Open the free chart tool (works in the TradingView phone app)One chart idea a day, in plain English. Follow along: