Moving Average Z-Score Suite [BackQuant] for ThinkOrSwim

samer800

Moderator - Expert
VIP
Lifetime
ZI1ydyC.png


Author MEssage:
This indicator transforms selected moving averages into a Z-Score oscillator, providing clear signals for potential buy and sell opportunities. The indicator includes options to choose from eleven different moving average types, each offering unique benefits and characteristics. It also provides additional features such as standard deviation levels, extreme levels, and divergence detection, enhancing its utility in various market conditions.

CODE:

CSS:
#// Indicator for TOS
#// © BackQuant
#indicator( title = "Moving Average Z-Score Suite [BackQuant]"
# Converted by Sam4Cok@Samer800    - 12/2024

declare lower;

input timeframe = AggregationPeriod.MIN;
input colorBars = yes;
input movAvgType = {"SMA", "Hull", "Ema", "Wma", "Dema", "RMA", "LINREG", "TEMA", "ALMA", default "Kalman Hull", "T3"};
input Source = FundamentalType.CLOSE; # "Calculation Source"
input length = 30;                    # "Calculation Period"
input ZScoreLookback = 30;            # "Z-Score Lookback Period"
input SigmaForAlma = 6;               # "Sigma for ALMA"
input measurementNoise = 3.0;         # "Measurement Noise"
input processNoise = 0.01;            # "Process Noise"
input showStandardLevels   = yes;     # "Show Standard Deviation Levels (0, 1, 2, -1, -2 Levels) ?"
input showExtremeLevels  = yes;       # "Show Extreme Levels ?"

def na = Double.NaN;
def last = IsNaN(close);
def cap = GetAggregationPeriod();
def tf = Max(cap, timeframe);
def src = Fundamental(FundamentalType = Source, Period = tf);
#-- Functions

Script t3 {
input source = close;
input length = 30;
input vf = 0.7;
    def ema1 = ExpAverage(source, length);
    def gd1  = ema1 * (1 + vf) - ExpAverage(ema1, length) * vf;
    def ema2 = ExpAverage(gd1, length);
    def gd2  = ema2 * (1 + vf) - ExpAverage(ema2, length) * vf;
    def ema3 = ExpAverage(gd2, length);
    def t3   = ema3 * (1 + vf) - ExpAverage(ema3, length) * vf;
    plot out = t3;
}
script ALMA {
  input Data = close;
  input Window = 9;
  input Offset = 0.0;
  input Sigma = 6;
    def m = (Offset * (Window - 1));
    def s = Window/Sigma;
    def SumVectorData = fold y = 0 to Window with WS do
         WS + Exp(-(sqr(y-m))/(2*sqr(s))) * getvalue(Data, (Window-1)-y);
    def SumVector = fold z = 0 to Window with CW do
         CW + Exp(-(sqr(z-m))/(2*sqr(s)));
 plot ALMA = SumVectorData / SumVector;
}
#// Kalman filter function
Script f_kalman {
input src = close;
input Noise = 3;
input process = 0.01;
input stateEst = close;
input errorCov = 1;
    def pse = if isNaN(stateEst) then src else if !stateEst then src else stateEst;
    def pec = CompoundValue(1, errorCov + process, 1);
    def kg = pec / (pec + Noise);
    def se = pse + kg * (src - pse);
    def ec = (1 - kg) * pec;
    plot stateEstimate = se;
    plot errorCovariance = ec;
}
#// Hull Moving Average Function with Kalman instead of Weighted Moving Average
Script KHMA {
input pricesource = close;
input measurementNoise = 3;
input processNoise = 0.01;
input length = 30;
    def len =  Round(Sqrt(length), 0);
    def se1; def ec1;
    def se0 = f_kalman(pricesource, measurementNoise, processNoise, se1[1], ec1[1]).stateEstimate;
    def ec0 = f_kalman(pricesource, measurementNoise, processNoise, se1[1], ec1[1]).errorCovariance;
        se1 = f_kalman(pricesource, measurementNoise, processNoise, se0, ec0).stateEstimate;
        ec1 = f_kalman(pricesource, measurementNoise, processNoise, se0, ec0).errorCovariance;
    def khma1 = f_kalman(pricesource, measurementNoise/2, processNoise, se0, ec0).stateEstimate;
    def khma2 = f_kalman(pricesource, measurementNoise, processNoise, se0, ec0).stateEstimate;
    def KHMA = f_kalman(2 * khma1 - khma2, len, processNoise, se0, ec0).stateEstimate;
    plot out = KHMA;
}

