Difference Between Two Zigzag High Pivot Points

british43

Member
VIP
I'm working on a script to find the different between two Zigzag high pivot points (would also like to do this for the low side also). Please see image. The bubble at "1" would green with the value of "93.74 and 43.01 (difference between previous high and current value of the Zigzag). If flip the scenario the bubble at "1" would red. Any help would be great.

This is the line of code I think I'm messing up.

def ATRSave = if !IsNaN(ZZ) then SMI1 else GetValue(ATRSave, 1);
def ATRchg = round(SMI1 - GetValue(ATRSave, 1));
plot ATRisUp = ATRchg >= 0;
ATRisUp.Hide();
def ATRisDown = ATRchg <= 0;
def isConf = AbsValue(ATRchg) >= reversalAmount or (IsNaN(getValue(ZZ, 1)) and getValue(isConf, 1));

plot ATRDiff= ATRchg;
ATRDiff.hide();

AddChartBubble(1, ZZ, SMI1+" "+ATRchg, if ATRisUp then Color.GREEN else if ATRisDown then Color.RED else Color.RED, ATRisUp);
[/CODE]

XC9SDhv.png


Ruby:
declare lower;

input length = 14;
input averageType1 = AverageType.WILDERS;

plot ADX = DMI(length, averageType1).ADX;
ADX.SetDefaultColor(GetColor(5));

input KPeriod = 8;
input n3 = 5;
input priceHl = high;
input priceLl = low;
input priceCl = close;
input slowing_period = 3;
input averageType = AverageType.SIMPLE;
input showBreakoutSignals = {default "No", "On FullK", "On FullD", "On FullK & FullD"};
input showlabels = yes;

def lowest_k = Lowest(priceLl, KPeriod);
def c1 = priceCl - lowest_k;
def c2 = Highest(priceHl, KPeriod) - lowest_k;
def FastK = if c2 != 0 then c1 / c2 * 100 else 0;

plot SMI1 = round(MovingAverage(averageType, FastK, slowing_period));

def o = open;
def h = high;
def l = low;
def c = close;
def priceH = SMI1;
def priceL = SMI1;
def priceC = SMI1;

input percentageReversal = 5.0;
input absoluteReversal = 0.0;
input atrLength = 5;
input atrReversal = 1;
input tickReversal = 0;

Assert(percentageReversal >= 0, "'percentage reversal' must not be negative: " + percentageReversal);
Assert(absoluteReversal >= 0, "'absolute reversal' must not be negative: " + absoluteReversal);
Assert(atrReversal >= 0, "'atr reversal' must not be negative: " + atrReversal);
Assert(tickReversal >= 0, "'ticks' must not be negative: " + tickReversal);
Assert(percentageReversal != 0 or absoluteReversal != 0 or atrReversal != 0 or tickReversal != 0, "Either 'percentage reversal' or 'absolute reversal' or 'atr reversal' or 'tick reversal' must not be zero");

def absReversal;
if (absoluteReversal != 0) {
    absReversal = absoluteReversal;
} else {
    absReversal =  tickReversal * TickSize();
}

def hlPivot;
if (atrReversal != 0) {
    hlPivot = percentageReversal / 100 + WildersAverage(TrueRange(SMI1, SMI1, SMI1), atrLength) / SMI1 * atrReversal;
} else {
    hlPivot = percentageReversal / 100;
}
def state = {default init, undefined, uptrend, downtrend};
def maxPriceH;
def minPriceL;
def newMax;
def newMin;
def prevMaxH = GetValue(maxPriceH, 1);
def prevMinL = GetValue(minPriceL, 1);

if GetValue(state, 1) == GetValue(state.init, 0) {
    maxPriceH = priceH;
    minPriceL = priceL;
    newMax = yes;
    newMin = yes;
    state = state.undefined;
} else if GetValue(state, 1) == GetValue(state.undefined, 0) {
    if priceH >= prevMaxH {
        state = state.uptrend;
        maxPriceH = priceH;
        minPriceL = prevMinL;
        newMax = yes;
        newMin = no;
    } else if priceL <= prevMinL {
        state = state.downtrend;
        maxPriceH = prevMaxH;
        minPriceL = priceL;
        newMax = no;
        newMin = yes;
    } else {
        state = state.undefined;
        maxPriceH = prevMaxH;
        minPriceL = prevMinL;
        newMax = no;
        newMin = no;
    }
} else if GetValue(state, 1) == GetValue(state.uptrend, 0) {
    if priceL <= prevMaxH - prevMaxH * hlPivot - absReversal {
        state = state.downtrend;
        maxPriceH = prevMaxH;
        minPriceL = priceL;
        newMax = no;
        newMin = yes;
    } else {
        state = state.uptrend;
        if (priceH >= prevMaxH) {
            maxPriceH = priceH;
            newMax = yes;
        } else {
            maxPriceH = prevMaxH;
            newMax = no;
        }
        minPriceL = prevMinL;
        newMin = no;
    }
} else {
    if priceH >= prevMinL + prevMinL * hlPivot + absReversal {
        state = state.uptrend;
        maxPriceH = priceH;
        minPriceL = prevMinL;
        newMax = yes;
        newMin = no;
    } else {
        state = state.downtrend;
        maxPriceH = prevMaxH;
        newMax = no;
        if (priceL <= prevMinL) {
            minPriceL = priceL;
            newMin = yes;
        } else {
            minPriceL = prevMinL;
            newMin = no;
        }
    }
}

def barNumber = BarNumber();
def barCount = HighestAll(If(IsNaN(priceH), 0, barNumber));
def newState = GetValue(state, 0) != GetValue(state, 1);
def offset = barCount - barNumber + 1;
def highPoint = state == state.uptrend and priceH == maxPriceH;
def lowPoint = state == state.downtrend and priceL == minPriceL;

