Trailing Stop Methods

Lock in profits with ATR-based, percentage-based, and Chandelier exit trailing stops.

A fixed take-profit target is simple but has a fundamental flaw: you exit a winning trade at a predetermined level, regardless of whether the trend has any more to give. In a strong trend, this means repeatedly leaving large profits on the table. In a weak trend, it may capture the profit just before a reversal that would have taken it back anyway.

Trailing stops solve this by replacing the fixed target with a dynamic one that follows price. As the trade moves in your favour, the stop advances with it — locking in progressively more profit. But the stop never moves back against you. The exit happens when price reverses enough to touch the trail — the market's own signal that the move has exhausted.

The critical trade-off in every trailing stop is the same: too tight and you get stopped out on normal pullbacks; too loose and you give back too much profit before exiting. The right calibration depends on the method, the instrument, and the timeframe.

The three methods compared

ATR-based trailing stop

The stop is placed a multiple of ATR below the current close (for longs). Because ATR reflects actual recent volatility, the stop distance is always proportional to how much the instrument is moving. In quiet markets the stop sits closer; in volatile markets it breathes wider.

This is the most adaptive method. It works well across different instruments and timeframes without recalibration because ATR scales automatically with the instrument's behaviour.

When to use it: general-purpose trailing exit, especially when the instrument's volatility changes meaningfully over time or across different market conditions.

Typical settings: 2.0–3.0× ATR. A multiplier below 2.0 tends to generate excessive stop-outs on normal pullbacks; above 4.0 tends to give back too much profit.

Percentage-based trailing stop

The stop is placed a fixed percentage below the current close. Simple and easy to understand, but the percentage is fixed regardless of whether the market is quiet or explosive. A 2% trail might be reasonable in normal conditions but will stop out on a single average bar during a volatile period.

When to use it: assets where percentage moves are more meaningful than point moves (e.g. stocks, crypto where price levels vary widely), or when simplicity is more important than precision.

Typical settings: 1.5–3.0% for daily charts. Intraday strategies typically use tighter percentages (0.3–1.0%).

Chandelier exit

The Chandelier exit is different from the other two: rather than trailing from the current close, it trails from the highest high since the trade was entered (for longs). The stop is placed a multiple of ATR below that highest high.

This has an important behavioural property: the stop doesn't move lower just because the current close moved lower. It only adjusts when price makes a new high. This makes it more resistant to noise while still tracking the peak of the trade's progress.

When to use it: trending instruments where price makes clean impulsive moves followed by pullbacks. The Chandelier is especially suited to instruments that trend persistently rather than oscillating.

Named after: the image of a chandelier hanging from the ceiling — the stop hangs down from the high point of the trade.

Choosing the right method

There is no universally best trailing stop — the right choice depends on your instrument and strategy context:

| Method | Best when | Weakness | |---|---|---| | ATR | Volatility varies over time | More complex than percentage | | Percentage | Simple rule needed, price levels vary | Fixed regardless of volatility | | Chandelier | Strong, sustained trends | Can give back significant profit after the high |

A practical approach is to backtest all three on your specific instrument and timeframe, then compare average winning trade size and the ratio of trades stopped out on noise versus legitimate reversals.

Why the stop never moves backward

A key implementation detail in all trailing stops: once the stop has advanced to a higher level, it must never move lower. This is enforced in the code with `math.max(nz(trailStop), newStop)` for longs — the stop can only be updated to a higher level, never a lower one.

Without this constraint, the stop would simply follow every dip, providing no protection and no profit-locking behaviour at all.

The psychology of trailing stops

There is a behavioural advantage to trailing stops that is worth understanding explicitly. Fixed targets remove you from the trade at a predetermined level, which often feels too early (during a strong trend) or too late (if the target is never hit and the trade reverses). This creates second-guessing.

Trailing stops reframe the exit decision: you stay in the trade until the market tells you the move is over, by reversing enough to touch your trail. The exit is objective and rules-based. This removes the temptation to exit early or to override the system — the market decides when you exit, not an arbitrary price level you chose before the trade.

//@version=6
strategy("Trailing Stop Methods", overlay=true)

method = input.string("ATR", "Trailing Method", options=["ATR", "Percent", "Chandelier"])
atrLen = input.int(14, "ATR Length")
atrMult = input.float(3.0, "ATR Multiplier")
pctTrail = input.float(2.0, "Percent Trail (%)")

// ATR trailing stop
atrValue = ta.atr(atrLen)

var float trailStop = na
var int tradeDir = 0

if strategy.position_size > 0
    tradeDir := 1
    newStop = switch method
        "ATR" => close - atrValue * atrMult
        "Percent" => close * (1 - pctTrail / 100)
        "Chandelier" => ta.highest(high, atrLen) - atrValue * atrMult
    trailStop := math.max(nz(trailStop), newStop)
else if strategy.position_size < 0
    tradeDir := -1
    newStop = switch method
        "ATR" => close + atrValue * atrMult
        "Percent" => close * (1 + pctTrail / 100)
        "Chandelier" => ta.lowest(low, atrLen) + atrValue * atrMult
    trailStop := math.min(nz(trailStop, 999999), newStop)
else
    trailStop := na
    tradeDir := 0

// Simple entry
if ta.crossover(ta.ema(close, 9), ta.ema(close, 21))
    strategy.entry("Long", strategy.long)
    trailStop := close - atrValue * atrMult

// Trailing stop exit
if strategy.position_size > 0 and close < trailStop
    strategy.close("Long")

plot(trailStop, "Trail Stop", color=tradeDir == 1 ? color.green : color.red, style=plot.style_stepline)