def subject;
Switch (movAvgType) {
Case "SMA" : subject = Average(src, length);
Case "Hull" : subject = HullMovingAvg(src, length);
Case "Ema" : subject = ExpAverage(src, length);
Case "Wma" : subject = WMA(src, length);
Case "Dema" : subject = DEMA(src, length);
Case "RMA" : subject = WildersAverage(src, length);
Case "LINREG" : subject = Inertia(src, length);
Case "TEMA" : subject = TEMA(src, length);
Case "ALMA" : subject = alma(src, length, 0, SigmaForAlma);
Case "T3" : subject = t3(src, length, 0.7);
Default: subject = KHMA(src, measurementNoise, processNoise, length);
}

def mean    = ExpAverage(subject, ZScoreLookback);
def stdDev  = stdev(subject, ZScoreLookback);
def zScore  = (subject - mean) / stdDev;

#// Conditional Color
def posroc = zScore > zScore[1];
def negroc = zScore < zScore[1];

def col = if zScore > 0 and posroc then 2 else
          if zScore > 0 and negroc then 1 else
          if zScore < 0 and negroc then -2 else
          if zScore < 0 and posroc then -1 else col[1];

#/ Adaptive Trend Strength Color
def trendStrength = AbsValue(zScore);
def maxStrength = 4.5;
def normalizedStrength = min(trendStrength / maxStrength * 100, 100);
def alphaValue = (100 - normalizedStrength);

#-- Zscore
plot demaZScore = zScore;
demaZScore.SetLineWeight(2);
demaZScore.SetPaintingStrategy(PaintingStrategy.HISTOGRAM);
demaZScore.AssignValueColor(if col == 2 then Color.CYAN else
                            if col == 1 then CreateColor(0, 100, 100) else
                            if col ==-2 then Color.MAGENTA else
                            if col ==-1 then Color.PLUM else Color.GRAY);

#----divergences
input showdivergences = no;
input LookBackRight  = 10; # "Pivot Lookback Right"
input LookBackLeft  = 10;  # "Pivot Lookback Left"

Script Pivot {
    input series    = hl2;
    input leftBars  = 10;
    input rightBars = 10;
    input isHigh = yes;
    def na = Double.NaN;
    def HH = series == Highest(series, leftBars + 1);
    def LL = series == Lowest(series, leftBars + 1);
    def pivotRange = (leftBars + rightBars + 1);
    def leftEdgeValue = if series[pivotRange] ==0 then na else series[pivotRange];
    def pvtCond = !isNaN(series) and leftBars > 0 and rightBars > 0 and !isNaN(leftEdgeValue);
    def barIndexH = if pvtCond then
                    fold i = 1 to rightBars + 1 with p=1 while p do
                    series > GetValue(series, - i) else na;
    def barIndexL = if pvtCond then
                    fold j = 1 to rightBars + 1 with q=1 while q do
                    series < GetValue(series, - j) else na;
    def PivotPoint;
if isHigh {
    PivotPoint = if HH and barIndexH then series else na;
    } else {
    PivotPoint = if LL and barIndexL then series else na;
    }
    plot pvt = PivotPoint;
}
#_inRange(cond) =>
script _inRange {
    input cond = yes;
        def bars = if cond then 0 else bars[1] + 1;
        def inrange =  (-80 <= bars) and (bars <= 80);
plot retrun = inRange;
}
def bar = bar[1] + 1;
def plFound = if isNaN(pivot(zScore, LookBackLeft, LookBackRight, no)[LookBackRight]) then no else yes;
def phFound = if isNaN(pivot(zScore, LookBackLeft, LookBackRight, yes)[LookBackRight]) then no else yes;

#-- Pvt Low
def vlFound; def vlFound1;
def plPrice; def plPrice1;
def lastPlBar; def prePlBar;
if plFound {
    vlFound = vlFound1[1];
    vlFound1  = zScore[LookBackRight];
    plPrice = plPrice1[1];
    plPrice1  = low(Period = tf)[LookBackRight];
    prePlBar = lastPlBar[1];
    lastPlBar = bar - LookBackRight;
    } else {
    vlFound1 = vlFound1[1];
    vlFound  = vlFound[1];
    plPrice1 = plPrice1[1];
    plPrice  = plPrice[1];
    prePlBar = prePlBar[1];
    lastPlBar = lastPlBar[1];
}
#-- Pvt High
def vhFound; def vhFound1;
def phPrice; def phPrice1;
def lastPhBar; def prePhBar;