def lastH;
if highPoint and offset > 1 {
    lastH = fold iH = 1 to offset with tH = priceH while !IsNaN(tH) and !GetValue(newState, -iH) do if GetValue(newMax, -iH) or iH == offset - 1 and GetValue(priceH, -iH) == tH then Double.NaN else tH;
} else {
    lastH = Double.NaN;
}

def lastL;
if lowPoint and offset > 1 {
    lastL = fold iL = 1 to offset with tL = priceL while !IsNaN(tL) and !GetValue(newState, -iL) do if GetValue(newMin, -iL) or iL == offset - 1 and GetValue(priceL, -iL) == tL then Double.NaN else tL;
} else {
    lastL = Double.NaN;
}

plot ZZ;
if barNumber == 1 {
    ZZ = fold iF = 1 to offset with tP = Double.NaN while IsNaN(tP) do if GetValue(state, -iF) == GetValue(state.uptrend, 0) then priceL else if GetValue(state, -iF) == GetValue(state.downtrend, 0) then priceH else Double.NaN;
} else if barNumber == barCount {
    ZZ = if highPoint or state == state.downtrend and priceL > minPriceL then priceH else if lowPoint or state == state.uptrend and priceH < maxPriceH then priceL else Double.NaN;
} else {
    ZZ = if !IsNaN(lastH) then lastH else if !IsNaN(lastL) then lastL else Double.NaN;
}
ZZ.SetDefaultColor(GetColor(1));
ZZ.EnableApproximation();

#ZZ.hide();

def bar = BarNumber();

input n = 10;
def CurrMACDh = if SMI1 > 0
                then fold i = 1 to n + 1
                with p = 1
                while p
                do SMI1 > GetValue(SMI1, -i)
                else 0;
def CurrMACDPivotH = if (bar > n and
                         SMI1 == Highest(SMI1, n) and
                         CurrMACDh)
                     then SMI1
                     else Double.NaN;
def CurrMACDl = if SMI1 > 0
                then fold j = 1 to n + 1
                with q = 1
                while q
                do SMI1 < GetValue(SMI1, -j)
                else 0;
def CurrMACDPivotL = if (bar > n and
                         SMI1 == Lowest(SMI1, n) and
                         CurrMACDl)
                     then SMI1
                     else Double.NaN;
def CurrPHBar = if !IsNaN(CurrMACDPivotH)
                then bar
                else CurrPHBar[1];
def CurrPLBar = if !IsNaN(CurrMACDPivotL)
                then bar
                else CurrPLBar[1];
def PHpoint = if !IsNaN(CurrMACDPivotH)
              then CurrMACDPivotH
              else PHpoint[1];
def priorPHBar = if PHpoint != PHpoint[1]
                 then CurrPHBar[1]
                 else priorPHBar[1];
def PLpoint = if !IsNaN(CurrMACDPivotL)
              then CurrMACDPivotL
              else PLpoint[1];
def priorPLBar = if PLpoint != PLpoint[1]
                 then CurrPLBar[1]
                 else priorPLBar[1];
def HighPivots = bar >= HighestAll(priorPHBar);
def LowPivots = bar >= HighestAll(priorPLBar);
def pivotHigh = if HighPivots
                then CurrMACDPivotH
                else Double.NaN;
plot PlotHline = pivotHigh;
PlotHline.EnableApproximation();
PlotHline.SetDefaultColor(GetColor(7));
PlotHline.SetStyle(Curve.SHORT_DASH);
plot pivotLow = if LowPivots
                then CurrMACDPivotL
                else Double.NaN;
pivotLow.EnableApproximation();
pivotLow.SetDefaultColor(GetColor(7));
pivotLow.SetStyle(Curve.SHORT_DASH);
plot PivotDot = if !IsNaN(pivotHigh)
                then pivotHigh
                else if !IsNaN(pivotLow)
                     then pivotLow
                     else Double.NaN;
PivotDot.SetDefaultColor(GetColor(7));
PivotDot.SetPaintingStrategy(PaintingStrategy.POINTS);
PivotDot.SetLineWeight(3);

input reversalamount =8.0;

[B]def ATRSave = if  !IsNaN(ZZ) then SMI1 else GetValue(ATRSave, 1);
def ATRchg = round(SMI1 - GetValue(ATRSave, 1));
plot ATRisUp = ATRchg >= 0;
ATRisUp.Hide();
def ATRisDown = ATRchg <= 0;
def isConf = AbsValue(ATRchg) >= reversalAmount or (IsNaN(getValue(ZZ, 1)) and getValue(isConf, 1));

plot ATRDiff= ATRchg;
ATRDiff.hide();

AddChartBubble(1, ZZ, SMI1+" "+ATRchg, if ATRisUp then Color.GREEN else if ATRisDown then Color.RED else Color.RED, ATRisUp);
[/B]
 
Last edited by a moderator:
I'm working on a script to find the different between two Zigzag high pivot points (would also like to do this for the low side also). Please see image. The bubble at "1" would green with the value of "93.74 and 43.01 (difference between previous high and current value of the Zigzag). If flip the scenario the bubble at "1" would red. Any help would be great.

This is the line of code I think I'm messing up.

def ATRSave = if !IsNaN(ZZ) then SMI1 else GetValue(ATRSave, 1);
def ATRchg = round(SMI1 - GetValue(ATRSave, 1));
plot ATRisUp = ATRchg >= 0;
ATRisUp.Hide();
def ATRisDown = ATRchg <= 0;
def isConf = AbsValue(ATRchg) >= reversalAmount or (IsNaN(getValue(ZZ, 1)) and getValue(isConf, 1));

plot ATRDiff= ATRchg;
ATRDiff.hide();

AddChartBubble(1, ZZ, SMI1+" "+ATRchg, if ATRisUp then Color.GREEN else if ATRisDown then Color.RED else Color.RED, ATRisUp);
[/CODE]


XC9SDhv.png

