Uptrick Liquid Reversal Bands for ThinkorSwim was converted from this original source.
https://www.tradingview.com/script/NkOJyPWb-Uptrick-Liquid-Reversal-Bands/
Liquid Reversal Bands is an overlay indicator designed to help traders identify dynamic support and resistance zones, detect mean-reversion opportunities, and read price position within a volatility-aware envelope. Rather than using fixed standard deviation bands around a single moving average, this system builds its band width from multiple volatility components simultaneously, creating a more adaptive and stable envelope that responds to changing market conditions without overreacting to short-term noise. The candle coloring, fair value line, and band fills all carry live visual information, making it possible to assess market state and recent signal context at a glance without needing additional tools on the chart.
https://www.tradingview.com/script/NkOJyPWb-Uptrick-Liquid-Reversal-Bands/
Liquid Reversal Bands is an overlay indicator designed to help traders identify dynamic support and resistance zones, detect mean-reversion opportunities, and read price position within a volatility-aware envelope. Rather than using fixed standard deviation bands around a single moving average, this system builds its band width from multiple volatility components simultaneously, creating a more adaptive and stable envelope that responds to changing market conditions without overreacting to short-term noise. The candle coloring, fair value line, and band fills all carry live visual information, making it possible to assess market state and recent signal context at a glance without needing additional tools on the chart.
Code:
#// Uptrick_Liquid_Reversal_Bands
#// Original concept from https://www.tradingview.com/script/NkOJyPWb-Uptrick-Liquid-Reversal-Bands/
#// Converted and modified by Chewie 7/11/2026
declare upper;
#=== Inputs ===
input src = close;
input fairLen = 50;
input zLen = 100;
input smoothLen = 18;
input upperMult = 2.4;
input lowerMult = 2.4;
input outerUpperMult = 1.45;
input outerLowerMult = 1.45;
input colorbar = yes;
input enableSignals = yes;
input cooldownBars = 0;
input candleMode = {default ReversalHeat, LatestSignal};
input showOuterBands = yes;
input lineSlopeLen = 5;
input lineSlopeSensitivity = 1.25;
#=== Fixed palette (matches original hex colors) ===
def bullR = 92; def bullG = 240; def bullB = 215;
def bearR = 179; def bearG = 42; def bearB = 195;
#=== ALMA (Arnaud Legoux Moving Average) for Fair Value ===
def almaOffset = 0.85;
def almaSigma = 6.0;
def m = almaOffset * (fairLen - 1);
def s = fairLen / almaSigma;
def wSum = fold wi = 0 to fairLen with ws = 0 do
ws + Exp(-1 * Power(wi - m, 2) / (2 * Power(s, 2)));
def wPriceSum = fold pi = 0 to fairLen with wps = 0 do
wps + GetValue(src, fairLen - 1 - pi) * Exp(-1 * Power(pi - m, 2) / (2 * Power(s, 2)));
def almaFair = wPriceSum / wSum;
#=== Liquid Fair Value ===
def emaFair = ExpAverage(src, fairLen);
def fairRaw = emaFair * 0.55 + almaFair * 0.45;
def fairSmoothLen = Max(1, Floor(smoothLen / 2.0));
def fair = ExpAverage(fairRaw, fairSmoothLen);
#=== Liquid Band Width ===
def dev = src - fair;
def devStdev = StandardDeviation(dev, zLen);
def atrValue = WildersAverage(TrueRange(high, close, low), 14);
def absDev = ExpAverage(AbsValue(dev), zLen);
def rangeEnergy = ExpAverage(high - low, smoothLen);
def baseWidth = devStdev * 0.60 + atrValue * 0.25 + absDev * 0.10 + rangeEnergy * 0.05;
def width = ExpAverage(baseWidth, smoothLen);
def upperBand1 = fair + width * upperMult;
def lowerBand1 = fair - width * lowerMult;
def outerUpperBand1 = fair + width * upperMult * outerUpperMult;
def outerLowerBand1 = fair - width * lowerMult * outerLowerMult;
def upperbanda = (upperband1 - fair) /2 + fair;
def lowerbanda = fair - (upperband1 - fair) /2;
#=== Fair Value Line Slope Coloring ===
def fairSlopeRaw = fair - fair[1];
def fairSlopeAvg = ExpAverage(AbsValue(fairSlopeRaw), lineSlopeLen);
def fairSlopeNorm = if fairSlopeAvg != 0 then fairSlopeRaw / fairSlopeAvg else 0;
def fairSlopeSmooth = ExpAverage(fairSlopeNorm, lineSlopeLen);
def lineRatioRaw = 0.5 + fairSlopeSmooth / (2 * lineSlopeSensitivity);
def lineRatio = Min(1, Max(0, lineRatioRaw));
def lineR = bearR + (bullR - bearR) * lineRatio;
def lineG = bearG + (bullG - bearG) * lineRatio;
def lineB = bearB + (bullB - bearB) * lineRatio;
#=== Band / Fair Value Plots ===
plot UpperBand = upperBand1;
plot LowerBand = lowerBand1;
plot UpperBandi = upperBanda;
plot LowerBandi = lowerBanda;
plot FairValue = fair;
UpperBand.SetDefaultColor(Color.LIGHT_GRAY);
LowerBand.SetDefaultColor(Color.LIGHT_GRAY);
UpperBand.SetLineWeight(1);
LowerBand.SetLineWeight(1);
UpperBandi.SetDefaultColor(Color.GRAY);
LowerBandi.SetDefaultColor(Color.GRAY);
FairValue.AssignValueColor(CreateColor(lineR, lineG, lineB));
FairValue.SetLineWeight(4);
plot OuterUpperBand = if showOuterBands then outerUpperBand1 else Double.NaN;
plot OuterLowerBand = if showOuterBands then outerLowerBand1 else Double.NaN;
OuterUpperBand.SetDefaultColor(CreateColor(bearR, bearG, bearB));
OuterLowerBand.SetDefaultColor(CreateColor(bullR, bullG, bullB));
#=== Reversal Signals ===
def rawBuy = close[1] <= lowerBand1[1] and close > lowerBand1;
def rawSell = close[1] >= upperBand1[1] and close < upperBand1;
# self-referential cooldown counter (bars since last accepted signal)
def barsSinceSignal = CompoundValue(1,
if enableSignals and (rawBuy or rawSell) and (barsSinceSignal[1] >= cooldownBars)
then 0
else barsSinceSignal[1] + 1,
9999);
def barsOk = barsSinceSignal[1] >= cooldownBars;
def finalBuy = enableSignals and rawBuy and barsOk;
def finalSell = enableSignals and rawSell and barsOk;
def lastSignalState = CompoundValue(1,
if finalBuy then 1 else if finalSell then -1 else lastSignalState[1],
0);
#=== Candle Coloring ===
def bandRange = upperBand1 - lowerBand1;
def ratioRaw = if bandRange != 0 then (src - lowerBand1) / bandRange else 0.5;
def ratioClamped = Min(1, Max(0, if IsNaN(ratioRaw) then 0.5 else ratioRaw));
def heatR = bullR + (bearR - bullR) * ratioClamped;
def heatG = bullG + (bearG - bullG) * ratioClamped;
def heatB = bullB + (bearB - bullB) * ratioClamped;
def candleR = if candleMode == candleMode.LatestSignal
then (if lastSignalState == 1 then bullR else if lastSignalState == -1 then bearR else heatR)
else heatR;
def candleG = if candleMode == candleMode.LatestSignal
then (if lastSignalState == 1 then bullG else if lastSignalState == -1 then bearG else heatG)
else heatG;
def candleB = if candleMode == candleMode.LatestSignal
then (if lastSignalState == 1 then bullB else if lastSignalState == -1 then bearB else heatB)
else heatB;
AssignPriceColor(if colorbar then CreateColor(candleR, candleG, candleB) else color.current);
#=== Fills ===
AddCloud(UpperBand, UpperBandi, CreateColor(129, 20, 135), CreateColor(129, 20, 135));
AddCloud(LowerBandi, LowerBand, CreateColor(70, 180, 155), CreateColor(70, 180, 155));
AddCloud(OuterUpperBand, UpperBand, CreateColor(bearR, bearG, bearB), CreateColor(bearR, bearG, bearB));
AddCloud(LowerBand, OuterLowerBand, CreateColor(bullR, bullG, bullB), CreateColor(bullR, bullG, bullB));
#=== Buy / Sell Signal Arrows ===
plot BuySignal = if finalBuy then low - ATR(60) / 2 else Double.NaN;
BuySignal.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
BuySignal.SetDefaultColor(color.green); #CreateColor(bullR, bullG, bullB));
BuySignal.SetLineWeight(2);
plot SellSignal = if finalSell then high + ATR(60) / 2 else Double.NaN;
SellSignal.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);
SellSignal.SetDefaultColor(color.red); #CreateColor(bearR, bearG, bearB));
SellSignal.SetLineWeight(2);