if phFound {
    vhFound   = vhFound1[1];
    vhFound1  = zScore[LookBackRight];
    phPrice   = phPrice1[1];
    phPrice1  = high(Period = tf)[LookBackRight];
    prePhBar  = lastPhBar[1];
    lastPhBar = bar - LookBackRight;
    } else {
    vhFound1  = vhFound1[1];
    vhFound   = vhFound[1];
    phPrice1  = phPrice1[1];
    phPrice   = phPrice[1];
    prePhBar  = prePhBar[1];
    lastPhBar = lastPhBar[1];
}

#// Regular Bullish
def oscHL = zScore[LookBackRight] > vlFound and _inRange(plFound[1]);
def priceLL = low(Period = tf)[LookBackRight] < plPrice and zScore <= 0;
def bullCond = plFound and oscHL and priceLL;
#// Regular Bearish
def inRangePh = _inRange(phFound[1]);
def oscLH   = zScore[LookBackRight] < vhFound and inRangePh;
def priceHH = high(Period = tf)[LookBackRight] > phPrice and zScore >= 0;
def bearCond = phFound and oscLH and priceHH;

#------ Bubbles
def bullBub  = showdivergences and bullCond;
def bearBub  = showdivergences and bearCond;

addchartbubble(bullBub[-LookBackRight], zScore , "R", Color.CYAN, no);
addchartbubble(bearBub[-LookBackRight], zScore , "R", Color.MAGENTA, yes);

##### Lines

#-- Bear Line
def priorPHBar;
def lastBearBar;
if bearCond {
    priorPHBar  = prePhBar;
    lastBearBar =  bar - LookBackRight;
    } else {
    priorPHBar  = 0;
    lastBearBar = 0;
}
#-- Bull Line
def priorPLBar;
def lastBullBar;
if bullCond {
    priorPLBar  = prePlBar;
    lastBullBar = bar - LookBackRight;
    } else {
    priorPLBar  = 0;
    lastBullBar = 0;
    }

def pivotHigh = if bar == HighestAll(priorPHBar)  then zScore else
                if bar == HighestAll(lastBearBar) then zScore else na;
def pivotLow  = if bar == HighestAll(priorPLBar)  then zScore else
                if bar == HighestAll(lastBullBar) then zScore else na;


plot PlotHline = if showdivergences then pivotHigh else na;
PlotHline.EnableApproximation();
PlotHline.SetDefaultColor(Color.MAGENTA);

plot PlotLline = if showdivergences then pivotLow else na;
PlotLline.EnableApproximation();
PlotLline.SetDefaultColor(Color.CYAN);

#// Upper Extreme Levels
plot u1 = if showExtremeLevels and !last then 4 else na; #, "Upper",
plot u2 = if showExtremeLevels and !last then 3 else na;
u1.SetPaintingStrategy(PaintingStrategy.LINE_VS_POINTS);
u2.SetPaintingStrategy(PaintingStrategy.LINE_VS_POINTS);
u1.AssignValueColor(if zScore>= 0 then CreateColor(255 - alphaValue  * 2.55, 0, 0) else CreateColor(26, 0, 0));
u2.AssignValueColor(if zScore>= 0 then CreateColor(255 - alphaValue  * 2.55, 0, 0) else CreateColor(26, 0, 0));

AddCloud(u1 , u2, Color.DARK_RED); # "Extreme Upper"

#// Lower Extreme Levels
plot l1 = if showExtremeLevels and !last then -4 else na; #, "Lower"
plot l2 = if showExtremeLevels and !last then -3 else na;
l1.SetPaintingStrategy(PaintingStrategy.LINE_VS_POINTS);
l2.SetPaintingStrategy(PaintingStrategy.LINE_VS_POINTS);
l1.AssignValueColor(if zScore< 0 then CreateColor(0, 255- alphaValue  * 2.55, 0) else CreateColor(0, 26, 0));
l2.AssignValueColor(if zScore< 0 then CreateColor(0, 255- alphaValue  * 2.55, 0) else CreateColor(0, 26, 0));