Added a bubble on the top/bottom of the current green/red bubbles that has the difference between the high/previous high and low/previous low. Astext() was used to present uniform looking rounded 2 digit numbers in the bubbles.

This is the area of the code where these changes were based upon. Not all of these were needed, but shows how you can capture past data.
#---------------------------------------------------------------------------------------------------------------------------------
def ATRSave = if !IsNaN(ZZ) then SMI1 else GetValue(ATRSave, 1);
def ATRSave1 = if ATRSave != ATRSave[1] then ATRSave[1] else GetValue(ATRSave1, 1);
def ATRSave2 = if ATRSave1 != ATRSave1[1] then ATRSave1[1] else GetValue(ATRSave2, 1);
def ATRSave3 = if ATRSave2 != ATRSave2[1] then ATRSave2[1] else GetValue(ATRSave3, 1);
#---------------------------------------------------------------------------------------------------------------------------------

Capture.jpg
Ruby:
declare lower;

input length = 14;
input averageType1 = AverageType.WILDERS;

plot ADX = DMI(length, averageType1).ADX;
ADX.SetDefaultColor(GetColor(5));

input KPeriod = 8;
input n3 = 5;
input priceHl = high;
input priceLl = low;
input priceCl = close;
input slowing_period = 3;
input averageType = AverageType.SIMPLE;
input showBreakoutSignals = {default "No", "On FullK", "On FullD", "On FullK & FullD"};
input showlabels = yes;

def lowest_k = Lowest(priceLl, KPeriod);
def c1 = priceCl - lowest_k;
def c2 = Highest(priceHl, KPeriod) - lowest_k;
def FastK = if c2 != 0 then c1 / c2 * 100 else 0;

plot SMI1 = Round(MovingAverage(averageType, FastK, slowing_period));

def o = open;
def h = high;
def l = low;
def c = close;
def priceH = SMI1;
def priceL = SMI1;
def priceC = SMI1;

input percentageReversal = 5.0;
input absoluteReversal = 0.0;
input atrLength = 5;
input atrReversal = 1;
input tickReversal = 0;

Assert(percentageReversal >= 0, "'percentage reversal' must not be negative: " + percentageReversal);
Assert(absoluteReversal >= 0, "'absolute reversal' must not be negative: " + absoluteReversal);
Assert(atrReversal >= 0, "'atr reversal' must not be negative: " + atrReversal);
Assert(tickReversal >= 0, "'ticks' must not be negative: " + tickReversal);
Assert(percentageReversal != 0 or absoluteReversal != 0 or atrReversal != 0 or tickReversal != 0, "Either 'percentage reversal' or 'absolute reversal' or 'atr reversal' or 'tick reversal' must not be zero");

def absReversal;
if (absoluteReversal != 0) {
    absReversal = absoluteReversal;
} else {
    absReversal =  tickReversal * TickSize();
}

def hlPivot;
if (atrReversal != 0) {
    hlPivot = percentageReversal / 100 + WildersAverage(TrueRange(SMI1, SMI1, SMI1), atrLength) / SMI1 * atrReversal;
} else {
    hlPivot = percentageReversal / 100;
}
def state = {default init, undefined, uptrend, downtrend};
def maxPriceH;
def minPriceL;
def newMax;
def newMin;
def prevMaxH = GetValue(maxPriceH, 1);
def prevMinL = GetValue(minPriceL, 1);

if GetValue(state, 1) == GetValue(state.init, 0) {
    maxPriceH = priceH;
    minPriceL = priceL;
    newMax = yes;
    newMin = yes;
    state = state.undefined;
} else if GetValue(state, 1) == GetValue(state.undefined, 0) {
    if priceH >= prevMaxH {
        state = state.uptrend;
        maxPriceH = priceH;
        minPriceL = prevMinL;
        newMax = yes;
        newMin = no;
    } else if priceL <= prevMinL {
        state = state.downtrend;
        maxPriceH = prevMaxH;
        minPriceL = priceL;
        newMax = no;
        newMin = yes;
    } else {
        state = state.undefined;
        maxPriceH = prevMaxH;
        minPriceL = prevMinL;
        newMax = no;
        newMin = no;
    }
} else if GetValue(state, 1) == GetValue(state.uptrend, 0) {
    if priceL <= prevMaxH - prevMaxH * hlPivot - absReversal {
        state = state.downtrend;
        maxPriceH = prevMaxH;
        minPriceL = priceL;
        newMax = no;
        newMin = yes;
    } else {
        state = state.uptrend;
        if (priceH >= prevMaxH) {
            maxPriceH = priceH;
            newMax = yes;
        } else {
            maxPriceH = prevMaxH;
            newMax = no;
        }
        minPriceL = prevMinL;
        newMin = no;
    }
} else {
    if priceH >= prevMinL + prevMinL * hlPivot + absReversal {
        state = state.uptrend;
        maxPriceH = priceH;
        minPriceL = prevMinL;
        newMax = yes;
        newMin = no;
    } else {
        state = state.downtrend;
        maxPriceH = prevMaxH;
        newMax = no;
        if (priceL <= prevMinL) {
            minPriceL = priceL;
            newMin = yes;
        } else {
            minPriceL = prevMinL;
            newMin = no;
        }
    }
}

def barNumber = BarNumber();
def barCount = HighestAll(If(IsNaN(priceH), 0, barNumber));
def newState = GetValue(state, 0) != GetValue(state, 1);
def offset = barCount - barNumber + 1;
def highPoint = state == state.uptrend and priceH == maxPriceH;
def lowPoint = state == state.downtrend and priceL == minPriceL;

def lastH;
if highPoint and offset > 1 {
    lastH = fold iH = 1 to offset with tH = priceH while !IsNaN(tH) and !GetValue(newState, -iH) do if GetValue(newMax, -iH) or iH == offset - 1 and GetValue(priceH, -iH) == tH then Double.NaN else tH;
} else {
    lastH = Double.NaN;
}

