If you're struggling with identifying trending markets, look no further than this ATR based trend average. This is designed to highlight reversal areas by displaying over extended price when it is beyond the bands. When overextended, the price will be either colored magenta or cyan. Yellow arrows indicate reversals. Customize the indicator in the settings.
Code:
# ---------------------------------------
# ATR_Trend Average
# Assembled by Chewie
# Notes:
# - Basis = EMA; Bands = EMA ± ATR * Multiplier (customizable)
# - Band + cloud colors shift by trend and intensify when price is outside
# - Yellow arrows when price "retests" a band after a recent breach
# ---------------------------------------
declare upper;
# ===== Inputs =====
input Colorbar = yes;
input showATRTREND = yes; # master on/off
input lengthEMA = 34; # basis length
input atrLength = 200; # ATR length
input atrMult = 3.5; # ATR multiplier
input lookbackRetestBars = 3; # how many bars to consider for "recent breach"
input requireCloseBackIn = yes; # require the close to be back inside the band for a retest signal
input showCloud = yes; # fill between bands
input showMidline = yes; # plot basis line
input showReversalSignals = yes; # yellow triangles
input showSlopeColorOnBand = yes; # color bands by slope when inside
input price = close; # price source
# Color customization
# These colors appear in the study settings so you can change them there.
DefineGlobalColor("BullInside", Color.GREEN);
DefineGlobalColor("BearInside", Color.RED);
DefineGlobalColor("BullOverext", Color.MAGENTA);
DefineGlobalColor("BearOverext", Color.CYAN);
DefineGlobalColor("MidlineUp", Color.CYAN);
DefineGlobalColor("MidlineDown", Color.MAGENTA);
DefineGlobalColor("CloudBull", Color.dark_GREEN);
DefineGlobalColor("CloudBear", Color.dark_RED);
# ===== Core calcs =====
def na = Double.NaN;
def basis = ExpAverage(price, lengthEMA);
def atr = Average(TrueRange(high, close, low), atrLength);
def upper = basis + atrMult * atr;
def lower = basis - atrMult * atr;
# Slope for color bias
def slope = basis - basis[1];
def upTrend = slope > 0;
def downTrend = slope < 0;
# ===== Band Plots =====
plot UpperBand = upper;
plot LowerBand = lower;
plot Midline = basis;
UpperBand.SetHiding(!showATRTREND);
LowerBand.SetHiding(!showATRTREND);
Midline.SetHiding(!showATRTREND or !showMidline);
UpperBand.SetLineWeight(2);
LowerBand.SetLineWeight(2);
Midline.SetLineWeight(2);
# Color logic for bands:
# - If price above upper -> intensified bullish color
# - If price below lower -> intensified bearish color
def aboveUpper = price > upper;
def belowLower = price < lower;
UpperBand.AssignValueColor(
if aboveUpper then GlobalColor("BullOverext")
else if showSlopeColorOnBand and upTrend then GlobalColor("BullInside")
else if showSlopeColorOnBand and downTrend then GlobalColor("BearInside")
else Color.GRAY
);
LowerBand.AssignValueColor(
if belowLower then GlobalColor("BearOverext")
else if showSlopeColorOnBand and upTrend then GlobalColor("BullInside")
else if showSlopeColorOnBand and downTrend then GlobalColor("BearInside")
else Color.GRAY
);
Midline.AssignValueColor(
if upTrend then GlobalColor("MidlineUp") else GlobalColor("MidlineDown")
);
# ===== Cloud between bands (ThinkScript-safe) =====
def showCloudNow = showATRTREND and showCloud;
# Masks so each cloud only renders in its regime
def upMask = showCloudNow and upTrend;
def dnMask = showCloudNow and downTrend;
# Bullish cloud
plot CloudUpperUp = if upMask then upper else Double.NaN;
plot CloudLowerUp = if upMask then lower else Double.NaN;
CloudUpperUp.SetDefaultColor(GlobalColor("CloudBull"));
CloudLowerUp.SetDefaultColor(GlobalColor("CloudBull"));
CloudUpperUp.SetHiding(!showCloudNow);
CloudLowerUp.SetHiding(!showCloudNow);
AddCloud(CloudUpperUp, CloudLowerUp, GlobalColor("CloudBull"), GlobalColor("CloudBull"));
# Bearish cloud
plot CloudUpperDn = if dnMask then upper else Double.NaN;
plot CloudLowerDn = if dnMask then lower else Double.NaN;
CloudUpperDn.SetDefaultColor(GlobalColor("CloudBear"));
CloudLowerDn.SetDefaultColor(GlobalColor("CloudBear"));
CloudUpperDn.SetHiding(!showCloudNow);
CloudLowerDn.SetHiding(!showCloudNow);
AddCloud(CloudUpperDn, CloudLowerDn, GlobalColor("CloudBear"), GlobalColor("CloudBear"));
# ===== Reversal "retest" logic =====
# Idea:
# 1) A recent breach outside band within lookbackRetestBars
# 2) A retest tag of the band after that breach
# 3) Optionally require the close to be back inside the envelope
#
# Bearish retest: price was above upper recently, then tags upper and (optionally) closes back below/inside.
# Bullish retest: price was below lower recently, then tags lower and (optionally) closes back above/inside.
def recentAbove = Highest(high > upper, lookbackRetestBars) > 0;
def recentBelow = Highest(low < lower, lookbackRetestBars) > 0;
# "Tag" = intrabar touch or cross of band
def tagUpper = high >= upper and low <= upper; # straddle/touch line
def tagLower = low <= lower and high >= lower;
# Back inside conditions
def backInsideFromUpper = if requireCloseBackIn then close <= upper and close >= lower else yes;
def backInsideFromLower = if requireCloseBackIn then close >= lower and close <= upper else yes;
# Reversal signals
def bearRetest = showATRTREND and showReversalSignals and recentAbove and tagUpper and backInsideFromUpper;
def bullRetest = showATRTREND and showReversalSignals and recentBelow and tagLower and backInsideFromLower;
plot BearReversal = bearRetest;
plot BullReversal = bullRetest;
BearReversal.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);
BearReversal.SetDefaultColor(Color.YELLOW);
BearReversal.SetLineWeight(2);
BullReversal.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
BullReversal.SetDefaultColor(Color.YELLOW);
BullReversal.SetLineWeight(2);
# Make sure arrows sit near band extremes
BearReversal.HideBubble();
BullReversal.HideBubble();
# ===== Optional: show small markers when price is outside (overextension) =====
input showOverextensionDots = no;
plot OverExtHigh = if showATRTREND and showOverextensionDots and aboveUpper then high else na;
plot OverExtLow = if showATRTREND and showOverextensionDots and belowLower then low else na;
OverExtHigh.SetPaintingStrategy(PaintingStrategy.POINTS);
OverExtLow.SetPaintingStrategy(PaintingStrategy.POINTS);
OverExtHigh.SetDefaultColor(GlobalColor("BULLOverext"));
OverExtLow.SetDefaultColor(GlobalColor("BEAROverext"));
OverExtHigh.SetLineWeight(3);
OverExtLow.SetLineWeight(3);
AssignPriceColor(if !ColorBar then Color.CURRENT else if belowLower then GlobalColor("bearOverext") else if aboveUpper then GlobalColor("bullOverext") else if upMask then GlobalColor("bullinside") else if dnMask then GlobalColor("Bearinside") else Color.dark_gray);