AddCloud(l2,l1, Color.DARK_GREEN);

#// Plotting Hlines
plot "0" = if showStandardLevels and !last then 0 else na;
plot "1" = if showStandardLevels and !last then 1 else na;
plot "2" = if showStandardLevels and !last then 2 else na;
plot "-1" = if showStandardLevels and !last then -1 else na;
plot "-2" = if showStandardLevels and !last then -2  else na;

"0".SetPaintingStrategy(PaintingStrategy.DASHES);
"1".SetPaintingStrategy(PaintingStrategy.DASHES);
"-1".SetPaintingStrategy(PaintingStrategy.DASHES);
"0".SetDefaultColor(Color.DARK_GRAY);
"1".SetDefaultColor(Color.DARK_GRAY);
"2".SetDefaultColor(Color.DARK_GRAY);
"-1".SetDefaultColor(Color.DARK_GRAY);
"-2".SetDefaultColor(Color.DARK_GRAY);


#-- Bar Color

AssignPriceColor(if !colorBars then Color.CURRENT else
                 if col == 2 then Color.GREEN else
                 if col == 1 then Color.DARK_GREEN else
                 if col ==-2 then Color.RED else
                 if col ==-1 then Color.DARK_RED else Color.GRAY);


#-- END of CODE
 
Last edited by a moderator:

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

There are a lot of moving average options with this one. Definitely have to do some testing on them and see what looks best based on your trading style. I like the Hull Avg, 12 length and 15 z-score lookback. Thanks for converting!
I made a few additions. I added a yellow Hull average line and added white arrows when the z-score cross above or below the average line. Also added extreme dots when the z-score is over 2/-2. Below is example on /MNQ 1 hr. chart.

1734414197220.png


Code:
#// Indicator for TOS
#// © BackQuant
#indicator( title = "Moving Average Z-Score Suite [BackQuant]"
# Converted by Sam4Cok@Samer800    - 12/2024

declare lower;

input timeframe = AggregationPeriod.MIN;
input colorBars = yes;
input movAvgType = {"SMA", "Kalman Hull", "Ema", "Wma", "Dema", "RMA", "LINREG", "TEMA", "ALMA", default "Hull", "T3"};
input Source = FundamentalType.CLOSE; # "Calculation Source"
input length = 12;                    # 30 "Calculation Period"
input ZScoreLookback = 15;            # 30 "Z-Score Lookback Period"
input SigmaForAlma = 6;               # "Sigma for ALMA"
input measurementNoise = 3.0;         # "Measurement Noise"
input processNoise = 0.01;            # "Process Noise"
input showStandardLevels   = yes;     # "Show Standard Deviation Levels (0, 1, 2, -1, -2 Levels) ?"
input showExtremeLevels  = yes;       # "Show Extreme Levels ?"

def na = Double.NaN;
def last = IsNaN(close);
def cap = GetAggregationPeriod();
def tf = Max(cap, timeframe);
def src = Fundamental(FundamentalType = Source, Period = tf);
#-- Functions

