All posts · Indicators · Risk management · Expert Advisors

Why Many Traders Misuse ATR (and How to Use It Properly)

ATR is everywhere, and often misused. What Average True Range really measures, why one fixed setting fails, and how to code ATR stops, filters and sizing.

· 6 min read · Updated

Average True Range (ATR) is everywhere in trading literature. Open a technical analysis book, a trading video or a forum thread, and you'll find ATR recommended for stop losses, position sizing and measuring volatility. It's also easy to misuse.

ATR isn't the problem. The problem is treating it as a magic number that works the same on every market, every timeframe and in every condition, without understanding what it measures or when it breaks down.

If you code strategies or trade systematically, these details matter. Here's what ATR really tells you, and how to use it in an Expert Advisor.

This is educational content about coding indicators and risk rules, not trading advice. The multipliers, thresholds and percentages below are examples to show the method, not recommended settings or risk levels for your account.

What ATR actually measures

ATR, introduced by J. Welles Wilder in 1978, is an average of the True Range over N bars. True Range is the largest of:

  • current high − current low
  • |current high − previous close|
  • |current low − previous close|

Wilder smoothed it with his own moving average, a form of exponential smoothing. MetaTrader's built-in ATR uses a simple moving average of True Range instead, so its values can differ slightly from other platforms.

Most traders stop there: take the default 14 periods, multiply by some constant for a stop, done. That's where the problems start.

Mistake 1: assuming volatility is stable

Volatility clusters. Markets cycle between quiet stretches and violent ones. An ATR(14) measured in a quiet summer week looks nothing like one measured around a major data release.

"Stop at 2× ATR" raises a question: ATR measured when? If you calibrated in a calm market and conditions change, your stops end up either too tight (stopped out by noise) or too wide (bigger losses than intended).

Mistake 2: using one ATR logic for every market

An ATR(14) on Bitcoin measures something very different from an ATR(14) on government bonds. Crypto trades around the clock and can move sharply at any hour. Bond futures have set sessions and react to scheduled releases. Applying identical ATR rules to both is like using one recipe for bread and for chicken.

Mistake 3: mismatching timeframe and holding period

If you swing trade and hold for about five days, the volatility that drives your profit and loss is daily volatility. Sizing the position from a 5-minute chart's ATR, just because you time entries on that chart, measures the wrong thing.

How to use ATR properly

1. Normalize ATR by price to compare markets

Raw ATR is in price units. A $50 ATR on a $5,000 stock is 1% volatility; a $50 ATR on a $100 stock is 50%.

So normalize it:

text
ATR% = ATR / Price × 100

Now volatility is comparable across markets. When scanning several markets, rank them by ATR% rather than raw ATR, so you don't accidentally overweight high-priced, low-volatility instruments.

In MQL5:

MQL5
int atrHandle = INVALID_HANDLE;

int OnInit()
{
   atrHandle = iATR(_Symbol, _Period, 14);
   if(atrHandle == INVALID_HANDLE)
      return INIT_FAILED;
   return INIT_SUCCEEDED;
}

// ATR of the last closed bar as a percentage of its close, or 0 if data isn't ready
double AtrPercent()
{
   double atr[1];
   if(CopyBuffer(atrHandle, 0, 1, 1, atr) != 1)
      return 0.0;
   double price = iClose(_Symbol, _Period, 1);
   return price > 0 ? atr[0] / price * 100.0 : 0.0;
}

2. Adapt the multiplier to the volatility regime

A fixed multiplier ignores whether the market is calmer or wilder than usual. Compare short-term ATR with long-term ATR:

text
Volatility_Ratio = ATR(14) / ATR(100)

And let the stop multiplier follow it. For example:

text
Volatility_Ratio < 0.5          use 1.5 × ATR stops
0.5 ≤ Volatility_Ratio ≤ 1.5    use 2.0 × ATR stops
Volatility_Ratio > 1.5          use 3.0 × ATR stops

The idea: in calm conditions price moves more steadily and a tighter stop is less likely to be hit by noise. In volatile conditions a stop needs more room, and targets usually widen too. The thresholds are illustrative; test your own rather than copying these.

3. Match the ATR period to your holding period

If your trades last about 20 bars, the volatility that matters is over roughly 20 bars, not the default 14. One rough heuristic:

text
ATR_Period ≈ median holding period (in bars) × 0.7

The 0.7 makes the measure a little more responsive than the full holding period, without making it jumpy.

Example: you day trade index futures on a 5-minute chart and hold for about 45 minutes, which is 9 bars. That suggests ATR(6) or ATR(7). The default ATR(14) on that chart covers 70 minutes, longer than the trades themselves.

4. Use ATR for position sizing, not only stops

Sizing from the stop distance alone is only as good as the stop:

text
Position_Size = Risk_Per_Trade / (Entry − Stop)

Put an arbitrarily tight stop on a volatile market and this gives you a large position that noise can easily stop out. Tying size to volatility keeps your exposure comparable across markets:

text
Position_Value = Account × Risk_Per_ATR / ATR%

With this formula, a one-ATR move costs the same share of the account whatever you trade. Volatile markets get smaller positions and calm markets get larger ones.

