Adaptive Moving Average ATR Bands (AMAAB) is a volatility-based, trend-following indicator that builds ATR bands around three different moving averages and combines them into a single outer envelope.
SMA, RMA and LSMA are calculated from the same source and length. Each moving average receives its own ATR bands, and the highest upper band and lowest lower band are used as the final bands.
Since the three moving averages react to price at different speeds, the envelope adapts its width to the distance between them, requiring a stronger move before the active condition changes.
Original concept: https://www.tradingview.com/script/u82khjne-Adaptive-Moving-Average-ATR-Bands-NJ/
Modified original by adding gray full bands and center line, which can be turned on/off in the settings.
This is an example of /NQ on a 10 minute chart.
SMA, RMA and LSMA are calculated from the same source and length. Each moving average receives its own ATR bands, and the highest upper band and lowest lower band are used as the final bands.
Since the three moving averages react to price at different speeds, the envelope adapts its width to the distance between them, requiring a stronger move before the active condition changes.
Original concept: https://www.tradingview.com/script/u82khjne-Adaptive-Moving-Average-ATR-Bands-NJ/
Modified original by adding gray full bands and center line, which can be turned on/off in the settings.
This is an example of /NQ on a 10 minute chart.
Code:
# Adaptive Moving Average ATR Bands (AMAAB)
# Original Concept: https://www.tradingview.com/script/u82khjne-Adaptive-Moving-Average-ATR-Bands-NJ/
# Converted by Chewie on 10/3/2026
declare upper;
# ===== INPUTS =====
input colorMode = {default Colored, Neutral};
input dispCandles = yes;
input full = yes;
input maSrc = close;
input maLen = 28;
input atrLen = 6;
input atrMulti = 0.75;
DefineGlobalColor("LongCol", CreateColor(0, 136, 100));
DefineGlobalColor("ShortCol", CreateColor(120, 0, 32));
DefineGlobalColor("LongNeutral", CreateColor(179, 179, 179));
DefineGlobalColor("ShortNeutral", CreateColor(60, 60, 60));
# ===== CALCULATION =====
# Three MAs: SMA, RMA (Wilder), and linear regression endpoint (linreg offset 0)
def smaMA = Average(maSrc, maLen);
def rmaMA = WildersAverage(maSrc, maLen);
def lsmaMA = Inertia(maSrc, maLen);
# ATR (Wilder / RMA, same as Pine ta.atr)
def atrVal = WildersAverage(TrueRange(high, close, low), atrLen);
def bandOff = atrVal * atrMulti;
# Farthest bands from price
def upperBandV = Max(Max(smaMA + bandOff, rmaMA + bandOff), lsmaMA + bandOff);
def lowerBandV = Min(Min(smaMA - bandOff, rmaMA - bandOff), lsmaMA - bandOff);
# ===== FINAL SIGNAL (Pine "var int NJ") =====
def NJ = CompoundValue(1,
if close > upperBandV then 1
else if close < lowerBandV then -1
else NJ[1],
0);
# ===== PLOTS =====
def isColored = colorMode == colorMode.Colored;
plot UpperBand = if NJ == -1 then upperBandV else Double.NaN;
UpperBand.SetLineWeight(3);
UpperBand.SetPaintingStrategy(PaintingStrategy.LINE);
UpperBand.AssignValueColor(if isColored then GlobalColor("ShortCol") else GlobalColor("ShortNeutral"));
plot LowerBand = if NJ == 1 then lowerBandV else Double.NaN;
LowerBand.SetLineWeight(3);
LowerBand.SetPaintingStrategy(PaintingStrategy.LINE);
LowerBand.AssignValueColor(if isColored then GlobalColor("LongCol") else GlobalColor("LongNeutral"));
plot U = if full then upperbandv else double.nan;
U.setdefaultColor(color.dark_gray);
plot D = if full then lowerbandv else double.nan;
D.setdefaultColor(color.dark_gray);
plot M = if full then (U - D)/2 + D else double.nan;
M.setdefaultColor(color.dark_gray);
# Color candles
AssignPriceColor(
if !dispCandles then Color.CURRENT
else if NJ == 1 then (if isColored then GlobalColor("LongCol") else GlobalColor("LongNeutral"))
else if NJ == -1 then (if isColored then GlobalColor("ShortCol") else GlobalColor("ShortNeutral"))
else Color.CURRENT
);