ATR Indicator Explained — How to Use Average True Range in Trading

ATR Indicator Explained — How to Use Average True Range in Trading

By HorizonAI Team

The ATR (Average True Range) is one of the most versatile indicators in trading. Unlike trend indicators that tell you direction, ATR measures volatility—how much price typically moves.

This makes it invaluable for setting stop losses, calculating position sizes, and filtering trades.

What is ATR (Average True Range)?

ATR measures the average range of price movement over a specified period, accounting for gaps. It was developed by J. Welles Wilder Jr. and introduced in his 1978 book "New Concepts in Technical Trading Systems."

Key characteristics:

  • Measures volatility, not direction
  • Always positive (no negative values)
  • Expressed in price units (not percentage)
  • Higher ATR = more volatility
  • Lower ATR = less volatility

ATR doesn't tell you which way price will move—only how much it typically moves. Use it alongside trend indicators for complete analysis.

How ATR is Calculated

ATR uses the concept of "True Range" which accounts for gaps between sessions:

True Range (TR)

True Range is the greatest of:

  1. Current High minus Current Low
  2. Absolute value of Current High minus Previous Close
  3. Absolute value of Current Low minus Previous Close
TR = max(High - Low, |High - Previous Close|, |Low - Previous Close|)

Average True Range

ATR is simply the moving average of True Range over N periods (typically 14):

//@version=6
indicator("ATR Calculation", overlay=false)

length = input.int(14, "ATR Length")

// ATR (using built-in for accuracy)
atrValue = ta.atr(length)

plot(atrValue, "ATR", color=color.blue)

Reading ATR Values

ATR is expressed in the same units as price:

  • If EUR/USD ATR(14) = 0.0080, price typically moves 80 pips per period
  • If AAPL ATR(14) = 3.50, price typically moves $3.50 per period
  • If BTC/USD ATR(14) = 1500, price typically moves $1,500 per period

High ATR (Increasing Volatility)

  • Larger price swings
  • Wider stops required
  • Bigger potential profits and losses
  • Often seen during trends or news events

Low ATR (Decreasing Volatility)

  • Smaller price swings
  • Tighter stops possible
  • Smaller moves, more choppy action
  • Often seen during consolidation

Pro tip: ATR naturally adjusts across different instruments and timeframes. A 1-minute ATR on forex will be tiny, while a daily ATR on crypto will be large—but both measure "normal" movement for that context.

Using ATR for Stop Losses

ATR-based stops adapt to current market conditions. This is the most common and powerful use of ATR.

Fixed ATR Multiple Stop

Set your stop loss at a multiple of ATR from entry:

//@version=6
strategy("ATR Stop Loss", overlay=true)

atrLength = input.int(14, "ATR Length")
atrMultiplier = input.float(2.0, "ATR Multiplier for Stop")

atr = ta.atr(atrLength)

// Example long entry
longCondition = ta.crossover(ta.ema(close, 9), ta.ema(close, 21))

if longCondition
    stopLoss = close - (atr * atrMultiplier)
    strategy.entry("Long", strategy.long)
    strategy.exit("Exit", "Long", stop=stopLoss)

// Visualize stop distance
plot(close - atr * atrMultiplier, "Stop Level", color=color.red, style=plot.style_stepline)

Common ATR Multiples

  • 1.0 ATR (Tight stop): Scalping, precise entries
  • 1.5 ATR (Standard): Day trading
  • 2.0 ATR (Moderate): Swing trading
  • 3.0 ATR (Wide): Position trading, volatile markets

ATR Trailing Stop

Let winners run while protecting profits:

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

atrLength = input.int(14, "ATR Length")
atrMultiplier = input.float(2.5, "ATR Multiplier")

atr = ta.atr(atrLength)

// Chandelier Exit style trailing stop
longStop = ta.highest(high, 22) - atr * atrMultiplier

// Track position
var int position = 0
var float trailStop = na

if ta.crossover(close, ta.ema(close, 50)) and position <= 0
    position := 1
    trailStop := close - atr * atrMultiplier
    strategy.entry("Long", strategy.long)

if position == 1
    trailStop := math.max(trailStop, close - atr * atrMultiplier)
    if close < trailStop
        position := 0
        strategy.close("Long")

plot(position == 1 ? trailStop : na, "Trail Stop", color=color.red, style=plot.style_linebr, linewidth=2)

Warning: Don't use the same ATR multiple for all markets. Volatile assets like crypto may need 2-3x ATR stops while stable forex pairs might work with 1.5x ATR.

Using ATR for Position Sizing

ATR enables volatility-adjusted position sizing—risk the same dollar amount regardless of an asset's volatility.

The Formula

Position Size = Risk Amount / (ATR × Multiplier)

Example:

  • Account: $10,000
  • Risk per trade: 1% = $100
  • Stock price: $50
  • ATR(14): $2.00
  • Stop distance: 2 × ATR = $4.00
Shares = $100 / $4.00 = 25 shares
Position value = 25 × $50 = $1,250

Why ATR Position Sizing Works

Without ATR adjustment:

  • A $100 stock moving 5% risks $5/share
  • A $10 stock moving 5% risks $0.50/share
  • Same percentage, different dollar risk

