Tutorial

ATR in Pine Script: Measuring Volatility in Code

What the Average True Range measures, why it is the backbone of volatility-aware stops and sizing, and how to build and use it in Pine Script v6.

10 min read

The Average True Range is not a signal indicator, and that is exactly why it is one of the most useful tools in Pine Script. It does not tell you which way price is going; it tells you how much price typically moves. That single number, a measure of volatility in the chart's own price units, is the backbone of volatility-aware stop losses, position sizing, and adaptive indicators like Supertrend and Keltner Channels. This guide explains what ATR measures, why traders build so much on top of it, and how to use it from scratch in Pine Script v6 on TradingView.

This is a coding tutorial, not trading advice. ATR is a way to express "how much is normal movement here" in code, and understanding it unlocks a whole category of adaptive logic.

What ATR measures

ATR is built on a concept called true range, developed by J. Welles Wilder Jr., the same author behind the RSI. True range for a bar is the largest of three distances: the current high minus the current low, the current high minus the previous close, and the previous close minus the current low. The reason it considers the previous close, not just the current bar's own high and low, is to capture gaps. If a market opens far from where it closed yesterday, the true range accounts for that jump even though it happened between bars.

The Average True Range is then a smoothed average of the true range over a lookback period, traditionally 14 bars, using Wilder's smoothing method. The output is a single positive number in the same units as price. On a stock trading at 100 dollars, an ATR of 2 means the market typically moves about two dollars per bar. On a different symbol at a different price, the ATR will be a completely different number, which is why ATR is usually used relative to price rather than as an absolute value to compare across markets.

Why traders use it

The single most common use of ATR is setting stops that adapt to volatility. A fixed stop, say fifty cents, is too tight on a volatile day and gets hit by normal noise, and too wide on a calm day, risking more than necessary. A stop placed a multiple of ATR away from entry solves both problems at once: it automatically widens when the market is volatile and tightens when it settles down. The same idea drives ATR-based position sizing, where you risk a fixed amount of money and let the ATR-derived stop distance decide how many units that translates to.

Fixed distanceATR-based distance
Adapts to volatilityNoYes
Behaves in calm marketsToo wide or too tightTightens automatically
Behaves in volatile marketsStopped out earlyWidens automatically
Pine building blockA constantta.atr()

Beyond stops and sizing, ATR is the raw material for other indicators. Supertrend places its trailing line a multiple of ATR from price, and Keltner Channels build their bands from ATR. Understanding ATR therefore makes those indicators far less mysterious, since you can see exactly what is scaling their distances. Our Supertrend guide is a good example of ATR doing its work inside a larger indicator.

Building the indicator

Pine Script provides ATR as a single built-in function. Here is a simple v6 indicator that plots it in its own pane.

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

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

atrValue = ta.atr(length)

plot(atrValue, "ATR", color = color.purple, linewidth = 2)

The whole calculation is ta.atr(length), which computes the Average True Range over your chosen lookback using Wilder's smoothing. Because ATR is measured in price units rather than a bounded 0-to-100 scale, it belongs in its own pane, hence overlay = false. The plotted line rises during volatile stretches and falls during calm ones, which on its own is a useful read on whether the market is expanding or contracting. If you want to see the true-range math worked out step by step, our ATR calculator shows it with the Pine Script equivalent beside it.

Using ATR for a volatility-based stop

The more practical use of ATR is inside a strategy, where it sizes the stop. Here is a simple example that enters on a moving-average crossover and places an ATR-based stop and target.

pine
//@version=6
strategy("ATR Stop Strategy", overlay = true, margin_long = 100, margin_short = 100)

atrLength  = input.int(14, "ATR Length")
atrMult    = input.float(2.0, "ATR Multiplier")

fastMA = ta.ema(close, 9)
slowMA = ta.ema(close, 21)

atrValue = ta.atr(atrLength)

if ta.crossover(fastMA, slowMA)
    stopDist   = atrValue * atrMult
    stopPrice  = close - stopDist
    targetPrice = close + stopDist * 2
    strategy.entry("Long", strategy.long)
    strategy.exit("Exit", "Long", stop = stopPrice, limit = targetPrice)

The key line is stopDist = atrValue * atrMult, which turns the current volatility into a stop distance. Multiplying the ATR by two places the stop two average ranges below entry, far enough that ordinary noise will not trigger it but close enough to cap the loss. The target here is set to twice the stop distance, a two-to-one reward-to-risk arrangement, though that ratio is a choice, not a rule. The strategy.exit() call attaches both the stop and the limit to the position; if you want the full mechanics of stops, targets, and how the exit call behaves, our guide to position size in Pine Script goes deeper.

Choosing the length and multiplier

The two knobs are the ATR length and the multiplier. A shorter length makes the ATR react faster to recent volatility, so stops adjust quickly but can be jumpy; a longer length gives a smoother, slower volatility estimate. The multiplier controls how many average ranges of room you give the trade. A smaller multiplier means tighter stops and more frequent stop-outs; a larger one means more room but a bigger loss when the stop is hit. The 14-length, 2-multiplier combination is a common starting point, but the right values depend on the timeframe and how much noise you are willing to sit through.

The honest pitfalls

The most common mistake is comparing ATR values across symbols as if they were the same unit. An ATR of 5 is enormous on a ten-dollar stock and trivial on a ten-thousand-dollar index, so ATR is only meaningful relative to the price it is measured on. If you want a comparable measure across markets, divide ATR by price to get a percentage, as some volatility screens do.

The second pitfall is treating ATR as directional. It says nothing about which way price will move, only how far it tends to travel, so an ATR spike can accompany a rally or a crash equally. Use it for what it is, a volatility gauge, and pair it with a separate directional signal. As always, test any ATR-based stop logic across a meaningful sample, and remember that stop and target fills in a backtest carry assumptions worth understanding, which our guide to how TradingView backtesting works explains.

Building it faster

Wiring ATR into stops and sizing by hand is genuinely useful practice, because it forces you to think about risk in the market's own units. When you already know the rules you want, describing them in plain English is faster than assembling the exit logic yourself. A tool like PineScripter generates the v6 code and fixes compile errors automatically by reading TradingView's messages directly. You can compare it with other options in our roundup of the best AI Pine Script generators.

The takeaway

ATR is a volatility measure delivered by one function, ta.atr(), that reports how much a market typically moves in the chart's own price units. It is not a signal but a scaling tool, and it is the foundation of adaptive stops, volatility-based sizing, and indicators like Supertrend and Keltner Channels. Build it, use it to make your stops and sizing respond to the market, and remember it tells you how far, never which way.


Disclaimer: PineScripter is a coding tool for Pine Script development. It does not provide financial advice and does not guarantee trading profits. Always backtest strategies thoroughly and understand the risks before live trading.