ATR-Based Position Sizing

Calculate position size based on current volatility (ATR) and a fixed percentage of account equity.

Professional traders never risk a fixed dollar amount or a fixed number of points per trade. They size positions based on criteria that ideally takes in the current volatility of the instrument — because volatility defines how much room a trade needs to breathe relative to market conditions today.

The fixed-point problem is one of the most underappreciated issues in strategy development. Consider the S&P 500: a 100-point stop loss in the year 2000 represented roughly 10% of the index's value (S&P 500 near 1,000). At that level, a 100-point stop would be hit on many ordinary trading days — it was a wide, generous stop for its era. In 2024, with the S&P 500 above 5,000, a 100-point move is less than 2% of the index's value and is comfortably within normal intraday noise. The same 100-point stop that was wide in 2000 and might have taken several months to achieve is now a typical daily move.

A strategy built with a fixed 100-point stop in 2000 and backtested across 20 years of data is broken by design. The stops and targets that worked in the early period become progressively miscalibrated as the instrument's price level and volatility evolve. ATR is one way that can help. It fixes this by anchoring every distance — stop, target, trailing stop — to how much the instrument is actually moving right now. This isn't a silver bullet and there are circumstances where we need to be careful; however, let's first look at how it's constructed.

The formula

Position size under ATR-based sizing comes out of a single expression:

``` stop_distance = ATR × atr_multiplier (in price units) cash_per_unit = stop_distance × point_value (what one unit of the instrument loses if the stop hits) position_size = cash_risk_per_trade / cash_per_unit (contracts / shares / lots) ```

Worked example: S&P 500 futures (ES). ATR(14) = 40 points. You choose a 2× ATR stop, so stop distance = 80 points. ES has a point value of $50 per contract, so cash per contract if the stop hits = 80 × $50 = $4,000. If your fixed risk per trade is $200, position size = 200 / 4,000 = 0.05 contracts — which means you cannot trade this signal with a standard ES contract and should either move to the Micro E-mini (MES, $5/point → 0.5 MES contracts, still sub-1) or skip the trade. That kind of answer is exactly what this formula is for: it tells you honestly whether the trade is sizeable at your risk tolerance.

The fixed-point problem in detail

To make the scale problem concrete, here is a comparison of what a 100-point stop has meant on the S&P 500 at different points in history:

| Year | S&P 500 Level | 100-point stop = | ATR(14) approx. | |---|---|---|---| | 2000 | ~1,000 | ~10% of price | ~20–30 pts | | 2008 | ~1,200 | ~8% of price | ~30–60 pts | | 2015 | ~2,000 | ~5% of price | ~20–30 pts | | 2020 | ~3,000 | ~3% of price | ~80–120 pts | | 2024 | ~5,000 | ~2% of price | ~50–80 pts |

In 2000, a 100-point stop was roughly 3–5 ATR — very generous, rarely hit on normal days. In 2024, the same 100-point stop is 1–2 ATR — well within normal daily noise. A system optimised with a 100-point stop in 2000 will generate far more stop-outs in 2024 than it was designed for, not because the strategy logic changed, but because the instrument's scale changed.

The same issue applies to any instrument that trends upward over time: stocks, indices, gold, Bitcoin. A fixed-point stop progressively tightens (relative to the instrument) as price rises.

How ATR-based sizing works

The formula is simple:

  1. Calculate the stop distance in price points: `atrValue × stopMultiplier`
  2. Calculate the risk amount in cash: `accountEquity × riskPercent`
  3. Divide: `riskAmount / stopDistance = positionSize`
  • If ATR is 50 points, your stop multiplier is 2×, and you want to risk 1% of a $10,000 account:
  • Stop distance = 50 × 2 = 100 points
  • Risk amount = $10,000 × 1% = $100
  • Position size = $100 / 100 = 1 unit
  • If ATR doubles to 100 (market gets volatile):
  • Stop distance = 100 × 2 = 200 points
  • Risk amount = $100 (unchanged)
  • Position size = $100 / 200 = 0.5 units

You automatically trade half the size in volatile conditions, protecting the account. In calmer conditions, the stop shrinks and the position size grows — you take larger positions when the market is offering cleaner, lower-noise conditions.

What "consistent risk" actually means

The goal of ATR-based sizing is consistent cash risk per trade, not consistent position size. Every trade risks the same percentage of equity, regardless of:

  • How volatile the instrument is today versus last year
  • Whether you are trading a $50 stock or a $5,000 index
  • Whether this is a high-volatility period or a calm, drifting market
  • Whether you started your strategy in 2000 or 2020

This is what makes the strategy scale-invariant. It can be applied to different instruments and different time periods without recalibration. The math adjusts automatically.

ATR adapts to volatility regimes

Markets cycle through volatility regimes. After a major news event or a financial crisis, daily ATR can triple or quadruple compared to normal conditions. During quiet summer trading, ATR might compress to a fraction of its normal value.

A fixed-point strategy treats all these conditions identically. ATR-based sizing responds:

  • High volatility → larger stop distances → smaller positions → lower risk per bar moved
  • Low volatility → smaller stop distances → larger positions → still the same cash risk

This is why professional systematic traders almost universally use some form of volatility-based sizing. It is not just about being precise — it is about building a strategy that remains valid across the full range of market conditions it will encounter.

Applying it to backtests

When running a backtest with ATR-based sizing, the `strategy.equity` variable gives you the current account value as it evolves. This means position sizes will also evolve as the account grows or shrinks during the backtest — which gives you a realistic simulation of how the strategy would behave in live trading with compounding.

The key inputs to tune are the ATR length (standard is 14), the ATR multiplier for stops (typically 1.5–3.0), and the risk percentage per trade (commonly 0.5–2.0% for systematic strategies).

//@version=6
strategy("ATR Position Sizing", overlay=true, default_qty_type=strategy.fixed, default_qty_value=1)

// Risk parameters
riskPercent = input.float(1.0, "Risk Per Trade (%)", step=0.1)
atrLength = input.int(14, "ATR Length")
atrMult = input.float(2.0, "ATR Stop Multiplier")

// Account info
accountBalance = strategy.equity

// ATR calculation
atrValue = ta.atr(atrLength)
stopDistance = atrValue * atrMult

// Position size calculation
riskAmount = accountBalance * (riskPercent / 100)
positionSize = math.floor(riskAmount / stopDistance)

// Simple entry logic
longCondition = ta.crossover(ta.ema(close, 9), ta.ema(close, 21))
shortCondition = ta.crossunder(ta.ema(close, 9), ta.ema(close, 21))

if (longCondition)
    strategy.entry("Long", strategy.long, qty=positionSize)
    strategy.exit("Long SL", "Long", stop=close - stopDistance, limit=close + stopDistance * 2)

if (shortCondition)
    strategy.entry("Short", strategy.short, qty=positionSize)
    strategy.exit("Short SL", "Short", stop=close + stopDistance, limit=close - stopDistance * 2)