MAD Volatility Trail [BackQuant]
Overview
MAD Volatility Trail is a robust trend-following overlay built from a rolling median and Median Absolute Deviation rather than a conventional moving average and standard deviation.
The indicator estimates a central price using the rolling median, measures how widely recent prices are distributed around that median using MAD, converts that dispersion into adaptive upper and lower bands, and then transforms those bands into one-sided trailing boundaries.
Original concept: https://www.tradingview.com/script/H9JdI5rn-MAD-Volatility-Trail-BackQuant/
Trading Note: I've noticed that when price gets to the line, there is a big move in either direction. That is a good time to place a straddle option strategy.
Here is an hourly chart of /NQ
Overview
MAD Volatility Trail is a robust trend-following overlay built from a rolling median and Median Absolute Deviation rather than a conventional moving average and standard deviation.
The indicator estimates a central price using the rolling median, measures how widely recent prices are distributed around that median using MAD, converts that dispersion into adaptive upper and lower bands, and then transforms those bands into one-sided trailing boundaries.
Original concept: https://www.tradingview.com/script/H9JdI5rn-MAD-Volatility-Trail-BackQuant/
Trading Note: I've noticed that when price gets to the line, there is a big move in either direction. That is a good time to place a straddle option strategy.
Here is an hourly chart of /NQ
Code:
# MAD_Volatility_Trail
# Original concept: https://www.tradingview.com/script/H9JdI5rn-MAD-Volatility-Trail-BackQuant/
# Converted by Chewie 8/29/2026
declare upper;
# ──────────────────────────────────────────────
# INPUTS
# ──────────────────────────────────────────────
input src = close;
input madLen = 45;
input madScale = 1.4655;
input factor = 1.15;
input useAtrFloor = no;
input atrLen = 14;
input atrFloorMult = 0.2;
input useSlopeConfirm = no;
input slopeLen = 2;
input triggerClose = yes;
input breakTrailOnFlip = yes;
input showTrail = yes;
input showMedian = no;
input showBands = no;
input showFill = yes;
input showGlow = yes;
input showSig = yes;
input paintBar = yes;
DefineGlobalColor("Bull", Color.GREEN);
DefineGlobalColor("Bear", Color.RED);
DefineGlobalColor("Median", Color.WHITE);
DefineGlobalColor("GradL1", CreateColor(0, 200, 0));
DefineGlobalColor("GradL2", CreateColor(0, 170, 0));
DefineGlobalColor("GradL3", CreateColor(0, 130, 0));
DefineGlobalColor("GradL4", CreateColor(0, 90, 0));
DefineGlobalColor("GradL5", CreateColor(0, 55, 0));
DefineGlobalColor("GradS1", CreateColor(200, 0, 0));
DefineGlobalColor("GradS2", CreateColor(170, 0, 0));
DefineGlobalColor("GradS3", CreateColor(130, 0, 0));
DefineGlobalColor("GradS4", CreateColor(90, 0, 0));
DefineGlobalColor("GradS5", CreateColor(55, 0, 0));
DefineGlobalColor("GlowBull", CreateColor(0, 255, 0));
DefineGlobalColor("GlowBear", CreateColor(255, 0, 0));
DefineGlobalColor("BloomBull", CreateColor(0, 200, 0));
DefineGlobalColor("BloomBear", CreateColor(200, 0, 0));
# ──────────────────────────────────────────────
# MAD CALCULATION
# ──────────────────────────────────────────────
def medianValue = Median(src, madLen);
def absDev = AbsValue(src - medianValue);
def rawMad = Median(absDev, madLen);
def robustDeviation = rawMad * madScale;
def madWidth = robustDeviation * factor;
def atrVal = WildersAverage(TrueRange(high, close, low), atrLen);
def atrFloorAmt = atrVal * atrFloorMult;
def bandWidth = if useAtrFloor then Max(madWidth, atrFloorAmt) else madWidth;
def rawUpper = medianValue + bandWidth;
def rawLower = medianValue - bandWidth;
# ──────────────────────────────────────────────
# TRIGGER
# ──────────────────────────────────────────────
def trigger = if triggerClose then close else src;
# ──────────────────────────────────────────────
# TRAILING BANDS
# ──────────────────────────────────────────────
def trailLower = CompoundValue(1,
if !IsNaN(trailLower[1]) and trigger[1] > trailLower[1]
then Max(rawLower, trailLower[1])
else rawLower,
rawLower);
def trailUpper = CompoundValue(1,
if !IsNaN(trailUpper[1]) and trigger[1] < trailUpper[1]
then Min(rawUpper, trailUpper[1])
else rawUpper,
rawUpper);
# ──────────────────────────────────────────────
# SLOPE CONFIRMATION
# ──────────────────────────────────────────────
def bullSlopePass = if !useSlopeConfirm then 1 else if medianValue > medianValue[slopeLen] then 1 else 0;
def bearSlopePass = if !useSlopeConfirm then 1 else if medianValue < medianValue[slopeLen] then 1 else 0;
# ──────────────────────────────────────────────
# TREND STATE
# ──────────────────────────────────────────────
def trend = CompoundValue(1,
if trend[1] == 0 and !IsNaN(medianValue) then
if trigger >= medianValue then 1 else -1
else if trigger > trailUpper and trend[1] != 1 and bullSlopePass then 1
else if trigger < trailLower and trend[1] != -1 and bearSlopePass then -1
else trend[1],
0);
def bullFlip = trend == 1 and trend[1] == -1;
def bearFlip = trend == -1 and trend[1] == 1;
def trendFlip = bullFlip or bearFlip;
def trendTrail = if trend == 1 then trailLower
else if trend == -1 then trailUpper
else Double.NaN;
def plottedTrail = if breakTrailOnFlip and trendFlip then Double.NaN else trendTrail;
# ──────────────────────────────────────────────
# VISUAL STRENGTH
# ──────────────────────────────────────────────
def trailDistance = if !IsNaN(trendTrail) then AbsValue(close - trendTrail) else 0.0;
def distanceStrength = if bandWidth > 0 then Min(trailDistance / bandWidth, 2.0) / 2.0 else 0.0;
def medianSlope = AbsValue(medianValue - medianValue[slopeLen]);
def slopeStrength = if bandWidth > 0 then Min(medianSlope / bandWidth, 1.0) else 0.0;
def trendStrength = Min(distanceStrength * 0.70 + slopeStrength * 0.30, 1.0);
def barsSinceFlip = if trendFlip then 0
else if IsNaN(barsSinceFlip[1]) then 100000
else barsSinceFlip[1] + 1;
def bloomStrength = if barsSinceFlip == 0 then 1.0
else if barsSinceFlip == 1 then 0.55
else if barsSinceFlip == 2 then 0.25
else 0.0;
# ──────────────────────────────────────────────
# GRADIENT REFERENCE VALUES
# ──────────────────────────────────────────────
def fillReady = if showTrail and showFill and !IsNaN(plottedTrail) then 1 else 0;
def isBull = trend == 1;
def grad1 = trendTrail + (close - trendTrail) * 0.15;
def grad2 = trendTrail + (close - trendTrail) * 0.35;
def grad3 = trendTrail + (close - trendTrail) * 0.60;
def grad4 = trendTrail + (close - trendTrail) * 0.82;
# ──────────────────────────────────────────────
# GLOW / BLOOM VALUES
# ──────────────────────────────────────────────
def atr14 = WildersAverage(TrueRange(high, close, low), 14);
def glowAmt = atr14 * (0.045 + trendStrength * 0.025);
def outerGlow = glowAmt * 2.3;
def glowReady = if showTrail and showGlow and !IsNaN(plottedTrail) then 1 else 0;
def bloomWidth = atr14 * (0.12 + bloomStrength * 0.08);
def bloomReady = if showTrail and showGlow and bloomStrength > 0 and !IsNaN(trendTrail) then 1 else 0;
# ──────────────────────────────────────────────
# TRAIL PLOT
# ──────────────────────────────────────────────
plot TrailLine = if showTrail then plottedTrail else Double.NaN;
TrailLine.SetLineWeight(3);
TrailLine.AssignValueColor(if trend == 1 then GlobalColor("Bull") else GlobalColor("Bear"));
TrailLine.SetStyle(Curve.FIRM);
# ──────────────────────────────────────────────
# MEDIAN & RAW BANDS
# ──────────────────────────────────────────────
plot MedianLine = if showMedian then medianValue else Double.NaN;
MedianLine.SetDefaultColor(GlobalColor("Median"));
MedianLine.SetLineWeight(1);
plot UpperBand = if showBands then rawUpper else Double.NaN;
UpperBand.SetDefaultColor(Color.GRAY);
UpperBand.SetLineWeight(1);
plot LowerBand = if showBands then rawLower else Double.NaN;
LowerBand.SetDefaultColor(Color.GRAY);
LowerBand.SetLineWeight(1);
# ──────────────────────────────────────────────
# BULL GRADIENT PLOTS & CLOUDS
# ──────────────────────────────────────────────
plot BullTrail = if fillReady and isBull then trendTrail else Double.NaN;
BullTrail.Hide();
plot BullGrad1 = if fillReady and isBull then grad1 else Double.NaN;
BullGrad1.Hide();
plot BullGrad2 = if fillReady and isBull then grad2 else Double.NaN;
BullGrad2.Hide();
plot BullGrad3 = if fillReady and isBull then grad3 else Double.NaN;
BullGrad3.Hide();
plot BullGrad4 = if fillReady and isBull then grad4 else Double.NaN;
BullGrad4.Hide();
plot BullPrice = if fillReady and isBull then close else Double.NaN;
BullPrice.Hide();
AddCloud(BullGrad1, BullTrail, GlobalColor("GradL1"), GlobalColor("GradL2"));
AddCloud(BullGrad2, BullGrad1, GlobalColor("GradL2"), GlobalColor("GradL3"));
AddCloud(BullGrad3, BullGrad2, GlobalColor("GradL3"), GlobalColor("GradL4"));
AddCloud(BullGrad4, BullGrad3, GlobalColor("GradL4"), GlobalColor("GradL5"));
AddCloud(BullPrice, BullGrad4, GlobalColor("GradL5"), GlobalColor("GradL5"));
# ──────────────────────────────────────────────
# BEAR GRADIENT PLOTS & CLOUDS
# ──────────────────────────────────────────────
plot BearTrail = if fillReady and !isBull then trendTrail else Double.NaN;
BearTrail.Hide();
plot BearGrad1 = if fillReady and !isBull then grad1 else Double.NaN;
BearGrad1.Hide();
plot BearGrad2 = if fillReady and !isBull then grad2 else Double.NaN;
BearGrad2.Hide();
plot BearGrad3 = if fillReady and !isBull then grad3 else Double.NaN;
BearGrad3.Hide();
plot BearGrad4 = if fillReady and !isBull then grad4 else Double.NaN;
BearGrad4.Hide();
plot BearPrice = if fillReady and !isBull then close else Double.NaN;
BearPrice.Hide();
AddCloud(BearTrail, BearGrad1, GlobalColor("GradS1"), GlobalColor("GradS2"));
AddCloud(BearGrad1, BearGrad2, GlobalColor("GradS2"), GlobalColor("GradS3"));
AddCloud(BearGrad2, BearGrad3, GlobalColor("GradS3"), GlobalColor("GradS4"));
AddCloud(BearGrad3, BearGrad4, GlobalColor("GradS4"), GlobalColor("GradS5"));
AddCloud(BearGrad4, BearPrice, GlobalColor("GradS5"), GlobalColor("GradS5"));
# ──────────────────────────────────────────────
# BULL GLOW PLOTS & CLOUDS
# ──────────────────────────────────────────────
plot BullGlowOL = if glowReady and isBull then trendTrail - outerGlow else Double.NaN;
BullGlowOL.Hide();
plot BullGlowOU = if glowReady and isBull then trendTrail + outerGlow else Double.NaN;
BullGlowOU.Hide();
plot BullGlowL = if glowReady and isBull then trendTrail - glowAmt else Double.NaN;
BullGlowL.Hide();
plot BullGlowU = if glowReady and isBull then trendTrail + glowAmt else Double.NaN;
BullGlowU.Hide();
AddCloud(BullGlowOU, BullGlowOL, GlobalColor("GlowBull"), GlobalColor("GlowBull"));
AddCloud(BullGlowU, BullGlowL, GlobalColor("GlowBull"), GlobalColor("GlowBull"));
# ──────────────────────────────────────────────
# BEAR GLOW PLOTS & CLOUDS
# ──────────────────────────────────────────────
plot BearGlowOL = if glowReady and !isBull then trendTrail - outerGlow else Double.NaN;
BearGlowOL.Hide();
plot BearGlowOU = if glowReady and !isBull then trendTrail + outerGlow else Double.NaN;
BearGlowOU.Hide();
plot BearGlowL = if glowReady and !isBull then trendTrail - glowAmt else Double.NaN;
BearGlowL.Hide();
plot BearGlowU = if glowReady and !isBull then trendTrail + glowAmt else Double.NaN;
BearGlowU.Hide();
AddCloud(BearGlowOU, BearGlowOL, GlobalColor("GlowBear"), GlobalColor("GlowBear"));
AddCloud(BearGlowU, BearGlowL, GlobalColor("GlowBear"), GlobalColor("GlowBear"));
# ──────────────────────────────────────────────
# BLOOM PLOTS & CLOUDS
# ──────────────────────────────────────────────
plot BullBloomL = if bloomReady and isBull then trendTrail - bloomWidth else Double.NaN;
BullBloomL.Hide();
plot BullBloomH = if bloomReady and isBull then trendTrail + bloomWidth else Double.NaN;
BullBloomH.Hide();
plot BearBloomL = if bloomReady and !isBull then trendTrail - bloomWidth else Double.NaN;
BearBloomL.Hide();
plot BearBloomH = if bloomReady and !isBull then trendTrail + bloomWidth else Double.NaN;
BearBloomH.Hide();
AddCloud(BullBloomH, BullBloomL, GlobalColor("BloomBull"), GlobalColor("BloomBull"));
AddCloud(BearBloomH, BearBloomL, GlobalColor("BloomBear"), GlobalColor("BloomBear"));
# ──────────────────────────────────────────────
# CANDLE COLORING
# ──────────────────────────────────────────────
AssignPriceColor(
if !paintBar then Color.CURRENT
else if trend == 1 then GlobalColor("Bull")
else GlobalColor("Bear")
);
# ──────────────────────────────────────────────
# SIGNALS
# ──────────────────────────────────────────────
plot BullSignal = if showSig and bullFlip then trendTrail else Double.NaN;
BullSignal.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
BullSignal.SetDefaultColor(GlobalColor("Bull"));
BullSignal.SetLineWeight(3);
plot BearSignal = if showSig and bearFlip then trendTrail else Double.NaN;
BearSignal.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);
BearSignal.SetDefaultColor(GlobalColor("Bear"));
BearSignal.SetLineWeight(3);