Script t3 {
input source = close;
input length = 30;
input vf = 0.7;
    def ema1 = ExpAverage(source, length);
    def gd1  = ema1 * (1 + vf) - ExpAverage(ema1, length) * vf;
    def ema2 = ExpAverage(gd1, length);
    def gd2  = ema2 * (1 + vf) - ExpAverage(ema2, length) * vf;
    def ema3 = ExpAverage(gd2, length);
    def t3   = ema3 * (1 + vf) - ExpAverage(ema3, length) * vf;
    plot out = t3;
}
script ALMA {
  input Data = close;
  input Window = 9;
  input Offset = 0.0;
  input Sigma = 6;
    def m = (Offset * (Window - 1));
    def s = Window/Sigma;
    def SumVectorData = fold y = 0 to Window with WS do
         WS + Exp(-(sqr(y-m))/(2*sqr(s))) * getvalue(Data, (Window-1)-y);
    def SumVector = fold z = 0 to Window with CW do
         CW + Exp(-(sqr(z-m))/(2*sqr(s)));
 plot ALMA = SumVectorData / SumVector;
}
#// Kalman filter function
Script f_kalman {
input src = close;
input Noise = 3;
input process = 0.01;
input stateEst = close;
input errorCov = 1;
    def pse = if isNaN(stateEst) then src else if !stateEst then src else stateEst;
    def pec = CompoundValue(1, errorCov + process, 1);
    def kg = pec / (pec + Noise);
    def se = pse + kg * (src - pse);
    def ec = (1 - kg) * pec;
    plot stateEstimate = se;
    plot errorCovariance = ec;
}
#// Hull Moving Average Function with Kalman instead of Weighted Moving Average
Script KHMA {
input pricesource = close;
input measurementNoise = 3;
input processNoise = 0.01;
input length = 30;
    def len =  Round(Sqrt(length), 0);
    def se1; def ec1;
    def se0 = f_kalman(pricesource, measurementNoise, processNoise, se1[1], ec1[1]).stateEstimate;
    def ec0 = f_kalman(pricesource, measurementNoise, processNoise, se1[1], ec1[1]).errorCovariance;
        se1 = f_kalman(pricesource, measurementNoise, processNoise, se0, ec0).stateEstimate;
        ec1 = f_kalman(pricesource, measurementNoise, processNoise, se0, ec0).errorCovariance;
    def khma1 = f_kalman(pricesource, measurementNoise/2, processNoise, se0, ec0).stateEstimate;
    def khma2 = f_kalman(pricesource, measurementNoise, processNoise, se0, ec0).stateEstimate;
    def KHMA = f_kalman(2 * khma1 - khma2, len, processNoise, se0, ec0).stateEstimate;
    plot out = KHMA;
}

def subject;
Switch (movAvgType) {
Case "SMA" : subject = Average(src, length);
Case "Hull" : subject = HullMovingAvg(src, length);
Case "Ema" : subject = ExpAverage(src, length);
Case "Wma" : subject = WMA(src, length);
Case "Dema" : subject = DEMA(src, length);
Case "RMA" : subject = WildersAverage(src, length);
Case "LINREG" : subject = Inertia(src, length);
Case "TEMA" : subject = TEMA(src, length);
Case "ALMA" : subject = alma(src, length, 0, SigmaForAlma);
Case "T3" : subject = t3(src, length, 0.7);
Default: subject = KHMA(src, measurementNoise, processNoise, length);
}

def mean    = ExpAverage(subject, ZScoreLookback);
def stdDev  = stdev(subject, ZScoreLookback);
def zScore  = (subject - mean) / stdDev;

#// Conditional Color
def posroc = zScore > zScore[1];
def negroc = zScore < zScore[1];

def col = if zScore > 0 and posroc then 2 else
          if zScore > 0 and negroc then 1 else
          if zScore < 0 and negroc then -2 else
          if zScore < 0 and posroc then -1 else col[1];

#/ Adaptive Trend Strength Color
def trendStrength = AbsValue(zScore);
def maxStrength = 4.5;
def normalizedStrength = min(trendStrength / maxStrength * 100, 100);
def alphaValue = (100 - normalizedStrength);

# Moving Average
plot MOVAVG = MovingAverage( AverageType.hull, zscore, length);
movavg.setdefaultColor(color.yellow);

#-- Zscore
plot demaZScore = zScore;
demaZScore.SetLineWeight(2);
demaZScore.SetPaintingStrategy(PaintingStrategy.HISTOGRAM);
demaZScore.AssignValueColor(if col == 2 then Color.CYAN else
                            if col == 1 then CreateColor(0, 100, 100) else
                            if col ==-2 then Color.MAGENTA else
                            if col ==-1 then Color.PLUM else Color.GRAY);

#Extreme levels

plot buy =  if ZScore < -2 and zscore < zscore[1] then -3.5 else DOUBLE.naN;
buy.SetDefaultColor(Color.magenta);
buy.SetPaintingStrategy(PaintingStrategy.POINTS);
buy.setlineWeight(4);

plot buy1 =  if ZScore < -2 and zscore > zscore[1] then -3.5 else DOUBLE.naN;
buy1.SetDefaultColor(Color.plum);
buy1.SetPaintingStrategy(PaintingStrategy.POINTS);
buy1.setlineWeight(4);
 

plot sell =  if ZScore > 2 and zscore > zscore[1] then 3.5 else DOUBLE.naN;
sell.SetDefaultColor(Color.cyan);
sell.SetPaintingStrategy(PaintingStrategy.POINTS);
sell.setlineWeight(4);

