Skip to content
Open RaamTrade

NATR — Normalized ATR

TA-Lib’s normalised average true range: ATR as a percentage of the close. Identical in construction to ATRPercent — it ships under both names because TA-Lib users search for NATR and chartists search for “ATR percent”.

Signature

NATR(period, on=<source>)
Argument Type Required Notes
period int Param or literal Yes ATR length. Default 14, bounds 1–100.
on= symbol No Source symbol. Defaults to the trade symbol. Reads high, low, close.

Formula

$$ \text{NATR} = 100,\frac{\text{ATR}(n)}{C} $$

Warmup

The ATR seeds cumulatively over its first period bars, then Wilder smoothing; converges over roughly 3n bars.

Reading the value

natr.value
natr.value > 2

Example

class VolatilityGate(Strategy):
"""Skip entries when normalised volatility is extreme."""
trade = Symbol()
sizing = FixedCapital()
def execute(self):
natr = NATR(14, on=self.trade)
sma = SMA(50, on=self.trade)
if natr.value < 2.5 and self.trade.close > sma.value and self.trade.is_flat:
self.buy(self.trade, reason=f"NATR {natr.value:.2f}")
if natr.value > 4 and self.trade.is_long:
self.sell(self.trade, self.trade.position, reason="Volatility spike")

Notes

  • TA-Lib NATR.
  • Proven by an assert-via-trade run on SPY daily (converged to an independent ATR replication within 0.02 once warm; zero alarm trades).
  • Same numbers as ATRPercent. Use one or the other inside a strategy, not both.
  • The recursion seeds from the first bar rather than from a warm-up window, so early values are not comparable with TA-Lib NATR(14), which seeds from an average of the first n; measured on a 300-bar tape the two agree to 1e-6 from bar 149 onward.