def lastL;
if lowPoint and offset > 1 {
    lastL = fold iL = 1 to offset with tL = priceL while !IsNaN(tL) and !GetValue(newState, -iL) do if GetValue(newMin, -iL) or iL == offset - 1 and GetValue(priceL, -iL) == tL then Double.NaN else tL;
} else {
    lastL = Double.NaN;
}

plot ZZ;
if barNumber == 1 {
    ZZ = fold iF = 1 to offset with tP = Double.NaN while IsNaN(tP) do if GetValue(state, -iF) == GetValue(state.uptrend, 0) then priceL else if GetValue(state, -iF) == GetValue(state.downtrend, 0) then priceH else Double.NaN;
} else if barNumber == barCount {
    ZZ = if highPoint or state == state.downtrend and priceL > minPriceL then priceH else if lowPoint or state == state.uptrend and priceH < maxPriceH then priceL else Double.NaN;
} else {
    ZZ = if !IsNaN(lastH) then lastH else if !IsNaN(lastL) then lastL else Double.NaN;
}
ZZ.SetDefaultColor(GetColor(1));
ZZ.EnableApproximation();

#ZZ.hide();

def bar = BarNumber();

input n = 10;
def CurrMACDh = if SMI1 > 0
                then fold i = 1 to n + 1
                with p = 1
                while p
                do SMI1 > GetValue(SMI1, -i)
                else 0;
def CurrMACDPivotH = if (bar > n and
                         SMI1 == Highest(SMI1, n) and
                         CurrMACDh)
                     then SMI1
                     else Double.NaN;
def CurrMACDl = if SMI1 > 0
                then fold j = 1 to n + 1
                with q = 1
                while q
                do SMI1 < GetValue(SMI1, -j)
                else 0;
def CurrMACDPivotL = if (bar > n and
                         SMI1 == Lowest(SMI1, n) and
                         CurrMACDl)
                     then SMI1
                     else Double.NaN;
def CurrPHBar = if !IsNaN(CurrMACDPivotH)
                then bar
                else CurrPHBar[1];
def CurrPLBar = if !IsNaN(CurrMACDPivotL)
                then bar
                else CurrPLBar[1];
def PHpoint = if !IsNaN(CurrMACDPivotH)
              then CurrMACDPivotH
              else PHpoint[1];
def priorPHBar = if PHpoint != PHpoint[1]
                 then CurrPHBar[1]
                 else priorPHBar[1];
def PLpoint = if !IsNaN(CurrMACDPivotL)
              then CurrMACDPivotL
              else PLpoint[1];
def priorPLBar = if PLpoint != PLpoint[1]
                 then CurrPLBar[1]
                 else priorPLBar[1];
def HighPivots = bar >= HighestAll(priorPHBar);
def LowPivots = bar >= HighestAll(priorPLBar);
def pivotHigh = if HighPivots
                then CurrMACDPivotH
                else Double.NaN;
plot PlotHline = pivotHigh;
PlotHline.EnableApproximation();
PlotHline.SetDefaultColor(GetColor(7));
PlotHline.SetStyle(Curve.SHORT_DASH);
plot pivotLow = if LowPivots
                then CurrMACDPivotL
                else Double.NaN;
pivotLow.EnableApproximation();
pivotLow.SetDefaultColor(GetColor(7));
pivotLow.SetStyle(Curve.SHORT_DASH);
plot PivotDot = if !IsNaN(pivotHigh)
                then pivotHigh
                else if !IsNaN(pivotLow)
                     then pivotLow
                     else Double.NaN;
PivotDot.SetDefaultColor(GetColor(7));
PivotDot.SetPaintingStrategy(PaintingStrategy.POINTS);
PivotDot.SetLineWeight(3);

input reversalamount = 8.0;
#---------------------------------------------------------------------------------------------------------------------------------
def ATRSave = if  !IsNaN(ZZ) then SMI1 else GetValue(ATRSave, 1);
def ATRSave1 = if  ATRSave != ATRSave[1] then ATRSave[1] else GetValue(ATRSave1, 1);
def ATRSave2 = if  ATRSave1 != ATRSave1[1] then ATRSave1[1] else GetValue(ATRSave2, 1);
def ATRSave3 = if  ATRSave2 != ATRSave2[1] then ATRSave2[1] else GetValue(ATRSave3, 1);
#---------------------------------------------------------------------------------------------------------------------------------
def ATRchg = Round(SMI1 - GetValue(ATRSave, 1));
plot ATRisUp = ATRchg >= 0;
ATRisUp.Hide();
def ATRisDown = ATRchg <= 0;
def isConf = AbsValue(ATRchg) >= reversalamount or (IsNaN(GetValue(ZZ, 1)) and GetValue(isConf, 1));

plot ATRDiff = ATRchg;
ATRDiff.Hide();

AddChartBubble(1, ZZ, astext(SMI1) + " " + astext(ATRchg), if ATRisUp then Color.GREEN else if ATRisDown then Color.RED else Color.RED, ATRisUp);
AddChartBubble(1, ZZ, astext(ATRSave - atrsave2), if ATRisUp then Color.GREEN else if ATRisDown then Color.RED else Color.RED, ATRisUp);
 
@SleepyZ I have another questions: How would I go about flipping the bubble direction (i.e. top for high pivot and bottom for low pivot)?
How is that different than in the chart image I posted above. Otherwise, see if this is what you mean

Ruby:
AddChartBubble(1, ZZ, astext(ATRSave - atrsave2), if ATRisUp then Color.GREEN else if ATRisDown then Color.RED else Color.RED, ATRisUp);

AddChartBubble(1, ZZ, astext(SMI1) + " " + astext(ATRchg), if ATRisUp then Color.GREEN else if ATRisDown then Color.RED else Color.RED, ATRisUp);
 
@SleepyZ How can I change the bubble values to HH, HL, LL, LH? I've been trying but failed. Thanks.
The following has options to display, for the now 3 types of bubbles.

