Trading Strategy

ATR Trailing Stop Strategy

A volatility-based trend following strategy that uses Average True Range (ATR) to dynamically adjust stop loss levels as price moves in your favor.

Dynamic Volatility-Based Stops

The ATR Trailing Stop adapts to current market volatility, automatically tightening stops in calm markets and widening them during volatile periods. Combined with a 200 EMA trend filter, this strategy captures strong trends while protecting profits with dynamic trailing stops.

Volatility Type
4h Chart Timeframe
Intermediate Complexity
Trending Best Market

Signal Logic

Long (Buy)

Price crosses above the ATR trailing stop line while above the 200 EMA trend filter.

Short (Sell)

Price crosses below the ATR trailing stop line while below the 200 EMA trend filter.

Implementation

//@version=6
strategy("ATR Trailing Stop Strategy", overlay=true, initial_capital=1000000, default_qty_type=strategy.percent_of_equity, default_qty_value=100)

// ==========================================
// 🔹 INPUTS
// ==========================================
// Group: ATR Settings
grp_atr = "ATR Settings"
atr_len   = input.int(14, "ATR Length", minval=1, group=grp_atr)
mult       = input.float(3.0, "ATR Multiplier", step=0.1, group=grp_atr)

// Group: Trend Filter
grp_trend = "Trend Filter"
use_trend = input.bool(true, "Use Trend Filter (EMA 200)", group=grp_trend)
ema_len   = input.int(200, "Trend EMA Length", minval=1, group=grp_trend)

// Group: Risk Management
grp_risk  = "Risk Management"
tp_mult   = input.float(2.0, "Take Profit (ATR Multiplier)", step=0.1, group=grp_risk)

// ==========================================
// 🔹 CALCULATIONS
// ==========================================
// ATR calculation
atr_val = ta.atr(atr_len)

// Trend EMA
ema_val = ta.ema(close, ema_len)

// Calculate trailing stop levels
long_stop = close - (atr_val * mult)
short_stop = close + (atr_val * mult)

// Initialize trailing stop variables
var float trailing_stop = na

// Trend Conditions
is_uptrend = use_trend ? close > ema_val : true
is_downtrend = use_trend ? close < ema_val : true

// ==========================================
// 🔹 STRATEGY LOGIC
// ==========================================
// Initialize on first bar
if na(trailing_stop)
    if is_uptrend
        trailing_stop := long_stop
    else
        trailing_stop := short_stop

// Update trailing stop on each bar
if strategy.position_size > 0
    // Long position - trail stop higher
    new_stop = long_stop
    trailing_stop := math.max(trailing_stop, new_stop)
else if strategy.position_size < 0
    // Short position - trail stop lower
    new_stop = short_stop
    trailing_stop := math.min(trailing_stop, new_stop)
else
    // No position - reset based on trend
    if is_uptrend
        trailing_stop := long_stop
    else
        trailing_stop := short_stop

// Entry signals
long_signal = is_uptrend and (ta.crossover(close, trailing_stop))
short_signal = is_downtrend and (ta.crossunder(close, trailing_stop))

// ==========================================
// 🔹 EXECUTION & RISK MANAGEMENT
// ==========================================

if long_signal
    strategy.entry("Long", strategy.long, comment="L | ATR Trail")

if short_signal
    strategy.entry("Short", strategy.short, comment="S | ATR Trail")

// Exit on trailing stop or take profit
if strategy.position_size > 0
    // Long position exits
    strategy.exit("Exit Long", "Long", stop=trailing_stop, limit=strategy.position_avg_price + (atr_val * tp_mult), comment_loss="TS", comment_profit="TP")

if strategy.position_size < 0
    // Short position exits
    strategy.exit("Exit Short", "Short", stop=trailing_stop, limit=strategy.position_avg_price - (atr_val * tp_mult), comment_loss="TS", comment_profit="TP")

// ==========================================
// 🔹 VISUALS
// ==========================================
// Plot EMA
plot(use_trend ? ema_val : na, "Trend EMA", color=color.new(color.orange, 0), linewidth=2)

// Plot trailing stop line
plot(trailing_stop, "Trailing Stop", color=color.new(color.blue, 0), linewidth=2)

// Plot Signals
plotshape(long_signal, title="Long Signal", location=location.belowbar, color=color.green, style=shape.labelup, text="BUY", textcolor=color.white)
plotshape(short_signal, title="Short Signal", location=location.abovebar, color=color.red, style=shape.labeldown, text="SELL", textcolor=color.white)

// Background color for trend context
bgcolor(is_uptrend ? color.new(color.green, 95) : color.new(color.red, 95))