// Licensed under the Apache License, Version 2.0 // © mihakralj //@version=6 indicator("Average True Range Normalized (ATRN)", "ATRN", overlay=false, format=format.percent, precision=2) //@function Calculates the Average True Range Normalized (ATRN) relative to its maximum value over a longer period. //@param length The period length for the ATR calculation. The highest uses a length of 10 * length. //@returns The ATRN value, normalized relative to its maximum over the longer period. //@optimized Beta precomputation for RMA warmup compensation atrn(simple int length) => var float prevClose = close float tr1 = high - low float tr2 = math.abs(high - prevClose) float tr3 = math.abs(low - prevClose) float trueRange = math.max(tr1, tr2, tr3) prevClose := close float alpha = 1.0 / float(length) float beta = 1.0 - alpha var float EPSILON = 1e-10 var float raw_rma = 0.0 var float e = 1.0 float atrValue = na if not na(trueRange) raw_rma := (raw_rma * (length - 1) + trueRange) / length e *= beta atrValue := e > EPSILON ? raw_rma / (1.0 - e) : raw_rma int lookbackWindow = math.min(10 * length, bar_index + 1) float maxAtr = ta.highest(atrValue, lookbackWindow) float minAtr = ta.lowest(atrValue, lookbackWindow) minAtr < maxAtr ? (atrValue - minAtr) / (maxAtr - minAtr) : 0.5 // ---------- Main loop ---------- // Inputs i_length = input.int(14, "Length", minval=1, tooltip="Number of bars used for the ATR calculation") // Calculation atrnValue = atrn(i_length) // Plot plot(atrnValue, "ATRN", color=color.yellow, linewidth=2)