Capture.jpg
Ruby:
declare lower;

input length = 14;
input averageType1 = AverageType.WILDERS;

plot ADX = DMI(length, averageType1).ADX;
ADX.SetDefaultColor(GetColor(5));

input KPeriod = 8;
input n3 = 5;
input priceHl = high;
input priceLl = low;
input priceCl = close;
input slowing_period = 3;
input averageType = AverageType.SIMPLE;
input showBreakoutSignals = {default "No", "On FullK", "On FullD", "On FullK & FullD"};
input showlabels = yes;

def lowest_k = Lowest(priceLl, KPeriod);
def c1 = priceCl - lowest_k;
def c2 = Highest(priceHl, KPeriod) - lowest_k;
def FastK = if c2 != 0 then c1 / c2 * 100 else 0;

plot SMI1 = Round(MovingAverage(averageType, FastK, slowing_period));

def o = open;
def h = high;
def l = low;
def c = close;
def priceH = SMI1;
def priceL = SMI1;
def priceC = SMI1;

input percentageReversal = 5.0;
input absoluteReversal = 0.0;
input atrLength = 5;
input atrReversal = 1;
input tickReversal = 0;

Assert(percentageReversal >= 0, "'percentage reversal' must not be negative: " + percentageReversal);
Assert(absoluteReversal >= 0, "'absolute reversal' must not be negative: " + absoluteReversal);
Assert(atrReversal >= 0, "'atr reversal' must not be negative: " + atrReversal);
Assert(tickReversal >= 0, "'ticks' must not be negative: " + tickReversal);
Assert(percentageReversal != 0 or absoluteReversal != 0 or atrReversal != 0 or tickReversal != 0, "Either 'percentage reversal' or 'absolute reversal' or 'atr reversal' or 'tick reversal' must not be zero");

def absReversal;
if (absoluteReversal != 0) {
    absReversal = absoluteReversal;
} else {
    absReversal =  tickReversal * TickSize();
}

def hlPivot;
if (atrReversal != 0) {
    hlPivot = percentageReversal / 100 + WildersAverage(TrueRange(SMI1, SMI1, SMI1), atrLength) / SMI1 * atrReversal;
} else {
    hlPivot = percentageReversal / 100;
}
def state = {default init, undefined, uptrend, downtrend};
def maxPriceH;
def minPriceL;
def newMax;
def newMin;
def prevMaxH = GetValue(maxPriceH, 1);
def prevMinL = GetValue(minPriceL, 1);

if GetValue(state, 1) == GetValue(state.init, 0) {
    maxPriceH = priceH;
    minPriceL = priceL;
    newMax = yes;
    newMin = yes;
    state = state.undefined;
} else if GetValue(state, 1) == GetValue(state.undefined, 0) {
    if priceH >= prevMaxH {
        state = state.uptrend;
        maxPriceH = priceH;
        minPriceL = prevMinL;
        newMax = yes;
        newMin = no;
    } else if priceL <= prevMinL {
        state = state.downtrend;
        maxPriceH = prevMaxH;
        minPriceL = priceL;
        newMax = no;
        newMin = yes;
    } else {
        state = state.undefined;
        maxPriceH = prevMaxH;
        minPriceL = prevMinL;
        newMax = no;
        newMin = no;
    }
} else if GetValue(state, 1) == GetValue(state.uptrend, 0) {
    if priceL <= prevMaxH - prevMaxH * hlPivot - absReversal {
        state = state.downtrend;
        maxPriceH = prevMaxH;
        minPriceL = priceL;
        newMax = no;
        newMin = yes;
    } else {
        state = state.uptrend;
        if (priceH >= prevMaxH) {
            maxPriceH = priceH;
            newMax = yes;
        } else {
            maxPriceH = prevMaxH;
            newMax = no;
        }
        minPriceL = prevMinL;
        newMin = no;
    }
} else {
    if priceH >= prevMinL + prevMinL * hlPivot + absReversal {
        state = state.uptrend;
        maxPriceH = priceH;
        minPriceL = prevMinL;
        newMax = yes;
        newMin = no;
    } else {
        state = state.downtrend;
        maxPriceH = prevMaxH;
        newMax = no;
        if (priceL <= prevMinL) {
            minPriceL = priceL;
            newMin = yes;
        } else {
            minPriceL = prevMinL;
            newMin = no;
        }
    }
}

def barNumber = BarNumber();
def barCount = HighestAll(If(IsNaN(priceH), 0, barNumber));
def newState = GetValue(state, 0) != GetValue(state, 1);
def offset = barCount - barNumber + 1;
def highPoint = state == state.uptrend and priceH == maxPriceH;
def lowPoint = state == state.downtrend and priceL == minPriceL;

def lastH;
if highPoint and offset > 1 {
    lastH = fold iH = 1 to offset with tH = priceH while !IsNaN(tH) and !GetValue(newState, -iH) do if GetValue(newMax, -iH) or iH == offset - 1 and GetValue(priceH, -iH) == tH then Double.NaN else tH;
} else {
    lastH = Double.NaN;
}

def lastL;
if lowPoint and offset > 1 {
    lastL = fold iL = 1 to offset with tL = priceL while !IsNaN(tL) and !GetValue(newState, -iL) do if GetValue(newMin, -iL) or iL == offset - 1 and GetValue(priceL, -iL) == tL then Double.NaN else tL;
} else {
    lastL = Double.NaN;
}

plot ZZ;
if barNumber == 1 {
    ZZ = fold iF = 1 to offset with tP = Double.NaN while IsNaN(tP) do if GetValue(state, -iF) == GetValue(state.uptrend, 0) then priceL else if GetValue(state, -iF) == GetValue(state.downtrend, 0) then priceH else Double.NaN;
} else if barNumber == barCount {
    ZZ = if highPoint or state == state.downtrend and priceL > minPriceL then priceH else if lowPoint or state == state.uptrend and priceH < maxPriceH then priceL else Double.NaN;
} else {
    ZZ = if !IsNaN(lastH) then lastH else if !IsNaN(lastL) then lastL else Double.NaN;
}
ZZ.SetDefaultColor(GetColor(1));
ZZ.EnableApproximation();

