Updated November 3, 2026. This article covers the definition and calculation of ATR and how it feeds stop-distance and position-size rules. Numbers below are illustrative examples of the arithmetic, not backtest or live trading results.
ATR measures the size of moves, not their direction
ATR (Average True Range) is a volatility indicator that J. Welles Wilder Jr. introduced in his 1978 book New Concepts in Technical Trading Systems. It says nothing about whether price will rise or fall. It only shows, in price units, how far a bar has typically moved recently.
That makes ATR a risk-management tool rather than an entry signal. The same number can link where a stop goes and how many units can be bought at that stop distance without exceeding the loss limit per trade. ATR rises in both rallies and selloffs, so a rising ATR is neither bullish nor bearish by itself.
True Range adds gaps to the intraday range
Using only high minus low misses days that open with a large gap from the previous close. Wilder’s True Range (TR) takes the largest of three values.
TR = max(High − Low, |High − Previous Close|, |Low − Previous Close|)
If the previous close was 100 and today traded only between 104 and 106, the intraday range is 2 but TR is 6. The 4 points moved through the gap count as risk.
Wilder’s smoothing is an exponential average with period 14
Wilder’s method, as documented by StockCharts ChartSchool, has two steps. The first ATR is the simple average of the first 14 TR values. After that, the prior ATR gets a weight of 13 and the new TR a weight of 1.
First ATR = average of the first 14 TRs
Later ATR = (Prior ATR × 13 + Current TR) / 14
This recursion is an exponential moving average with smoothing factor α = 1/14. The same “14” therefore reacts much more slowly than a conventional EMA with span 14 (α = 2/15). If a platform computes ATR with an SMA or a conventional EMA, or starts the calculation from a different amount of history, its values will differ slightly. Confirm that backtest and live trading use the same definition.
An ATR chart follows volatility changes with a lag
Rising ATR means recent bars have been moving more; falling ATR means less. Because of the smoothing, ATR understates current risk right after a shock and stays elevated for a while after the shock has passed.
ATR is an absolute value in price units. An ATR of 2 means something different for an asset priced at 20 than for one priced at 200, so cross-asset comparison converts it to a ratio such as ATR ÷ Close × 100. Timeframes must also match. Daily and hourly ATR are not directly comparable; compute ATR on the bars on which stops and orders are managed.
Tie stop distance and size to one risk budget
ATR-based risk management rests on two formulas.
Stop distance = ATR × multiple
Units = risk budget per trade ÷ stop distance
With a risk budget of 1,000, ATR of 2.5, and a multiple of 2, the stop distance is 5 and the size is 200 units. If ATR doubles to 5, the stop distance doubles and the size falls to 100. The loss when the stop is hit stays roughly the same as volatility changes.
The code below implements TR, Wilder ATR, and the size calculation with the standard library only, and checks the numbers above.
def true_range(high, low, prev_close):
if prev_close is None:
return high - low
return max(high - low, abs(high - prev_close), abs(low - prev_close))
def wilder_atr(bars, n=14):
"""bars: list of (high, low, close). Returns ATR list (None until n TRs exist)."""
trs, prev = [], None
for high, low, close in bars:
trs.append(true_range(high, low, prev))
prev = close
atr = [None] * len(trs)
if len(trs) < n:
return atr
atr[n - 1] = sum(trs[:n]) / n
for i in range(n, len(trs)):
atr[i] = (atr[i - 1] * (n - 1) + trs[i]) / n
return atr
def position_size(risk_budget, atr_value, multiple):
stop_distance = atr_value * multiple
return int(risk_budget // stop_distance), stop_distance
# Gap: previous close 100, today's range 104-106 -> TR uses the gap, not 2.
assert true_range(106, 104, 100) == 6
assert true_range(101, 99, 100) == 2
bars = [(11, 9, 10)] * 3 + [(14, 10, 13)]
atr = wilder_atr(bars, n=3)
assert atr[2] == 2 # first value = simple mean of 3 TRs
assert abs(atr[3] - (2 * 2 + 4) / 3) < 1e-12 # then (prev * (n-1) + TR) / n
units, stop = position_size(risk_budget=1_000, atr_value=2.5, multiple=2)
assert (units, stop) == (200, 5.0)
assert position_size(1_000, 5.0, 2)[0] == 100 # ATR doubles -> size halves
The same structure serves trailing stops. Charles Le Beau’s Chandelier Exit for a long position uses the highest high of the last 22 periods minus 3 × ATR(22) as the exit line. The line rises as a trend continues, but in directionless markets it can produce repeated exits and re-entries.
| Use | Calculation | What to check |
|---|---|---|
| Initial stop | Entry ± ATR × multiple | Whether size falls as the multiple grows |
| Position size | Risk budget ÷ (ATR × multiple) | Actual loss when a gap fills beyond the stop |
| Trailing stop | 22-period high − 3 × ATR(22) | Cost of repeated exits in sideways markets |
| Volatility breakout filter | Reference price ± ATR × multiple | A separate direction condition, since ATR has none |
Period and multiple are parameters to test
Shortening the period to 7 makes ATR react faster but adds noise; lengthening it to 20–22 makes it steadier but slower. The stop multiple works the same way. It is not a constant that raises the win rate; it is a risk parameter to set together with holding period, gap risk, transaction costs, and the target reward-to-risk ratio.
ATR does not account for these risks:
- Gaps and liquidity: A stop order can fill worse than its price during a gap or in a thin order book. The calculated loss limit and the realized loss can differ.
- Regime change: The volatility of the last 14 bars does not guarantee the volatility of the next one.
- Direction: A high ATR alone cannot decide between buying and selling.
If you tested several period and multiple combinations, do not adopt the best one as is. Re-check it with walk-forward methods that include the selection step, as described in Preventing backtest overfitting. For collecting the bar data that feeds ATR, see the exchange API data pipeline.
Sources and scope
- StockCharts ChartSchool: Average True Range (ATR): Wilder (1978) origin, True Range definition, first ATR and the smoothing recursion.
- StockCharts ChartSchool: Chandelier Exit: Charles Le Beau’s 22-period, 3-ATR default and formula.
- Park & Irwin (2007), “What Do We Know About the Profitability of Technical Analysis?”: literature review noting recurring data-snooping, ex post rule selection, and cost-estimation problems in technical trading studies.
- This article explains how ATR is calculated and how risk rules are structured. It does not claim that any period or multiple earns returns or limits losses, and it is not investment advice.

