Edgoro
Volatility indicator

ATR indicator: formula, stop placement and Pine Script v6 code

What the Average True Range measures, how traders use ATR for stops and position sizing, common settings, and a free ATR stop-lines script for TradingView.

What it measures

The Average True Range measures how far price typically moves in one bar, including gaps. It says nothing about direction: a market falling hard and a market rising hard can have the same ATR. What it gives you is a sense of scale, which is exactly what you need for stops, targets and position size.

Wilder introduced ATR in 1978 alongside RSI and ADX. It is in the instrument's price units, so an ATR of 0.0060 on EUR/USD means about 60 pips of typical range per bar on that timeframe.

The formula in words

  1. For each bar, the true range is the largest of three distances: high − low, |high − previous close|, and |low − previous close|. The last two capture gaps between bars.
  2. ATR is a smoothed average of the true range over N bars (14 by default), using Wilder's smoothing: each new value = previous ATR × (N − 1) / N + today's true range / N.

Pine Script's ta.atr(14) uses this Wilder (RMA) smoothing. Be aware that not every platform does: MetaTrader 5's built-in ATR uses a simple average of the true range, so the two can differ slightly on the same bars.

How traders read it

  • Stop distance. A stop at 1.5 to 3 × ATR from entry sits outside the bar-to-bar noise for that market and timeframe. The ATR stop-loss calculator gives the level for any multiplier.
  • Position size. Once the stop is in ATR terms, size the trade so the stop costs a fixed share of the account. Quiet markets then get larger positions and volatile ones smaller; see position sizing and the 1% rule and the position size calculator.
  • Trailing stops. A stop that trails price by a multiple of ATR, ratcheting only in your favour, adapts to volatility as the trade runs. The script below draws one for each side.
  • Volatility regime. A rising ATR means bars are getting larger. Many traders reduce size or widen expectations when ATR is well above its own average.

Common settings

SettingTypical valueNotes
Length14Wilder's default. 20 to 22 for a steadier value on daily charts.
Stop multiplier1.5 to 3Smaller multipliers get stopped out by noise more often.
Trailing referenceHigh/low or closeMeasuring from the high (for longs) gives a chandelier-style stop.

Pine Script v6 code

The complete, self-contained script is below. Copy it into a new indicator in TradingView's Pine Editor, or download the .pine file.

Pine Script v6
//@version=6
indicator("ATR stop lines", shorttitle = "ATR stops", overlay = true)

atrLen = input.int(14, "ATR length", minval = 1)
mult   = input.float(2.0, "Stop distance (x ATR)", minval = 0.1, step = 0.1)
useHL  = input.bool(true, "Measure from the high/low instead of the close")
trail  = input.bool(true, "Trail: only move a stop in the trade's favour")

atr      = ta.atr(atrLen)
rawLong  = (useHL ? high : close) - mult * atr
rawShort = (useHL ? low : close) + mult * atr

var float longStop  = na
var float shortStop = na
prevLong  = longStop
prevShort = shortStop

// A long stop ratchets up while price closes above it; after a close through it, it restarts from the raw level.
longStop  := trail and not na(prevLong) and close[1] > prevLong ? math.max(rawLong, prevLong) : rawLong
shortStop := trail and not na(prevShort) and close[1] < prevShort ? math.min(rawShort, prevShort) : rawShort

longBreak  = not na(prevLong) and close < prevLong
shortBreak = not na(prevShort) and close > prevShort

plot(longStop, "Long stop", color = color.new(color.teal, 0), style = plot.style_stepline)
plot(shortStop, "Short stop", color = color.new(color.red, 0), style = plot.style_stepline)
plot(atr, "ATR", display = display.data_window)
plotshape(longBreak, "Close below long stop", shape.xcross, location.belowbar, color.new(color.teal, 0), size = size.tiny)
plotshape(shortBreak, "Close above short stop", shape.xcross, location.abovebar, color.new(color.red, 0), size = size.tiny)

var table info = table.new(position.top_right, 2, 3, border_width = 1)
if barstate.islast
    table.cell(info, 0, 0, "ATR(" + str.tostring(atrLen) + ")", text_color = chart.fg_color)
    table.cell(info, 1, 0, str.tostring(atr, format.mintick), text_color = chart.fg_color)
    table.cell(info, 0, 1, "Stop distance", text_color = chart.fg_color)
    table.cell(info, 1, 1, str.tostring(mult * atr, format.mintick), text_color = chart.fg_color)
    table.cell(info, 0, 2, "In ticks", text_color = chart.fg_color)
    table.cell(info, 1, 2, str.tostring(math.round(mult * atr / syminfo.mintick)), text_color = chart.fg_color)

alertcondition(longBreak, "Close below long stop", "{{ticker}} closed below the ATR long stop ({{interval}})")
alertcondition(shortBreak, "Close above short stop", "{{ticker}} closed above the ATR short stop ({{interval}})")

Two step lines are drawn on the price chart: a long stop below price and a short stop above it, each a multiple of ATR away. With trailing on, a stop only moves in the trade's favour until price closes through it, then restarts. A small table on the right shows the current ATR, the stop distance in price, and the same distance in ticks, which is what you need for sizing.

Alerts fire when price closes through either stop. The ATR value itself is in the data window.

Add it to your chart

  1. Open any chart on TradingView and open the Pine Editor.
  2. Create a new indicator, delete the template code and paste the script.
  3. Click Save, then Add to chart. Change lengths and levels from the indicator's settings.

Stuck on an error? See how to add a Pine Script indicator to TradingView.

Pitfalls

  • Comparing ATR across platforms. Smoothing methods differ (Wilder in Pine Script, a simple average in MT5's built-in ATR), so values on the same bars can be slightly different.
  • Using ATR as a direction signal. It only measures range. Rising ATR can come with a rally or a sell-off.
  • Stops too tight for the timeframe. One ATR on a 5-minute chart is a tiny distance; a news spike can cover it in seconds.
  • Forgetting gaps. ATR includes past gaps in the average, but a stop is still only a level. Weekend and news gaps can fill you beyond it.

The script is an educational example: test it on your own markets before relying on it. Indicators describe the past; they don't predict the future. Trading involves substantial risk of loss and is not suitable for every investor. Edgoro is a software tool, not a broker or financial adviser: nothing it produces is investment advice, and past or backtested performance does not guarantee future results.

Make it yours with Edgoro

Describe the change in plain English and Edgoro writes the Pine Script v6 for you, ready to paste. For example:

“Plot a 3 × ATR(14) trailing stop for longs that only moves up, show the stop distance in pips in a table, and alert when price closes below it.”

Build your ATR indicator