#ZZ.hide();

def bar = BarNumber();

input n = 10;
def CurrMACDh = if SMI1 > 0
                then fold i = 1 to n + 1
                with p = 1
                while p
                do SMI1 > GetValue(SMI1, -i)
                else 0;
def CurrMACDPivotH = if (bar > n and
                         SMI1 == Highest(SMI1, n) and
                         CurrMACDh)
                     then SMI1
                     else Double.NaN;
def CurrMACDl = if SMI1 > 0
                then fold j = 1 to n + 1
                with q = 1
                while q
                do SMI1 < GetValue(SMI1, -j)
                else 0;
def CurrMACDPivotL = if (bar > n and
                         SMI1 == Lowest(SMI1, n) and
                         CurrMACDl)
                     then SMI1
                     else Double.NaN;
def CurrPHBar = if !IsNaN(CurrMACDPivotH)
                then bar
                else CurrPHBar[1];
def CurrPLBar = if !IsNaN(CurrMACDPivotL)
                then bar
                else CurrPLBar[1];
def PHpoint = if !IsNaN(CurrMACDPivotH)
              then CurrMACDPivotH
              else PHpoint[1];
def priorPHBar = if PHpoint != PHpoint[1]
                 then CurrPHBar[1]
                 else priorPHBar[1];
def PLpoint = if !IsNaN(CurrMACDPivotL)
              then CurrMACDPivotL
              else PLpoint[1];
def priorPLBar = if PLpoint != PLpoint[1]
                 then CurrPLBar[1]
                 else priorPLBar[1];
def HighPivots = bar >= HighestAll(priorPHBar);
def LowPivots = bar >= HighestAll(priorPLBar);
def pivotHigh = if HighPivots
                then CurrMACDPivotH
                else Double.NaN;
plot PlotHline = pivotHigh;
PlotHline.EnableApproximation();
PlotHline.SetDefaultColor(GetColor(7));
PlotHline.SetStyle(Curve.SHORT_DASH);
plot pivotLow = if LowPivots
                then CurrMACDPivotL
                else Double.NaN;
pivotLow.EnableApproximation();
pivotLow.SetDefaultColor(GetColor(7));
pivotLow.SetStyle(Curve.SHORT_DASH);
plot PivotDot = if !IsNaN(pivotHigh)
                then pivotHigh
                else if !IsNaN(pivotLow)
                     then pivotLow
                     else Double.NaN;
PivotDot.SetDefaultColor(GetColor(7));
PivotDot.SetPaintingStrategy(PaintingStrategy.POINTS);
PivotDot.SetLineWeight(3);

input reversalamount = 8.0;
#---------------------------------------------------------------------------------------------------------------------------------
def ATRSave = if  !IsNaN(ZZ) then SMI1 else GetValue(ATRSave, 1);
def ATRSave1 = if  ATRSave != ATRSave[1] then ATRSave[1] else GetValue(ATRSave1, 1);
def ATRSave2 = if  ATRSave1 != ATRSave1[1] then ATRSave1[1] else GetValue(ATRSave2, 1);
def ATRSave3 = if  ATRSave2 != ATRSave2[1] then ATRSave2[1] else GetValue(ATRSave3, 1);
#---------------------------------------------------------------------------------------------------------------------------------
def ATRchg = Round(SMI1 - GetValue(ATRSave, 1));
plot ATRisUp = ATRchg >= 0;
ATRisUp.Hide();
def ATRisDown = ATRchg <= 0;
def isConf = AbsValue(ATRchg) >= reversalamount or (IsNaN(GetValue(ZZ, 1)) and GetValue(isConf, 1));

plot ATRDiff = ATRchg;
ATRDiff.Hide();

#Bubbles and spacers--------------------------------------------------------------------------
input show_smi_atrchange_bubble = yes;
AddChartBubble(show_smi_atrchange_bubble,   
                  ZZ,
                  AsText(SMI1) + " " + AsText(ATRchg),
                  if ATRisUp then Color.GREEN
                  else if ATRisDown then Color.RED
                  else Color.RED, ATRisUp);

input show_atr_change_bubble = yes;
AddChartBubble(show_atr_change_bubble,
                  ZZ,
                  AsText(ATRSave - ATRSave2),
                  if ATRisUp then Color.GREEN
                  else if ATRisDown then Color.RED
                  else Color.WHITE, ATRisUp);

input showHH_HL_LH_LL_bubble = yes;
AddChartBubble(showHH_HL_LH_LL_bubble,
                  ZZ,
                  if ATRisUp and (ATRSave - ATRSave2) > 0
                  then "HH"
                  else if ATRisUp
                  then "LH"
                  else if ATRisDown and (ATRSave - ATRSave2) > 0
                  then "HL"
                  else if ATRisDown and (ATRSave - ATRSave2) < 0
                  then "LL"
                  else "",
                  if ATRisUp then Color.GREEN
                  else if ATRisDown then Color.RED
                  else Color.WHITE, ATRisUp);
 