plot sell1 =  if ZScore > 2 and zscore < zscore[1] then 3.5 else DOUBLE.naN;
sell1.SetDefaultColor(CreateColor(0, 100, 100));
sell1.SetPaintingStrategy(PaintingStrategy.POINTS);
sell1.setlineWeight(4);

# Signals
plot Crossup = if zscore crosses above movavg then -3 else double.nan;
plot Crossdn = if zscore crosses below movavg then 3 else double.nan;
Crossdn.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);
Crossdn.SetDefaultColor(Color.white);
Crossup.SetPaintingStrategy(PaintingStrategy.ARROW_up);
Crossup.SetDefaultColor(Color.white);


#----divergences
input showdivergences = YES;
input LookBackRight  = 10; # "Pivot Lookback Right"
input LookBackLeft  = 10;  # "Pivot Lookback Left"

Script Pivot {
    input series    = hl2;
    input leftBars  = 10;
    input rightBars = 10;
    input isHigh = yes;
    def na = Double.NaN;
    def HH = series == Highest(series, leftBars + 1);
    def LL = series == Lowest(series, leftBars + 1);
    def pivotRange = (leftBars + rightBars + 1);
    def leftEdgeValue = if series[pivotRange] ==0 then na else series[pivotRange];
    def pvtCond = !isNaN(series) and leftBars > 0 and rightBars > 0 and !isNaN(leftEdgeValue);
    def barIndexH = if pvtCond then
                    fold i = 1 to rightBars + 1 with p=1 while p do
                    series > GetValue(series, - i) else na;
    def barIndexL = if pvtCond then
                    fold j = 1 to rightBars + 1 with q=1 while q do
                    series < GetValue(series, - j) else na;
    def PivotPoint;
if isHigh {
    PivotPoint = if HH and barIndexH then series else na;
    } else {
    PivotPoint = if LL and barIndexL then series else na;
    }
    plot pvt = PivotPoint;
}
#_inRange(cond) =>
script _inRange {
    input cond = yes;
        def bars = if cond then 0 else bars[1] + 1;
        def inrange =  (-80 <= bars) and (bars <= 80);
plot retrun = inRange;
}
def bar = bar[1] + 1;
def plFound = if isNaN(pivot(zScore, LookBackLeft, LookBackRight, no)[LookBackRight]) then no else yes;
def phFound = if isNaN(pivot(zScore, LookBackLeft, LookBackRight, yes)[LookBackRight]) then no else yes;

#-- Pvt Low
def vlFound; def vlFound1;
def plPrice; def plPrice1;
def lastPlBar; def prePlBar;
if plFound {
    vlFound = vlFound1[1];
    vlFound1  = zScore[LookBackRight];
    plPrice = plPrice1[1];
    plPrice1  = low(Period = tf)[LookBackRight];
    prePlBar = lastPlBar[1];
    lastPlBar = bar - LookBackRight;
    } else {
    vlFound1 = vlFound1[1];
    vlFound  = vlFound[1];
    plPrice1 = plPrice1[1];
    plPrice  = plPrice[1];
    prePlBar = prePlBar[1];
    lastPlBar = lastPlBar[1];
}
#-- Pvt High
def vhFound; def vhFound1;
def phPrice; def phPrice1;
def lastPhBar; def prePhBar;

if phFound {
    vhFound   = vhFound1[1];
    vhFound1  = zScore[LookBackRight];
    phPrice   = phPrice1[1];
    phPrice1  = high(Period = tf)[LookBackRight];
    prePhBar  = lastPhBar[1];
    lastPhBar = bar - LookBackRight;
    } else {
    vhFound1  = vhFound1[1];
    vhFound   = vhFound[1];
    phPrice1  = phPrice1[1];
    phPrice   = phPrice[1];
    prePhBar  = prePhBar[1];
    lastPhBar = lastPhBar[1];
}

#// Regular Bullish
def oscHL = zScore[LookBackRight] > vlFound and _inRange(plFound[1]);
def priceLL = low(Period = tf)[LookBackRight] < plPrice and zScore <= 0;
def bullCond = plFound and oscHL and priceLL;
#// Regular Bearish
def inRangePh = _inRange(phFound[1]);
def oscLH   = zScore[LookBackRight] < vhFound and inRangePh;
def priceHH = high(Period = tf)[LookBackRight] > phPrice and zScore >= 0;
def bearCond = phFound and oscLH and priceHH;

