RMA ATR Bands for ThinkorSwim

chewie76

Well-known member
VIP
VIP Enthusiast
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.

1780601012472.png


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);
 

Join useThinkScript to post your question to a community of 21,000+ developers and traders.

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
2121 Online
Create Post

Similar threads

Similar threads

The Market Trading Game Changer

Join 2,500+ subscribers inside the useThinkScript VIP Membership Club
  • Exclusive indicators
  • Proven strategies & setups
  • Private Discord community
  • ‘Buy The Dip’ signal alerts
  • Exclusive members-only content
  • Add-ons and resources
  • 1 full year of unlimited support

Frequently Asked Questions

What is useThinkScript?

useThinkScript is the #1 community of stock market investors using indicators and other tools to power their trading strategies. Traders of all skill levels use our forums to learn about scripting and indicators, help each other, and discover new ways to gain an edge in the markets.

How do I get started?

We get it. Our forum can be intimidating, if not overwhelming. With thousands of topics, tens of thousands of posts, our community has created an incredibly deep knowledge base for stock traders. No one can ever exhaust every resource provided on our site.

If you are new, or just looking for guidance, here are some helpful links to get you started.

What are the benefits of VIP Membership?
VIP members get exclusive access to these proven and tested premium indicators: Buy the Dip, Advanced Market Moves 2.0, Take Profit, and Volatility Trading Range. In addition, VIP members get access to over 50 VIP-only custom indicators, add-ons, and strategies, private VIP-only forums, private Discord channel to discuss trades and strategies in real-time, customer support, trade alerts, and much more. Learn all about VIP membership here.
How can I access the premium indicators?
To access the premium indicators, which are plug and play ready, sign up for VIP membership here.
Back
Top