This is a modified conversion of the RMA ATR Bands which is a directional volatility trend indicator built around a smoothed RMA baseline combined with asymmetric ATR expansion bands.
Unlike traditional symmetric ATR envelopes, the indicator uses independent upper and lower ATR multipliers to create adaptive directional filtering and trend regime detection. This allows the system to respond differently to bullish and bearish volatility conditions while maintaining a smoother baseline structure through RMA smoothing.
Bullish regime:
• Price closes above the upper ATR expansion band
Bearish regime:
• Price closes below the lower ATR expansion band
I added and modified the upper and lower bands along with dots for extreme conditions.
Original code: https://www.tradingview.com/script/xN8JwiZI-RMA-ATR-Bands/
Here is /MES on the 10 minute chart.
Unlike traditional symmetric ATR envelopes, the indicator uses independent upper and lower ATR multipliers to create adaptive directional filtering and trend regime detection. This allows the system to respond differently to bullish and bearish volatility conditions while maintaining a smoother baseline structure through RMA smoothing.
Bullish regime:
• Price closes above the upper ATR expansion band
Bearish regime:
• Price closes below the lower ATR expansion band
I added and modified the upper and lower bands along with dots for extreme conditions.
Original code: https://www.tradingview.com/script/xN8JwiZI-RMA-ATR-Bands/
Here is /MES on the 10 minute chart.
Code:
# RMA_ATR_Bands
# Inspired and converted from Pine Script by SchizoQuant https://www.tradingview.com/v/xN8JwiZI/
# Converted and modified by Chewie 6/4/2026
declare upper;
# ─── USER INPUTS ───────────────────────────────────────────────────────────────
input alerts = yes;
input maSrc = FundamentalType.HIGH; # RMA source (HIGH matches Pine default)
input maLength = 14; # RMA length
input atrLength = 13; # ATR length
input upperMult = 0.4; # Upper ATR multiplier
input upperMult2 = 1.6; # Upper ATR multiplier
input upperMult3 = 3.0; # Upper ATR multiplier
input lowerMult = 1.6; # Lower ATR multiplier
input lowerMult2 = 3.0; # Lower ATR multiplier
input showATRBands = yes; # Show ATR bands
input colorBars = yes; # Color price bars
input dots = yes;
input showSignals = yes; # Show long/short signals
input showBubble = no; # Show long/short signals
# ─── SOURCE ────────────────────────────────────────────────────────────────────
def src = Fundamental(maSrc);
# ─── RMA (Wilder's Moving Average) ─────────────────────────────────────────────
def ma = WildersSmoothing(src, maLength);
# ─── ATR BANDS ─────────────────────────────────────────────────────────────────
def atr = Average(TrueRange(high, close, low), atrLength);
def upperLine = ma + atr * upperMult;
def upperLine2 = ma + atr * upperMult2;
def upperLine3 = ma + atr * upperMult3;
def lowerLine = ma - atr * lowerMult;
def lowerLine2 = ma - atr * lowerMult2;
# ─── TREND LOGIC ───────────────────────────────────────────────────────────────
def isLong = close > upperLine;
def isShort = close < lowerLine;
def trend;
if isLong {
trend = 1;
} else if isShort {
trend = -1;
} else {
trend = trend[1]; # hold previous state (matches Pine's var int)
}
def longSignal = trend == 1 and trend[1] != 1;
def shortSignal = trend == -1 and trend[1] != -1;
# ─── COLORS ────────────────────────────────────────────────────────────────────
DefineGlobalColor("Long", CreateColor(57, 255, 20));
DefineGlobalColor("Short", CreateColor(138, 43, 226));
DefineGlobalColor("Neutral", Color.GRAY);
# ─── PLOTS ─────────────────────────────────────────────────────────────────────
plot RMALine = ma;
RMALine.SetLineWeight(2);
RMALine.AssignValueColor(
if trend == 1 then GlobalColor("Long")
else if trend == -1 then GlobalColor("Short")
else GlobalColor("Neutral")
);
RMALine.SetDefaultColor(Color.GRAY);
plot UpperBand = if showATRBands then upperLine else Double.NaN;
UpperBand.SetLineWeight(1);
UpperBand.AssignValueColor(
if trend == 1 then GlobalColor("Long")
else if trend == -1 then GlobalColor("Short")
else GlobalColor("Neutral")
);
UpperBand.SetDefaultColor(Color.GRAY);
plot UpperBand2 = if showATRBands then upperLine2 else Double.NaN;
UpperBand2.SetLineWeight(1);
UpperBand2.AssignValueColor(
if trend == 1 then GlobalColor("Long")
else if trend == -1 then GlobalColor("Short")
else GlobalColor("Neutral")
);
UpperBand2.SetDefaultColor(Color.GRAY);
plot UpperBand3 = if showATRBands then upperLine3 else Double.NaN;
UpperBand3.SetLineWeight(1);
UpperBand3.AssignValueColor(
if trend == 1 then GlobalColor("Long")
else if trend == -1 then GlobalColor("Short")
else GlobalColor("Neutral")
);
UpperBand3.SetDefaultColor(Color.GRAY);
plot LowerBand = if showATRBands then lowerLine else Double.NaN;
LowerBand.SetLineWeight(1);
LowerBand.AssignValueColor(
if trend == 1 then GlobalColor("Long")
else if trend == -1 then GlobalColor("Short")
else GlobalColor("Neutral")
);
#LowerBand.SetDefaultColor(Color.GRAY);
plot LowerBand2 = if showATRBands then lowerLine2 else Double.NaN;
LowerBand2.SetLineWeight(1);
LowerBand2.AssignValueColor(
if trend == 1 then GlobalColor("Long")
else if trend == -1 then GlobalColor("Short")
else GlobalColor("Neutral")
);
LowerBand2.SetDefaultColor(Color.GRAY);
# Fill between MA and bands — split by trend state for correct cloud color
# Upper cloud (MA to upperLine)
plot UpperLong = if showATRBands and trend == 1 then upperLine else Double.NaN;
plot UpperShort = if showATRBands and trend == -1 then upperLine else Double.NaN;
plot MARefUpper = if showATRBands then ma else Double.NaN;
MARefUpper.SetDefaultColor(Color.CURRENT);
MARefUpper.SetPaintingStrategy(PaintingStrategy.LINE);
MARefUpper.HideTitle();
MARefUpper.HideBubble();
AddCloud(UpperLong, MARefUpper, CreateColor(57, 255, 20), CreateColor(57, 255, 20));
AddCloud(UpperShort, MARefUpper, CreateColor(138, 43, 226), CreateColor(138, 43, 226));
AddCloud(Lowerband, Lowerband2, Color.dark_GRAY, Color.dark_GRAY);
# Lower cloud (lowerLine to MA)
plot MARefLower = if showATRBands then ma else Double.NaN;
MARefLower.SetDefaultColor(Color.CURRENT);
MARefLower.SetPaintingStrategy(PaintingStrategy.LINE);
MARefLower.HideTitle();
MARefLower.HideBubble();
AddCloud(upperlong, MARefLower, CreateColor(57, 255, 20), CreateColor(57, 255, 20));
AddCloud(MARefLower, UpperShort, CreateColor(138, 43, 226), CreateColor(138, 43, 226));
AddCloud(Upperband3, Upperband2, Color.dark_GRAY, Color.dark_GRAY);
# ─── SIGNALS ───────────────────────────────────────────────────────────────────
def longTrigger = trend == 1 and trend[1] != 1;
def shortTrigger = trend == -1 and trend[1] != -1;
plot LongArrow = if showSignals and longTrigger then 1 else 0;
LongArrow.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
LongArrow.SetDefaultColor(color.white);
LongArrow.SetLineWeight(4);
plot ShortArrow = if showSignals and shortTrigger then 1 else 0;
ShortArrow.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);
ShortArrow.SetDefaultColor(color.white);
ShortArrow.SetLineWeight(4);
# Signal labels
AddChartBubble(showBubble and longSignal, low, "LONG", GlobalColor("Long"), no);
AddChartBubble(showBubble and shortSignal, high, "SHORT", GlobalColor("Short"), yes);
# Dots #
plot BUY = if low < Lowerband2 then low - ATR(60) / 2 else Double.NaN;
BUY.SetPaintingStrategy(PaintingStrategy.POINTS);
BUY.SetDefaultColor(Color.WHITE);
BUY.SetLineWeight(1);
plot SELL = if high > UpperBand3 then high + ATR(60) / 2 else Double.NaN;
SELL.SetPaintingStrategy(PaintingStrategy.POINTS);
SELL.SetDefaultColor(Color.WHITE);
SELL.SetLineWeight(1);
# ─── BAR COLORING ──────────────────────────────────────────────────────────────
AssignPriceColor(
if !colorBars then Color.CURRENT
else if trend == 1 then GlobalColor("Long")
else if trend == -1 then GlobalColor("Short")
else GlobalColor("Neutral")
);
# ─── ALERTS ────────────────────────────────────────────────────────────────────
Alert(alerts and longSignal, "RMA ATR Bands Long Signal", Alert.BAR, Sound.Ding);
Alert(alerts and shortSignal, "RMA ATR Bands Short Signal", Alert.BAR, Sound.Bell);