#------ Bubbles
def bullBub  = showdivergences and bullCond;
def bearBub  = showdivergences and bearCond;

addchartbubble(bullBub[-LookBackRight], zScore , "R", Color.CYAN, no);
addchartbubble(bearBub[-LookBackRight], zScore , "R", Color.MAGENTA, yes);

##### Lines

#-- Bear Line
def priorPHBar;
def lastBearBar;
if bearCond {
    priorPHBar  = prePhBar;
    lastBearBar =  bar - LookBackRight;
    } else {
    priorPHBar  = 0;
    lastBearBar = 0;
}
#-- Bull Line
def priorPLBar;
def lastBullBar;
if bullCond {
    priorPLBar  = prePlBar;
    lastBullBar = bar - LookBackRight;
    } else {
    priorPLBar  = 0;
    lastBullBar = 0;
    }

def pivotHigh = if bar == HighestAll(priorPHBar)  then zScore else
                if bar == HighestAll(lastBearBar) then zScore else na;
def pivotLow  = if bar == HighestAll(priorPLBar)  then zScore else
                if bar == HighestAll(lastBullBar) then zScore else na;


plot PlotHline = if showdivergences then pivotHigh else na;
PlotHline.EnableApproximation();
PlotHline.SetDefaultColor(Color.MAGENTA);

plot PlotLline = if showdivergences then pivotLow else na;
PlotLline.EnableApproximation();
PlotLline.SetDefaultColor(Color.CYAN);

#// Upper Extreme Levels
plot u1 = if showExtremeLevels and !last then 4 else na; #, "Upper",
plot u2 = if showExtremeLevels and !last then 3 else na;
u1.SetPaintingStrategy(PaintingStrategy.LINE_VS_POINTS);
u2.SetPaintingStrategy(PaintingStrategy.LINE_VS_POINTS);
u1.AssignValueColor(if zScore>= 0 then CreateColor(255 - alphaValue  * 2.55, 0, 0) else CreateColor(26, 0, 0));
u2.AssignValueColor(if zScore>= 0 then CreateColor(255 - alphaValue  * 2.55, 0, 0) else CreateColor(26, 0, 0));

AddCloud(u1 , u2, Color.DARK_RED); # "Extreme Upper"

#// Lower Extreme Levels
plot l1 = if showExtremeLevels and !last then -4 else na; #, "Lower"
plot l2 = if showExtremeLevels and !last then -3 else na;
l1.SetPaintingStrategy(PaintingStrategy.LINE_VS_POINTS);
l2.SetPaintingStrategy(PaintingStrategy.LINE_VS_POINTS);
l1.AssignValueColor(if zScore< 0 then CreateColor(0, 255- alphaValue  * 2.55, 0) else CreateColor(0, 26, 0));
l2.AssignValueColor(if zScore< 0 then CreateColor(0, 255- alphaValue  * 2.55, 0) else CreateColor(0, 26, 0));

AddCloud(l2,l1, Color.DARK_GREEN);

#// Plotting Hlines
plot "0" = if showStandardLevels and !last then 0 else na;
plot "1" = if showStandardLevels and !last then 1 else na;
plot "2" = if showStandardLevels and !last then 2 else na;
plot "-1" = if showStandardLevels and !last then -1 else na;
plot "-2" = if showStandardLevels and !last then -2  else na;

"0".SetPaintingStrategy(PaintingStrategy.DASHES);
"1".SetPaintingStrategy(PaintingStrategy.DASHES);
"-1".SetPaintingStrategy(PaintingStrategy.DASHES);
"0".SetDefaultColor(Color.DARK_GRAY);
"1".SetDefaultColor(Color.DARK_GRAY);
"2".SetDefaultColor(Color.RED);
"-1".SetDefaultColor(Color.DARK_GRAY);
"-2".SetDefaultColor(Color.GREEN);


#-- Bar Color

AssignPriceColor(if !colorBars then Color.CURRENT else
                 if col == 2 then Color.GREEN else
                 if col == 1 then Color.DARK_GREEN else
                 if col ==-2 then Color.RED else
                 if col ==-1 then Color.DARK_RED else Color.GRAY);


#-- END of CODE
 
Last edited:

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
157 Online
Create Post

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