This is great!!I wanted to do something like this but for RSI. Do you think something like this would be possible over RSI? I tried out a couple of things without success, but I didn't want to go too far down this path if it wasn't possible or if there is already a RSI ZigZag indicator (I wasn't able to find one on here or elsewhere online for for TOS).
 
This is great!!I wanted to do something like this but for RSI. Do you think something like this would be possible over RSI? I tried out a couple of things without success, but I didn't want to go too far down this path if it wasn't possible or if there is already a RSI ZigZag indicator (I wasn't able to find one on here or elsewhere online for for TOS).
I have one message eme back tomorrow ull send it your way
 
This is great!!I wanted to do something like this but for RSI. Do you think something like this would be possible over RSI? I tried out a couple of things without success, but I didn't want to go too far down this path if it wasn't possible or if there is already a RSI ZigZag indicator (I wasn't able to find one on here or elsewhere online for for TOS).
#Muathe: the moving average and its zig zag requested by Braum codede by zzz. cloud added by Paris. peak and valley added by Braum . The difference between Muathe rsi and regular rsi is the values of the ovb and ovs.and most important part of it is the line of 61.8. listen to him at youtube for the full explaination of this line. I changed the exp to wilders.
Ruby:
declare lower;

input length = 14;
input over_Bought = 69.10;
input over_Sold = 38.2;
input price = close;
input averageType = AverageType.WILDERS;

def NetChgAvg = MovingAverage(averageType, price - price[1], length);
def TotChgAvg = MovingAverage(averageType, AbsValue(price - price[1]), length);
def ChgRatio = if TotChgAvg != 0 then NetChgAvg / TotChgAvg else 0;




plot mid_point = 61.8;
plot RSI = 50 * (ChgRatio + 1);
RSI.DefineColor("OverBought", Color.RED); RSI.DefineColor("Normal", Color.gray); RSI.DefineColor("OverSold", Color.green); RSI.AssignValueColor(if RSI > over_Bought then RSI.Color("OverSOLD") else if RSI < over_Sold then RSI.Color("OverBOUGHT") else RSI.Color("normal"));
plot center_line = 50.10;

plot OverSold = over_Sold;
OverSold.SetDefaultColor(Color.green); OverSold.SetStyle(Curve.firm); OverSold.SetLineWeight(2);

plot OverBought = over_Bought; OverBought.SetDefaultColor(Color.red); OverBought.SetStyle(Curve.firm); OverBought.SetLineWeight(2);
RSI.DefineColor("OverBought", GetColor(5));
RSI.DefineColor("Normal", GetColor(7));
RSI.DefineColor("OverSold", GetColor(1));
RSI.AssignValueColor(if RSI > over_Bought then RSI.color("OverBought") else if RSI < over_Sold then RSI.color("OverSold") else RSI.color("Normal"));
OverSold.SetDefaultColor(GetColor(8));
OverBought.SetDefaultColor(GetColor(8));

input reversalAmount = 0.3;
input lengthzz = 1;
input avg = AverageType.EXPONENTIAL;
input rsiavglength = 3; #for 1M i use 9avg and for 5M use 5avg
def pricezz = average(rsi,rsiavglength);

def avgprice = MovingAverage(averagetype = avg, (pricezz), length);
Assert(reversalAmount > 0, "'reversal amount' should be positive: " + reversalAmount);
plot "ZZ$" = reference ZigZagHighLow(avgprice, avgprice, 0, reversalAmount, 1, 0);
def zzSave = if !IsNaN("ZZ$") then avgprice else GetValue(zzSave, 1);

def chg = avgprice - GetValue(zzSave, 1);
def isUp = if chg >= 0 then 1 else 0;
def isConf = AbsValue(chg) >= reversalAmount or (IsNaN(GetValue("ZZ$", 1)) and GetValue(isConf, 1));
"ZZ$".EnableApproximation();
"ZZ$".AssignValueColor(if isUp then Color.green else Color.red);
AddCloud(if rsi >= over_Bought then rsi else Double.NaN, over_Bought, Color.green, Color.CURRENT);
AddCloud(over_Sold, if rsi <= over_Sold then rsi else Double.NaN, Color.red, Color.CURRENT);

AddCloud(RSI, avgprice, Color.GREEN, Color.RED);
AddChartBubble(!IsNaN("ZZ$") and !isUp, "ZZ$", "V", Color.GREEN, no);
AddChartBubble(!IsNaN("ZZ$") and isUp, "ZZ$", "P", Color.RED, yes);
 
Last edited by a moderator:
@germanburrito I convert the study to RSI


Ruby:
declare lower;

plot Forecast = reference RSI;

def o = open;
def h = high;
def l = low;
def c = close;
def priceH = forecast;
def priceL = forecast;
def priceC = forecast;

input percentageReversal = 5.0;
input absoluteReversal = 0.0;
input atrLength = 5;
input atrReversal = 1;
input tickReversal = 0;

Assert(percentageReversal >= 0, "'percentage reversal' must not be negative: " + percentageReversal);
Assert(absoluteReversal >= 0, "'absolute reversal' must not be negative: " + absoluteReversal);
Assert(atrReversal >= 0, "'atr reversal' must not be negative: " + atrReversal);
Assert(tickReversal >= 0, "'ticks' must not be negative: " + tickReversal);
Assert(percentageReversal != 0 or absoluteReversal != 0 or atrReversal != 0 or tickReversal != 0, "Either 'percentage reversal' or 'absolute reversal' or 'atr reversal' or 'tick reversal' must not be zero");

def absReversal;
if (absoluteReversal != 0) {
    absReversal = absoluteReversal;
} else {
    absReversal =  tickReversal * TickSize();
}

def hlPivot;
if (atrReversal != 0) {
    hlPivot = percentageReversal / 100 + WildersAverage(TrueRange(forecast, forecast, forecast), atrLength) / forecast * atrReversal;
} else {
    hlPivot = percentageReversal / 100;
}
def state = {default init, undefined, uptrend, downtrend};
def maxPriceH;
def minPriceL;
def newMax;
def newMin;
def prevMaxH = GetValue(maxPriceH, 1);
def prevMinL = GetValue(minPriceL, 1);

if GetValue(state, 1) == GetValue(state.init, 0) {
    maxPriceH = priceH;
    minPriceL = priceL;
    newMax = yes;
    newMin = yes;
    state = state.undefined;
} else if GetValue(state, 1) == GetValue(state.undefined, 0) {
    if priceH >= prevMaxH {
        state = state.uptrend;
        maxPriceH = priceH;
        minPriceL = prevMinL;
        newMax = yes;
        newMin = no;
    } else if priceL <= prevMinL {
        state = state.downtrend;
        maxPriceH = prevMaxH;
        minPriceL = priceL;
        newMax = no;
        newMin = yes;
    } else {
        state = state.undefined;
        maxPriceH = prevMaxH;
        minPriceL = prevMinL;
        newMax = no;
        newMin = no;
    }
} else if GetValue(state, 1) == GetValue(state.uptrend, 0) {
    if priceL <= prevMaxH - prevMaxH * hlPivot - absReversal {
        state = state.downtrend;
        maxPriceH = prevMaxH;
        minPriceL = priceL;
        newMax = no;
        newMin = yes;
    } else {
        state = state.uptrend;
        if (priceH >= prevMaxH) {
            maxPriceH = priceH;
            newMax = yes;
        } else {
            maxPriceH = prevMaxH;
            newMax = no;
        }
        minPriceL = prevMinL;
        newMin = no;
    }
} else {
    if priceH >= prevMinL + prevMinL * hlPivot + absReversal {
        state = state.uptrend;
        maxPriceH = priceH;
        minPriceL = prevMinL;
        newMax = yes;
        newMin = no;
    } else {
        state = state.downtrend;
        maxPriceH = prevMaxH;
        newMax = no;
        if (priceL <= prevMinL) {
            minPriceL = priceL;
            newMin = yes;
        } else {
            minPriceL = prevMinL;
            newMin = no;
        }
    }
}

def barNumber = BarNumber();
def barCount = HighestAll(If(IsNaN(priceH), 0, barNumber));
def newState = GetValue(state, 0) != GetValue(state, 1);
def offset = barCount - barNumber + 1;
def highPoint = state == state.uptrend and priceH == maxPriceH;
def lowPoint = state == state.downtrend and priceL == minPriceL;

def lastH;
if highPoint and offset > 1 {
    lastH = fold iH = 1 to offset with tH = priceH while !IsNaN(tH) and !GetValue(newState, -iH) do if GetValue(newMax, -iH) or iH == offset - 1 and GetValue(priceH, -iH) == tH then Double.NaN else tH;
} else {
    lastH = Double.NaN;
}

def lastL;
if lowPoint and offset > 1 {
    lastL = fold iL = 1 to offset with tL = priceL while !IsNaN(tL) and !GetValue(newState, -iL) do if GetValue(newMin, -iL) or iL == offset - 1 and GetValue(priceL, -iL) == tL then Double.NaN else tL;
} else {
    lastL = Double.NaN;
}

plot ZZ;
if barNumber == 1 {
    ZZ = fold iF = 1 to offset with tP = Double.NaN while IsNaN(tP) do if GetValue(state, -iF) == GetValue(state.uptrend, 0) then priceL else if GetValue(state, -iF) == GetValue(state.downtrend, 0) then priceH else Double.NaN;
} else if barNumber == barCount {
    ZZ = if highPoint or state == state.downtrend and priceL > minPriceL then priceH else if lowPoint or state == state.uptrend and priceH < maxPriceH then priceL else Double.NaN;
} else {
    ZZ = if !IsNaN(lastH) then lastH else if !IsNaN(lastL) then lastL else Double.NaN;
}
ZZ.SetDefaultColor(GetColor(1));
ZZ.EnableApproximation();

#ZZ.hide();
 
@SleepyZ The bubbles makes the chart really clutter is there is a way to the bubble SetPaintingStrategy(PaintingStrategy.VALUES_BELOW) or VALUES_ABOVE?


igVczU2.png
The values that would be plotted are numerical. So instead, red/green arrows may work better. Set the bubble inputs to 'NO" and add the following to the bottom of your script.

Ruby:
input showarrows = yes;
plot arrowh = if showarrows and highpoint then zz else double.nan;
arrowh.setpaintingStrategy(PaintingStrategy.ARROW_DOWN);
arrowh.assignValueColor(if ATRisUp and (ATRSave - ATRSave2) > 0 then color.green else color.red);
plot arrowl = if showarrows and lowpoint then zz else double.nan;
arrowl.setpaintingStrategy(PaintingStrategy.ARROW_up);
arrowl.assignValueColor(if ATRisDown and (ATRSave - ATRSave2) > 0 then color.green else color.red);
 
Last edited:
Hi! Is there away to have the bubbles show on the chart as an upper indicator?
The easiest way is to just move the script to the upper panel and check left axis at the input screen. You can the uncheck the plots for any lines you do not want to appear.

Alternatively, you could uncheck (hide) all of the plots and add the following verticalline code to the bottom of the script. The colors of the lines have been reversed to more represent the potential future trend.

In the image is the verticalline option with the zz plot showing for clarity.

Capture.jpg
Ruby:
#Verticalline---------------------------------------------------------
input showverticalline = yes;
AddVerticalLine(showverticalline and ZZ, "                                                                                         " +                       
if ATRisUp and (ATRSave - ATRSave2) > 0                   
then "HH"                   
else if ATRisUp                   
then "LH"                   
else if ATRisDown and (ATRSave - ATRSave2) > 0                   
then "HL"                   
else if ATRisDown and (ATRSave - ATRSave2) < 0                   
then "LL"                   
else "",
if ATRisUp then Color.RED                   
else if ATRisDown
then Color.GREEN                   
else Color.WHITE,
Curve.FIRM);
 
The easiest way is to just move the script to the upper panel and check left axis at the input screen. You can the uncheck the plots for any lines you do not want to appear.

Alternatively, you could uncheck (hide) all of the plots and add the following verticalline code to the bottom of the script. The colors of the lines have been reversed to more represent the potential future trend.

In the image is the verticalline option with the zz plot showing for clarity.
Thanks @SleepyZ ! You always come through. How could I use this to scan for HL's or LH's?
 

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
275 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