With ATR adjustment:

  • Both positions risk the same dollar amount
  • Volatile stocks = smaller position
  • Stable stocks = larger position
  • Consistent risk across your portfolio

Using ATR for Take Profit

Set take profit targets based on realistic price movement:

//@version=6
strategy("ATR Take Profit", overlay=true)

atrLength = input.int(14, "ATR Length")
stopMultiplier = input.float(1.5, "Stop ATR Multiple")
tpMultiplier = input.float(3.0, "TP ATR Multiple")

atr = ta.atr(atrLength)

longCondition = ta.crossover(ta.ema(close, 9), ta.ema(close, 21))

if longCondition
    entryPrice = close
    stopLoss = entryPrice - (atr * stopMultiplier)
    takeProfit = entryPrice + (atr * tpMultiplier)
    
    strategy.entry("Long", strategy.long)
    strategy.exit("Exit", "Long", stop=stopLoss, limit=takeProfit)

ATR-Based Risk/Reward

  • 1.5 ATR stop / 3.0 ATR target: 1:2 R:R, requires 33% win rate
  • 2.0 ATR stop / 4.0 ATR target: 1:2 R:R, requires 33% win rate
  • 1.5 ATR stop / 4.5 ATR target: 1:3 R:R, requires 25% win rate
  • 2.0 ATR stop / 6.0 ATR target: 1:3 R:R, requires 25% win rate

ATR as a Volatility Filter

Use ATR to filter trades based on market conditions:

High Volatility Filter

Only trade when volatility is elevated (breakout strategies):

//@version=6
strategy("High Volatility Filter", overlay=true)

atrLength = input.int(14, "ATR Length")
atrMALength = input.int(50, "ATR MA Length")
volatilityThreshold = input.float(1.2, "Min ATR/MA Ratio")

atr = ta.atr(atrLength)
atrMA = ta.sma(atr, atrMALength)

// Only trade when current ATR > average ATR
highVolatility = atr > atrMA * volatilityThreshold

longCondition = ta.crossover(close, ta.highest(high, 20)[1]) and highVolatility

if longCondition
    strategy.entry("Long", strategy.long)
    strategy.exit("Exit", "Long", stop=close - atr * 2)

bgcolor(highVolatility ? color.new(color.green, 90) : na)

Low Volatility Filter

Only trade when volatility is low (mean reversion strategies):

//@version=6
strategy("Low Volatility Filter", overlay=true)

atrLength = input.int(14, "ATR Length")
atrMALength = input.int(50, "ATR MA Length")
volatilityThreshold = input.float(0.8, "Max ATR/MA Ratio")

atr = ta.atr(atrLength)
atrMA = ta.sma(atr, atrMALength)

// Only trade when current ATR < average ATR (quiet market)
lowVolatility = atr < atrMA * volatilityThreshold

// Mean reversion setup
rsi = ta.rsi(close, 14)
longCondition = rsi < 30 and lowVolatility

if longCondition
    strategy.entry("Long", strategy.long)
    strategy.exit("Exit", "Long", stop=close - atr * 2, limit=close + atr * 2)

bgcolor(lowVolatility ? color.new(color.blue, 90) : na)

ATR Settings: What Period to Use?

ATR(14) - Standard

  • Most common setting
  • Balanced view of recent volatility
  • Good for most trading styles

ATR(7) - Short-term

  • More responsive to recent volatility
  • Better for day trading
  • Can be choppy

ATR(21) - Longer-term

  • Smoother, less reactive
  • Better for swing/position trading
  • Filters out short-term spikes

Pro tip: Match your ATR period to your trading timeframe. Day traders on 5-minute charts might use ATR(10), while position traders on daily charts might use ATR(20).

Building ATR Strategies with HorizonAI

Use HorizonAI to quickly implement ATR-based risk management:

Example prompts:

  • "Add a 2x ATR stop loss and 3x ATR take profit to my strategy"
  • "Create position sizing that risks 1% of account using ATR"
  • "Build an ATR trailing stop that activates after 1R profit"
  • "Only take trades when ATR is above its 50-period average"
Try it free →

FAQs

What is a good ATR value?

There's no universal "good" value—ATR varies by instrument and timeframe. Compare current ATR to its historical average to determine if volatility is high or low relative to normal.

ATR vs Standard Deviation: Which is better?

ATR accounts for gaps between sessions; standard deviation doesn't. For instruments that gap frequently (stocks), ATR is often more accurate.

Can ATR predict price direction?

No. ATR only measures how much price typically moves, not which direction. Use trend indicators for direction and ATR for sizing stops and targets.

Why does my ATR stop keep getting hit?

Your multiplier may be too tight. If using 1x ATR, price will naturally hit your stop ~50% of the time just from normal movement. Try 1.5-2x ATR for more breathing room.

Summary

ATR is essential for professional risk management:

  • Stop Losses: Set stops that adapt to current volatility (1.5-3x ATR)
  • Position Sizing: Risk consistent amounts across different assets
  • Take Profits: Set realistic targets based on typical movement
  • Trade Filtering: Only trade when volatility conditions match your strategy

Unlike indicators that try to predict direction, ATR tells you what's realistic. Use it to keep your expectations—and your risk—grounded in reality.

Have questions about ATR? Join our Discord to discuss with other traders!