Hypothetical example, just to show the arithmetic: a $100,000 account sizing positions so that a one-ATR move equals 2% of the account. The 2% isn't a suggested risk level. Market A has an ATR% of 3%, market B of 1%.

  • Market A: 100,000 × 0.02 / 0.03 ≈ $66,667 position
  • Market B: 100,000 × 0.02 / 0.01 = $200,000 position (which needs leverage)

In both cases a one-ATR move is worth about $2,000. Note that the calm market gets the bigger position, and leverage magnifies losses as well as gains. A one-ATR move is also not the most a position can lose: prices can move several ATRs, or gap past a stop.

5. Add percentile filters for extremes

ATR tells you the average. For risk, the extremes matter more. Ranking today's ATR against its own history shows when volatility is unusually high or low:

text
ATR_Percentile = percentile rank of ATR(14) among its last 252 values

An EA can use it to scale down in extreme conditions. For example:

text
ATR_Percentile > 90    trade at half size
ATR_Percentile < 10    normal size, or skip (moves may be too small to cover costs)

Something to test: compare the results of trades entered at very high ATR percentiles with those entered around median levels, on your own market and strategy. The idea isn't to avoid volatility, but to stop the EA from taking full size when volatility is extreme.

6. Use different ATR lengths for different jobs

One ATR setting rarely suits every purpose:

  • Stops: ATR(14) or ATR(20). Smooth enough that stops don't jump around.
  • Position sizing: ATR(50) or ATR(100). A longer-term picture of typical volatility.
  • Regime detection: a short ATR against a long one, such as ATR(10) vs ATR(200), to spot changes quickly.

In MQL5, a regime ratio from two ATR handles:

MQL5
int shortAtr = INVALID_HANDLE, longAtr = INVALID_HANDLE;

int OnInit()
{
   shortAtr = iATR(_Symbol, _Period, 10);
   longAtr  = iATR(_Symbol, _Period, 200);
   if(shortAtr == INVALID_HANDLE || longAtr == INVALID_HANDLE)
      return INIT_FAILED;
   return INIT_SUCCEEDED;
}

// > 1.5: unusually volatile, < 0.5: unusually quiet, 0 if data isn't ready
double VolatilityRegime()
{
   double s[1], l[1];
   if(CopyBuffer(shortAtr, 0, 1, 1, s) != 1 || CopyBuffer(longAtr, 0, 1, 1, l) != 1 || l[0] <= 0)
      return 0.0;
   return s[0] / l[0];
}

Five more things about ATR

1. Volatility fades slowly. After a spike, ATR doesn't snap back to normal; volatility often stays elevated for weeks. An EA can require signs that it's falling before returning to normal size. One simple check: ATR(14) crossing below its own 20-period average.

2. ATR underestimates gap risk. ATR averages over bars, so a sudden gap only gradually shows up in it, and the loss from a gap can be far larger than any ATR-based stop suggests. For gap-prone instruments, such as individual stocks around earnings, an EA can widen stops, reduce size or stay flat around known events.

3. ATR says how far, not where. ATR gives a volatility-appropriate distance, not a location. Combine it with price structure. For a long trade, for example:

text
ATR_Distance = 2 × ATR(20)
Support      = nearest support level below entry
Stop         = min(Entry − ATR_Distance, Support − small buffer)

The stop then sits beyond the support level and at least 2 ATR from entry. If that puts it too far away for your risk budget, skip the trade rather than tightening the stop.

4. Different markets may suit different periods. Reasonable starting points to test: ATR(20) for equity indices, ATR(14) for FX pairs, ATR(10)–ATR(15) for individual stocks depending on liquidity, and ATR(7)–ATR(10) for crypto, where volatility changes faster. Don't use 14 just because it's the default.

5. ATR can set targets, too. A profit target of, say, 2.5–3× ATR from entry is grounded in how far price typically moves, rather than a fixed risk-reward ratio. Stops, on the other hand, work better when they consider ATR and price structure.

Implementation checklist

If you're coding a strategy that uses ATR:

  1. Use ATR% (normalized by price) whenever you compare markets.
  2. Match the ATR period to your typical holding period instead of defaulting to 14.
  3. Detect volatility regimes with a short-to-long ATR ratio.
  4. Scale position size inversely to ATR% for consistent volatility exposure.
  5. Use ATR percentiles to spot extreme volatility.
  6. Combine ATR stops with price structure.
  7. Consider ATR-based profit targets.
  8. Account for gap risk around known events.
  9. Test different ATR periods on your own market.
  10. Wait for volatility to actually fall before sizing back up after a spike.

Final thoughts

ATR isn't plug-and-play. It's raw material that needs processing before it's useful. Using it well comes down to understanding what it measures and adapting it to the market, the timeframe and the conditions.

Don't treat the defaults as universal. Normalize ATR, adapt it to the volatility regime, match it to how you actually trade, and test every rule on historical data and a demo account before it touches real money.

For the basics of sizing and risk, see position sizing and risk management. For how volatility filters fit into a full trading bot, see trend following EAs: when they work and when they die.

Build a bot from your idea

Describe your trading idea and the AI writes MT4 or MT5 code for you to review and test, with a plain-English explanation and setup steps. Your first bot is free.

More from the blog