Repaints ZigZag High Low with Supply & Demand Zones for ThinkorSwim

Repaints
Hey @SleepyZ , I really love the ZigZag study you updated with the Fibonacci Extensions -- it's quickly become one of my favorite studies to help with zones. One request I have though, and I apologize if this has already been done or isn't possible, but is it possible to be able to extend these zones further out until they're invalidated? I noticed this today, and while the zones still helped a lot I realized the cloud didn't extend until the next swing completed:

porb8Rv.png


A7XzCIL.png


Is this just a property of the zigzag, or can I extend those clouds fully right away? I noticed there seemed to be similar code on the first page of this but I couldn't tell if it translated to this study or not.

TOS does not have a built-in function to extend these lines. However, we can isolate these line plots and use the script function to extend them.

Here is a revision to the old Linus zigzag script I modified in 2013 to create the 'supply/demand zones' with those areas now extended to the right edge. This code has 5 extended zones (more can be simply added) which can be adjusted by percent and atr settings, as well as a display limiter.

Screenshot-2022-12-29-063543.png

Ruby:
## AO_SupplyDemandComposite_Ver4
## START CODE
## ZigZagSign TOMO modification, v0.2 written by Linus @Thinkscripter Lounge adapted from
## Thinkorswim ZigZagSign Script
##8.24.13 Mod by Lar to add Supply/Demand Levels (Red Zones are Supply, Green are Demand), ability to enter percentage, amount or atr for reversalAmount (using the greater of the three at any reversal)
##2.20.14 Mod by Linus to hide non-active Supply/Demand Levels.
##2.20.14 Mods by Linus to remove everything but Supply/Demand levels and arrows.
##3.04.14 Mods by Linus to change Supply/Demand levels to start at arrows. (Ver2.1)
##4 Mods by Sleepyz(Lar) to isolate and extend to right edge supply/demand zones

script sd {
    input Count = 1;
    def   price               = close;
    def   priceH              = high;    # swing high
    def   priceL              = low;     # swing low
    input ATRreversalfactor   = 3.0;#Hint ATRreversalfactor: 3 is standard, adjust to whatever instrument/timeframe you are trading.
    input ATRlength           = 5;#Hint ATRlength: 5 is standard, adjust to whatever instrument/timeframe you are trading
    input zigzagpercent       = 1.50;#LAR original is 0.2, but modified in testing for 4h charting (may modify further later)
    input zigzagamount        = .15;
    def ATR                   = reference ATR(length = ATRlength);
    def reversalAmount        = if (close * zigzagpercent / 100) > Max(zigzagamount < ATRreversalfactor * ATR, zigzagamount) then (close * zigzagpercent / 100) else if zigzagamount < ATRreversalfactor * ATR then ATRreversalfactor * ATR else zigzagamount;
    input showArrows          = yes; #orignal by LAR was no
    input useAlerts           = no; #orignal by LAR was no
 
#Original TOS ZigZag code Modified by Linus
    def barNumber = BarNumber();
    def barCount = HighestAll(If(IsNaN(price), 0, barNumber));

    rec state = {default init, undefined, uptrend, downtrend};
    rec minMaxPrice;

    if (GetValue(state, 1) == GetValue(state.init, 0)) {
        minMaxPrice = price;
        state = state.undefined;
    } else if (GetValue(state, 1) == GetValue(state.undefined, 0)) {
        if (price <= GetValue(minMaxPrice, 1) - reversalAmount) {
            state = state.downtrend;
            minMaxPrice = priceL;
        } else if (price >= GetValue(minMaxPrice, 1) + reversalAmount) {
            state = state.uptrend;
            minMaxPrice = priceH;
        } else {
            state = state.undefined;
            minMaxPrice = GetValue(minMaxPrice, 1);
        }
    } else if (GetValue(state, 1) == GetValue(state.uptrend, 0)) {
        if (price <= GetValue(minMaxPrice, 1) - reversalAmount) {
            state = state.downtrend;
            minMaxPrice = priceL;
        } else {
            state = state.uptrend;
            minMaxPrice = Max(priceH, GetValue(minMaxPrice, 1));
        }
    } else {
        if (price >= GetValue(minMaxPrice, 1) + reversalAmount) {
            state = state.uptrend;
            minMaxPrice = priceH;
        } else {
            state = state.downtrend;
            minMaxPrice = Min(priceL, GetValue(minMaxPrice, 1));
        }
    }

    def isCalculated = GetValue(state, 0) != GetValue(state, 1) and barNumber >= 1;
    def futureDepth =  barCount - barNumber;
    def tmpLastPeriodBar;
    if (isCalculated) {
        if (futureDepth >= 1 and GetValue(state, 0) == GetValue(state, -1)) {
            tmpLastPeriodBar = fold lastPeriodBarI = 2 to futureDepth + 1 with lastPeriodBarAcc = 1
            while lastPeriodBarAcc > 0
            do if (GetValue(state, 0) != GetValue(state, -lastPeriodBarI))
                then -lastPeriodBarAcc
                else lastPeriodBarAcc + 1;
        } else {
            tmpLastPeriodBar = 0;
        }
    } else {
        tmpLastPeriodBar = Double.NaN;
    }

    def lastPeriodBar = if (!IsNaN(tmpLastPeriodBar)) then -AbsValue(tmpLastPeriodBar) else -futureDepth;

    rec currentPriceLevel;
    rec currentPoints;
    if (state == state.uptrend and isCalculated) {
        currentPriceLevel =
        fold barWithMaxOnPeriodI = lastPeriodBar to 1 with barWithMaxOnPeriodAcc = minMaxPrice
            do Max(barWithMaxOnPeriodAcc, GetValue(minMaxPrice, barWithMaxOnPeriodI));
        currentPoints =
        fold maxPointOnPeriodI = lastPeriodBar to 1 with maxPointOnPeriodAcc = Double.NaN
            while IsNaN(maxPointOnPeriodAcc)
            do if (GetValue(priceH, maxPointOnPeriodI) == currentPriceLevel)
                then maxPointOnPeriodI
                else maxPointOnPeriodAcc;
    } else if (state == state.downtrend and isCalculated) {
        currentPriceLevel =
        fold barWithMinOnPeriodI = lastPeriodBar to 1 with barWithMinOnPeriodAcc = minMaxPrice
            do Min(barWithMinOnPeriodAcc, GetValue(minMaxPrice, barWithMinOnPeriodI));
        currentPoints =
        fold minPointOnPeriodI = lastPeriodBar to 1 with minPointOnPeriodAcc = Double.NaN
            while IsNaN(minPointOnPeriodAcc)
            do if (GetValue(priceL, minPointOnPeriodI) == currentPriceLevel)
                then minPointOnPeriodI
                else minPointOnPeriodAcc;
    } else if (!isCalculated and (state == state.uptrend or state == state.downtrend)) {
        currentPriceLevel = GetValue(currentPriceLevel, 1);
        currentPoints = GetValue(currentPoints, 1) + 1;
    } else {
        currentPoints = 1;
        currentPriceLevel = GetValue(price, currentPoints);
    }

    plot "ZZ$" = if (barNumber == barCount or barNumber == 1) then if state == state.uptrend then priceH else priceL else if (currentPoints == 0) then currentPriceLevel else Double.NaN;

    rec zzSave =  if !IsNaN("ZZ$") then if (barNumber == barCount or barNumber == 1) then if IsNaN(barNumber[-1]) and  state == state.uptrend then priceH else priceL else currentPriceLevel else GetValue(zzSave, 1);

    def chg = (if barNumber == barCount and currentPoints < 0 then priceH else if barNumber == barCount and currentPoints > 0 then priceL else currentPriceLevel) - GetValue(zzSave, 1);

    def isUp = chg >= 0;
    rec isConf = AbsValue(chg) >= reversalAmount or (IsNaN(GetValue("ZZ$", 1)) and GetValue(isConf, 1));

    "ZZ$".EnableApproximation();
    "ZZ$".DefineColor("Up Trend", Color.GREEN);
    "ZZ$".DefineColor("Down Trend", Color.RED);
    "ZZ$".DefineColor("Undefined", Color.DARK_ORANGE);
    "ZZ$".AssignValueColor(if !isConf then "ZZ$".Color("Undefined") else if isUp then "ZZ$".Color("Up Trend") else "ZZ$".Color("Down Trend"));
    "ZZ$".SetLineWeight(2);
    DefineGlobalColor("Unconfirmed", Color.DARK_ORANGE);
    DefineGlobalColor("Up", Color.GREEN);
    DefineGlobalColor("Down", Color.RED);
 
#Arrows

    def zzL = if !IsNaN("ZZ$") and state == state.downtrend then priceL else GetValue(zzL, 1);

    def zzH = if !IsNaN("ZZ$") and state == state.uptrend then priceH else GetValue(zzH, 1);

    def dir = CompoundValue(1, if zzL != zzL[1] then 1 else if zzH != zzH[1] then -1 else dir[1], 0);

    def signal = CompoundValue(1,
    if dir > 0 and low > zzL then
        if signal[1] <= 0 then 1 else signal[1]
    else if dir < 0 and high < zzH then
        if signal[1] >= 0 then -1 else signal[1]
    else signal[1]
, 0);

    plot U1 = showArrows and signal > 0 and signal[1] <= 0;
    U1.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
    U1.SetDefaultColor(Color.GREEN);
    U1.SetLineWeight(4);

    plot D1 = showArrows and signal < 0 and signal[1] >= 0;
    D1.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);
    D1.SetDefaultColor(Color.RED);
    D1.SetLineWeight(4);

    Alert(useAlerts and U1, "ZIG-UP", Alert.BAR, Sound.Bell);
    Alert(useAlerts and D1, "ZAG-DOWN", Alert.BAR, Sound.Chimes);
 
#AddLabel(1, "ZZ$" + " " + "ZZ$"[1], Color.yellow);
## END CODE

#Supply Demand Areas

    input showsupplydemand = yes;

    def zzhigh    = if zzSave == priceH then low else zzhigh[1];
    def dataCount = CompoundValue(1,
                    if zzhigh != zzhigh[1]
                    then dataCount[1] + 1 else dataCount[1], 0);
    def zzhi      = if IsNaN(close)
                    then zzhi[1]
                    else if HighestAll(dataCount) - dataCount == Count - 1
                    then zzhigh else zzhi[1];

    plot zzupline = zzhi;
    zzupline.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
    zzupline.SetDefaultColor(color = Color.RED);
    zzupline.SetLineWeight(1);
    ;

    def zzhigh1 = if zzSave == priceH then high else zzhigh1[1];
    def zzhi1   = if IsNaN(close)
                  then zzhi1[1]
                  else if HighestAll(dataCount) - dataCount == Count - 1
                  then zzhigh1 else zzhi1[1];

    plot zzupline1 = zzhi1;
    zzupline1.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
    zzupline1.SetDefaultColor(color = Color.RED);
    zzupline1.SetLineWeight(1);
    AddCloud(if showsupplydemand then zzupline1 else Double.NaN, zzupline, Color.RED, Color.RED);
;

    def zzlow      = if zzSave == priceL then high else zzlow[1];
    def dataCount1 = CompoundValue(1,
                     if zzlow != zzlow[1]
                     then dataCount1[1] + 1 else dataCount1[1], 0);
    def zzlo       = if IsNaN(close)
                     then zzlo[1]
                     else if HighestAll(dataCount1) - dataCount1 == Count - 1
                     then zzlow else zzlo[1];

    plot zzlowline = zzlo;
    zzlowline.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
    zzlowline.SetDefaultColor(color = Color.GREEN);
    zzlowline.SetLineWeight(1);


    def zzlow1 = if zzSave == priceL then low else zzlow1[1];
    def zzlo1  = if IsNaN(close)
                 then zzlo1[1]
                 else if HighestAll(dataCount1) - dataCount1 == Count - 1
                 then zzlow1 else zzlo1[1];

    plot zzlowline1 = zzlo1;
    zzlowline1.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
    zzlowline1.SetDefaultColor(color = Color.GREEN);
    zzlowline1.SetLineWeight(1);
    AddCloud(if showsupplydemand then zzlowline1 else Double.NaN, zzlowline, Color.GREEN, Color.GREEN);
}

input display   = 2;
input percent   = 2.5;
input atrfactor = 2.5;
input atrlength = 5;

def na  = Double.NaN;


def up1 = if display < 1 then na else sd(1, "at rreversalfactor" = atrfactor, "at rlength" = atrlength, zigzagpercent = percent).zzupline;
def u1  = if display < 1 then na else sd(1, "at rreversalfactor" = atrfactor, "at rlength" = atrlength, zigzagpercent = percent).zzupline1;
AddCloud(up1, u1, Color.RED, Color.RED);

def up2 = if display < 2 then na else sd(2, "at rreversalfactor" = atrfactor, "at rlength" = atrlength, zigzagpercent = percent).zzupline;
def u2  = if display < 2 then na else sd(2, "at rreversalfactor" = atrfactor, "at rlength" = atrlength, zigzagpercent = percent).zzupline1;
AddCloud(up2, u2, Color.RED, Color.RED);

def up3 = if display < 3 then na else sd(3, "at rreversalfactor" = atrfactor, "at rlength" = atrlength, zigzagpercent = percent).zzupline;
def u3  = if display < 3 then na else sd(3, "at rreversalfactor" = atrfactor, "at rlength" = atrlength, zigzagpercent = percent).zzupline1;
AddCloud(up3, u3, Color.RED, Color.RED);

def up4 = if display < 4 then na else sd(4, "at rreversalfactor" = atrfactor, "at rlength" = atrlength, zigzagpercent = percent).zzupline;
def u4  = if display < 4 then na else sd(4, "at rreversalfactor" = atrfactor, "at rlength" = atrlength, zigzagpercent = percent).zzupline1;
AddCloud(up4, u4, Color.RED, Color.RED);

def up5 = if display < 5 then na else sd(5, "at rreversalfactor" = atrfactor, "at rlength" = atrlength, zigzagpercent = percent).zzupline;
def u5  = if display < 5 then na else sd(5, "at rreversalfactor" = atrfactor, "at rlength" = atrlength, zigzagpercent = percent).zzupline1;
AddCloud(up5, u5, Color.RED, Color.RED);

#
def dn1 = if display < 1 then na else sd(1, "at rreversalfactor" = atrfactor, "at rlength" = atrlength, zigzagpercent = percent).zzlowline;
def d1  = if display < 1 then na else sd(1, "at rreversalfactor" = atrfactor, "at rlength" = atrlength, zigzagpercent = percent).zzlowline1;
AddCloud(dn1, d1, Color.GREEN, Color.GREEN);

def dn2 = if display < 2 then na else sd(2, "at rreversalfactor" = atrfactor, "at rlength" = atrlength, zigzagpercent = percent).zzlowline;
def d2  = if display < 2 then na else sd(2, "at rreversalfactor" = atrfactor, "at rlength" = atrlength, zigzagpercent = percent).zzlowline1;
AddCloud(dn2, d2, Color.GREEN, Color.GREEN);

def dn3 = if display < 3 then na else sd(3, "at rreversalfactor" = atrfactor, "at rlength" = atrlength, zigzagpercent = percent).zzlowline;
def d3  = if display < 3 then na else sd(3, "at rreversalfactor" = atrfactor, "at rlength" = atrlength, zigzagpercent = percent).zzlowline1;
AddCloud(dn3, d3, Color.GREEN, Color.GREEN);

def dn4 = if display < 4 then na else sd(4, "at rreversalfactor" = atrfactor, "at rlength" = atrlength, zigzagpercent = percent).zzlowline;
def d4  = if display < 4 then na else sd(4, "at rreversalfactor" = atrfactor, "at rlength" = atrlength, zigzagpercent = percent).zzlowline1;
AddCloud(dn4, d4, Color.GREEN, Color.GREEN);

def dn5 = if display < 5 then na else sd(5, "at rreversalfactor" = atrfactor, "at rlength" = atrlength, zigzagpercent = percent).zzlowline;
def d5  = if display < 5 then na else sd(5, "at rreversalfactor" = atrfactor, "at rlength" = atrlength, zigzagpercent = percent).zzlowline1;
AddCloud(dn5, d5, Color.GREEN, Color.GREEN);
 
I just saw your request. Perhaps this may be useful. It is an adaption of the zigzag script that I added at the bottom, code to draw the lines similar to those in your request.
Code:
# ZigZag High Low Supply Demand
# ZigZag High Low modified in part by Linus' and Lar's code
# ZZZ, with modifications by tomsk
# 1.12.2020

# https://usethinkscript.com/threads/zigzag-high-low-with-supply-demand-zones-for-thinkorswim.172/page-2#post-13790

# V1.0 - 10.09.2016 - ZZZ   - Initial release of ZigZag High Low Supply Demand
# V1.1 - 06.28.2017 - tomsk - Sectionalized code, and rearranged flow of some ZZ Logic
# V1.2 - 01.12.2020 - tomsk - Removed Fibonacci related code per user request

input showBubblesChange = no;  # Price Change between Zigzags
input showBubblesPrice = no;    # Price at Zigzag High/Low
input showBubblesBarCount = no; # Bar Count between Zigzags
input showBubblesVolume = no;   # Volume at Zigzag Reversals

input showArrows = no;
input useAlerts = no;
input numberSuppDemandToShow = 2;
input showSupplyDemand = {default Pivot, Arrow, None};
input showSupplyDemandCloud = yes;

input BubbleOffset = .0005;
input PercentAmount = .01;
input RevAmount = .15;
input ATRreversal = 1.0;
input ATRlength = 5;

def zz = ZigZagHighLow("price h" = high, "price l" = low, "percentage reversal" = PercentAmount,
"absolute reversal" = RevAmount, "atr length" = ATRlength, "atr reversal" = ATRreversal);

def ReversalAmount = if (close * PercentAmount / 100) > Max(RevAmount < ATRreversal * ATRlength, RevAmount)
                     then (close * PercentAmount / 100)
                     else if RevAmount < ATRreversal * ATRlength
                          then ATRreversal * ATRlength
                          else RevAmount;
# Zig Zag Specific Data

def zzSave = if !IsNaN(zz) then zz else GetValue(zzSave, 1);
def chg = (if zzSave == high then high else low) - GetValue(zzSave, 1);
def isUp = chg >= 0;
def isConf = AbsValue(chg) >= ReversalAmount or (IsNaN(GetValue(zz, 1)) and GetValue(isConf, 1));

# Price Change Between ZigZags

def xxHigh = if zzSave == high then high else xxHigh[1];
def chgHigh = high - xxHigh[1];
def xxLow = if zzSave == low then low else xxLow[1];
def chgLow = low - xxLow[1];

# Bar Count Between ZigZags

def zzCount = if zzSave[1] != zzSave then 1 else if zzSave[1] == zzSave then zzCount[1] + 1 else 0;
def zzCountHiLo = if zzCountHiLo[1] == 0 and (zzSave == high or zzSave == low) then 1
                  else if zzSave == high or zzSave == low then zzCountHiLo[1] + 1
                  else zzCountHiLo[1];
def zzHiLo = if zzSave == high or zzSave == low then zzCountHiLo else zzCountHiLo + 1;
def zzCountHigh = if zzSave == high then zzCount[1] else Double.NaN;
def zzCountLow  = if zzSave == low then zzCount[1] else Double.NaN;

# Volume at Reversals

def vol = if BarNumber() == 0 then 0 else volume + vol[1];
def vol1 = if BarNumber() == 1 then volume else vol1[1];
def xxVol = if zzSave == high or zzSave == low then TotalSum(volume) else xxVol[1];
def chgVol =  if xxVol - xxVol[1] + vol1 == vol then vol else xxVol - xxVol[1];

# Label for Confirmed/Unconfirmed Status of Current Zigzag

AddLabel(BarNumber() != 1, (if isConf then "Confirmed " else "Unconfirmed ") + "ZigZag: " + chg,
    if !isConf then Color.Dark_Orange else if isUp then Color.Green else Color.Red);

# Zig Zag Plot

plot zzp = if isUp <= 1 then zz else Double.NaN;
zzp.AssignValueColor(if isUp then Color.Green else if !isUp then Color.Red else Color.Dark_Orange);
zzp.SetStyle(Curve.FIRM);
zzp.EnableApproximation();

plot zzdot = if isUp <= 1 then zz else Double.NaN;
zzdot.setpaintingStrategy(paintingStrategy.POINTS);
zzdot.setlineWeight(5);
zzdot.assignvalueColor(if zzsave==high then color.yellow else color.blue);

# Bubbles

# Price Change between Zigzags

AddChartBubble(showBubblesChange and !IsNaN(zz) and BarNumber() != 1, if isUp then high * (1 + BubbleOffset) else low * (1 - BubbleOffset), "$" + chg, if isUp and chgHigh > 0 then Color.Green else if isUp and chgHigh < 0 then Color.Red else if isUp then Color.Yellow else if !isUp and chgLow > 0 then Color.Green else if !isUp and chgLow < 0 then Color.Red else Color.Yellow, isUp);

# Price at Zigzag High/Low

AddChartBubble(showBubblesPrice and !IsNaN(zz) and BarNumber() != 1, if isUp then high * (1 + BubbleOffset) else low * (1 - BubbleOffset), if isUp then "$" + high else "$" + low , if isUp and chgHigh > 0 then Color.Green else if isUp and chgHigh < 0 then Color.Red else if isUp then Color.Yellow else if !isUp and chgLow > 0 then Color.Green else if !isUp and chgLow < 0 then Color.Red else Color.Yellow, isUp);

# Bar Count between Zigzags

AddChartBubble(showBubblesBarCount and !IsNaN(zz) and BarNumber() != 1, if isUp then high * (1 + BubbleOffset) else low * (1 - BubbleOffset), if zzSave == high then zzCountHigh else zzCountLow, if isUp and chgHigh > 0 then Color.Green else if isUp and chgHigh < 0 then Color.Red else if isUp then Color.Yellow else if !isUp and chgLow > 0 then Color.Green else if !isUp and chgLow < 0 then Color.Red else Color.Yellow, if isUp then yes else no );

# Volume at Zigzag Reversals

AddChartBubble(showBubblesVolume and !IsNaN(zz) and BarNumber() != 1, if isUp then high * (1 + bubbleoffset) else low * (1 - bubbleoffset), chgVol,if isUp and chghigh > 0 then Color.Green else if isUp and chghigh < 0 then Color.Red else if isUp then Color.Yellow else if !isUp and chglow > 0 then Color.Green else if !isUp and chglow < 0 then Color.Red else Color.Yellow, if isUp then yes else no );

# Arrows

def zzL = if !IsNaN(zz) and !isUp then low else GetValue(zzL, 1);
def zzH = if !IsNaN(zz) and isUp then high else GetValue(zzH, 1);

def dir = CompoundValue(1, if zzL != zzL[1] or low == zzL[1] and low == zzSave then 1
                           else if zzH != zzH[1] or high == zzH[1] and high == zzSave then -1
                           else dir[1], 0);

def signal = CompoundValue(1, if dir > 0 and low > zzL
                              then if signal[1] <= 0 then 1 else signal[1]
                              else if dir < 0 and high < zzH
                                   then if signal[1] >= 0 then -1 else signal[1]
                                   else signal[1], 0);

plot U1 = showArrows and signal > 0 and signal[1] <= 0;
U1.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
U1.SetDefaultColor(Color.Green);
U1.SetLineWeight(4);

plot D1 = showArrows and signal < 0 and signal[1] >= 0;
D1.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);
D1.SetDefaultColor(Color.Red);
D1.SetLineWeight(4);

# Alerts

Alert(useAlerts and U1, "ZIG-UP", Alert.BAR, Sound.Bell);
Alert(useAlerts and D1, "ZAG-DOWN", Alert.BAR, Sound.Chimes);

# Supply Demand Areas

def data1 = CompoundValue(1, if (zzSave == high or zzSave == low) then data1[1] + 1 else data1[1], 0);
def dataCount1 = (HighestAll(data1) - data1[1]);
def idx = showSupplyDemand == showSupplyDemand.Pivot;

def rLow;
def rHigh;
if signal crosses 0 {
    rLow = low[idx];
    rHigh = high[idx];
} else {
    rLow = rLow[1];
    rHigh = rHigh[1];
}

plot HighLine = if dataCount1 <= numberSuppDemandToShow and
                   showSupplyDemand != showSupplyDemand.None and
                   !isNaN(close) and
                   rHigh != 0
                then rHigh
                else Double.NaN;
HighLine.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
HighLine.AssignValueColor(if signal > 0 then Color.Green else Color.Red);

plot LowLine = if dataCount1 <= numberSuppDemandToShow and
                  showSupplyDemand != showSupplyDemand.None and
                  !isNaN(close) and
                  rLow != 0
               then rLow
               else Double.NaN;
LowLine.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
LowLine.AssignValueColor(if signal > 0 then Color.Green else Color.Red);

def hlUp = if signal > 0 then HighLine else Double.NaN;
def hlDn = if signal < 0 then HighLine else Double.NaN;

AddCloud(if showSupplyDemandCloud then hlUp else Double.NaN, LowLine, Color.Light_Green, Color.Light_Green);
AddCloud(if showSupplyDemandCloud then hlDn else Double.NaN, LowLine, Color.Light_Red, Color.Light_Red);


#Moification per Usethinkscript request to draw lines form one zzlow to another and the same for zzhigh to another zzhigh 
def shsl_low = if zzsave==low then zz else shsl_low[1];
plot swinglow = shsl_low;
swinglow.enableApproximation();
def slcolor = if swinglow != swinglow[1] and swinglow > swinglow[1]
              then 1
              else if slcolor[1] == 1 and swinglow == swinglow[1]
              then 1
              else 0;
swinglow.assignvalueColor(if slcolor == 1 then color.green else color.red);
swinglow.setlineWeight(3);

def shsl_high = if zzsave==high then zz else shsl_high[1];
plot swinghigh = shsl_high;
swinghigh.enableApproximation();
swinghigh.setlineWeight(3);

def shcolor = if swinghigh != swinghigh[1] and swinghigh > swinghigh[1]
              then 1
              else if slcolor[1] == 1 and swinghigh == swinghigh[1]
              then 1
              else 0;
swinghigh.assignvalueColor(if shcolor == 1 then color.green else color.red);

# End ZigZag High Low Supply Demand

Capture.jpg
Hello,

Thank you for this code @SleepyZ . I am using this, but am curious if there is a way to have the swing high/low lines plot at the last confirmed zig zag high/low instead of following price down to the current bar? Visually this is a bit messy to look at. I can just change the drawing style to something like square, but it looks cleaner as a line. Let me know if you need clarification.

Thanks!
 
@buytheabe You can change the line style to this:

IMoEtAn.png


And as a reminder, this is a repainting indicator.

Thanks for the suggestion. This does theoretically solve my problem, similar to using the square drawstyle. However, I do prefer having the prior swings connected visually. It just gets messy when the line drops to the current bar without the zig zag reversal parameters having been met.

It is something I can work around if necessary, but was curious if there is an easy alteration in the code that could prevent the current swing high/low line from dropping down to the current bar.
 
Thanks for the suggestion. This does theoretically solve my problem, similar to using the square drawstyle. However, I do prefer having the prior swings connected visually. It just gets messy when the line drops to the current bar without the zig zag reversal parameters having been met.

It is something I can work around if necessary, but was curious if there is an easy alteration in the code that could prevent the current swing high/low line from dropping down to the current bar.

This might work the way you want. The code now does not look at the last bar to plot zz or swing lines unless the prior bar is the possible pivot. Since this indicator repaints, the future bars activity can change the plot of possible pivot.

The image shows the prior code on the left panel and the revised code on the right panel.

Screenshot-2023-03-23-100624.png
Code:
# ZigZag High Low Supply Demand
# ZigZag High Low modified in part by Linus' and Lar's code
# ZZZ, with modifications by tomsk
# 1.12.2020

# https://usethinkscript.com/threads/zigzag-high-low-with-supply-demand-zones-for-thinkorswim.172/page-2#post-13790

# V1.0 - 10.09.2016 - ZZZ   - Initial release of ZigZag High Low Supply Demand
# V1.1 - 06.28.2017 - tomsk - Sectionalized code, and rearranged flow of some ZZ Logic
# V1.2 - 01.12.2020 - tomsk - Removed Fibonacci related code per user request

input showBubblesChange = no;  # Price Change between Zigzags
input showBubblesPrice = no;    # Price at Zigzag High/Low
input showBubblesBarCount = no; # Bar Count between Zigzags
input showBubblesVolume = no;   # Volume at Zigzag Reversals

input showArrows = no;
input useAlerts = no;
input numberSuppDemandToShow = 2;
input showSupplyDemand = {default Pivot, Arrow, None};
input showSupplyDemandCloud = yes;

input BubbleOffset = .0005;
input PercentAmount = .01;
input RevAmount = .15;
input ATRreversal = 1.0;
input ATRlength = 5;

def zz = ZigZagHighLow("price h" = high, "price l" = low, "percentage reversal" = PercentAmount,
"absolute reversal" = RevAmount, "atr length" = ATRlength, "atr reversal" = ATRreversal);

def ReversalAmount = if (close * PercentAmount / 100) > Max(RevAmount < ATRreversal * ATRlength, RevAmount)
                     then (close * PercentAmount / 100)
                     else if RevAmount < ATRreversal * ATRlength
                          then ATRreversal * ATRlength
                          else RevAmount;
# Zig Zag Specific Data

def zzSave = if !IsNaN(zz) then zz else GetValue(zzSave, 1);
def chg = (if zzSave == high then high else low) - GetValue(zzSave, 1);
def isUp = chg >= 0;
def isConf = AbsValue(chg) >= ReversalAmount or (IsNaN(GetValue(zz, 1)) and GetValue(isConf, 1));

# Price Change Between ZigZags

def xxHigh = if zzSave == high then high else xxHigh[1];
def chgHigh = high - xxHigh[1];
def xxLow = if zzSave == low then low else xxLow[1];
def chgLow = low - xxLow[1];

# Bar Count Between ZigZags

def zzCount = if zzSave[1] != zzSave then 1 else if zzSave[1] == zzSave then zzCount[1] + 1 else 0;
def zzCountHiLo = if zzCountHiLo[1] == 0 and (zzSave == high or zzSave == low) then 1
                  else if zzSave == high or zzSave == low then zzCountHiLo[1] + 1
                  else zzCountHiLo[1];
def zzHiLo = if zzSave == high or zzSave == low then zzCountHiLo else zzCountHiLo + 1;
def zzCountHigh = if zzSave == high then zzCount[1] else Double.NaN;
def zzCountLow  = if zzSave == low then zzCount[1] else Double.NaN;

# Volume at Reversals

def vol = if BarNumber() == 0 then 0 else volume + vol[1];
def vol1 = if BarNumber() == 1 then volume else vol1[1];
def xxVol = if zzSave == high or zzSave == low then TotalSum(volume) else xxVol[1];
def chgVol =  if xxVol - xxVol[1] + vol1 == vol then vol else xxVol - xxVol[1];

# Label for Confirmed/Unconfirmed Status of Current Zigzag

AddLabel(BarNumber() != 1, (if isConf then "Confirmed " else "Unconfirmed ") + "ZigZag: " + chg,
    if !isConf then Color.Dark_Orange else if isUp then Color.Green else Color.Red);

# Zig Zag Plot

def lastbar = if isnan(close) then 0 else barnumber();
plot zzp = if  barnumber()==highestall(lastbar) then double.nan else if isUp <= 1 then zz else Double.NaN;
zzp.AssignValueColor(if isUp then Color.Green else if !isUp then Color.Red else Color.Dark_Orange);
zzp.SetStyle(Curve.FIRM);
zzp.EnableApproximation();

plot zzdot = if barnumber()==highestall(lastbar) then double.nan else if isUp <= 1 then zz else Double.NaN;
zzdot.setpaintingStrategy(paintingStrategy.POINTS);
zzdot.setlineWeight(5);
zzdot.assignvalueColor(if zzsave==high then color.yellow else color.blue);

# Bubbles

# Price Change between Zigzags

AddChartBubble(showBubblesChange and !IsNaN(zz) and BarNumber() != 1, if isUp then high * (1 + BubbleOffset) else low * (1 - BubbleOffset), "$" + chg, if isUp and chgHigh > 0 then Color.Green else if isUp and chgHigh < 0 then Color.Red else if isUp then Color.Yellow else if !isUp and chgLow > 0 then Color.Green else if !isUp and chgLow < 0 then Color.Red else Color.Yellow, isUp);

# Price at Zigzag High/Low

AddChartBubble(showBubblesPrice and !IsNaN(zz) and BarNumber() != 1, if isUp then high * (1 + BubbleOffset) else low * (1 - BubbleOffset), if isUp then "$" + high else "$" + low , if isUp and chgHigh > 0 then Color.Green else if isUp and chgHigh < 0 then Color.Red else if isUp then Color.Yellow else if !isUp and chgLow > 0 then Color.Green else if !isUp and chgLow < 0 then Color.Red else Color.Yellow, isUp);

# Bar Count between Zigzags

AddChartBubble(showBubblesBarCount and !IsNaN(zz) and BarNumber() != 1, if isUp then high * (1 + BubbleOffset) else low * (1 - BubbleOffset), if zzSave == high then zzCountHigh else zzCountLow, if isUp and chgHigh > 0 then Color.Green else if isUp and chgHigh < 0 then Color.Red else if isUp then Color.Yellow else if !isUp and chgLow > 0 then Color.Green else if !isUp and chgLow < 0 then Color.Red else Color.Yellow, if isUp then yes else no );

# Volume at Zigzag Reversals

AddChartBubble(showBubblesVolume and !IsNaN(zz) and BarNumber() != 1, if isUp then high * (1 + bubbleoffset) else low * (1 - bubbleoffset), chgVol,if isUp and chghigh > 0 then Color.Green else if isUp and chghigh < 0 then Color.Red else if isUp then Color.Yellow else if !isUp and chglow > 0 then Color.Green else if !isUp and chglow < 0 then Color.Red else Color.Yellow, if isUp then yes else no );

# Arrows

def zzL = if !IsNaN(zz) and !isUp then low else GetValue(zzL, 1);
def zzH = if !IsNaN(zz) and isUp then high else GetValue(zzH, 1);

def dir = CompoundValue(1, if zzL != zzL[1] or low == zzL[1] and low == zzSave then 1
                           else if zzH != zzH[1] or high == zzH[1] and high == zzSave then -1
                           else dir[1], 0);

def signal = CompoundValue(1, if dir > 0 and low > zzL
                              then if signal[1] <= 0 then 1 else signal[1]
                              else if dir < 0 and high < zzH
                                   then if signal[1] >= 0 then -1 else signal[1]
                                   else signal[1], 0);

plot U1 = showArrows and signal > 0 and signal[1] <= 0;
U1.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
U1.SetDefaultColor(Color.Green);
U1.SetLineWeight(4);

plot D1 = showArrows and signal < 0 and signal[1] >= 0;
D1.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);
D1.SetDefaultColor(Color.Red);
D1.SetLineWeight(4);

# Alerts

Alert(useAlerts and U1, "ZIG-UP", Alert.BAR, Sound.Bell);
Alert(useAlerts and D1, "ZAG-DOWN", Alert.BAR, Sound.Chimes);

# Supply Demand Areas

def data1 = CompoundValue(1, if (zzSave == high or zzSave == low) then data1[1] + 1 else data1[1], 0);
def dataCount1 = (HighestAll(data1) - data1[1]);
def idx = showSupplyDemand == showSupplyDemand.Pivot;

def rLow;
def rHigh;
if signal crosses 0 {
    rLow = low[idx];
    rHigh = high[idx];
} else {
    rLow = rLow[1];
    rHigh = rHigh[1];
}

plot HighLine = if dataCount1 <= numberSuppDemandToShow and
                   showSupplyDemand != showSupplyDemand.None and
                   !isNaN(close) and
                   rHigh != 0
                then rHigh
                else Double.NaN;
HighLine.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
HighLine.AssignValueColor(if signal > 0 then Color.Green else Color.Red);

plot LowLine = if dataCount1 <= numberSuppDemandToShow and
                  showSupplyDemand != showSupplyDemand.None and
                  !isNaN(close) and
                  rLow != 0
               then rLow
               else Double.NaN;
LowLine.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
LowLine.AssignValueColor(if signal > 0 then Color.Green else Color.Red);

def hlUp = if signal > 0 then HighLine else Double.NaN;
def hlDn = if signal < 0 then HighLine else Double.NaN;

AddCloud(if showSupplyDemandCloud then hlUp else Double.NaN, LowLine, Color.Light_Green, Color.Light_Green);
AddCloud(if showSupplyDemandCloud then hlDn else Double.NaN, LowLine, Color.Light_Red, Color.Light_Red);


#Moification per Usethinkscript request to draw lines form one zzlow to another and the same for zzhigh to another zzhigh
def shsl_low = if zzsave==low then zz else shsl_low[1];
plot swinglow = if barnumber()==highestall(lastbar) then double.nan else shsl_low;
swinglow.enableApproximation();
def slcolor = if swinglow != swinglow[1] and swinglow > swinglow[1]
              then 1
              else if slcolor[1] == 1 and swinglow == swinglow[1]
              then 1
              else 0;
swinglow.assignvalueColor(if slcolor == 1 then color.green else color.red);
swinglow.setlineWeight(3);

def shsl_high = if zzsave==high then zz else shsl_high[1];
plot swinghigh =  if barnumber()==highestall(lastbar) then double.nan else shsl_high;
swinghigh.enableApproximation();
swinghigh.setlineWeight(3);

def shcolor = if swinghigh != swinghigh[1] and swinghigh > swinghigh[1]
              then 1
              else if slcolor[1] == 1 and swinghigh == swinghigh[1]
              then 1
              else 0;
swinghigh.assignvalueColor(if shcolor == 1 then color.green else color.red);

# End ZigZag High Low Supply Demand
 
This might work the way you want. The code now does not look at the last bar to plot zz or swing lines unless the prior bar is the possible pivot. Since this indicator repaints, the future bars activity can change the plot of possible pivot.

The image shows the prior code on the left panel and the revised code on the right panel.
This is exactly what I was looking for. Thank you so much for your help! I really appreciate it.
 
Here is the ZigZag High Low indicator with Supply and Demand Zones. In addition to that, we also have Fibonacci extension, alerts, reversal signals, and price change shown in bubbles style. You can adjust these features to your liking after adding the indicator.

eXpGylF.png


thinkScript Code

Rich (BB code):
# Archive Name: ZigZag High Low with Supply DemandIndex and Fibs_Linus_Lar
# Archive Section: Scripts
# Suggested Tos Name: ZigZagHighLow_SupplyDemand_FibExtensions_LinusLar
# Archive Date:
# Archive Notes:

#TOS version ZigZagHighLow modified in part by Linus' and Lar's code
input bubbleoffset = .0005;
input percentamount = .01;
input revAmount = .15;
input atrreversal = 1.0;
input atrlength = 5;
def zz = ZigZagHighLow("price h" = high, "price l" = low, "percentage reversal" = percentAmount, "absolute reversal" = revAmount, "atr length" =atrlength, "atr reversal" = atrreversal);
def reversalAmount        = if (close * percentamount / 100) > Max(revAmount < atrreversal * atrlength, revAmount) then (close * percentamount / 100) else if revAmount < atrreversal * atrlength then atrreversal * atrlength else revAmount;
rec zzSave = if !IsNaN(zz) then zz else GetValue(zzSave, 1);
def chg = (if zzSave == high then high else low) - GetValue(zzSave, 1);
def isUp = chg >= 0;
rec isConf = AbsValue(chg) >= reversalAmount or (IsNaN(GetValue(zz, 1)) and GetValue(isConf, 1));
def zzd = if isUp then 1 else 0;
plot zzp = if zzd <= 1 then zz else Double.NaN;
zzp.AssignValueColor(if zzd == 1 then Color.GREEN else if zzd == 0 then Color.RED else Color.DARK_ORANGE);
zzp.SetStyle(Curve.FIRM);
zzp.EnableApproximation();

#Price Change between zigzags
def xxhigh = if zzSave == high then  high else xxhigh[1];
def chghigh = high - xxhigh[1];
def xxlow = if zzSave == low then low else xxlow[1];
def chglow = low - xxlow[1];
input showBubbleschange = yes;
AddChartBubble(showBubbleschange and !IsNaN(zz) and BarNumber() != 1, if isUp then high * (1 + bubbleoffset)  else low * (1 - bubbleoffset)   , "$" + chg , if isUp and chghigh > 0 then Color.GREEN else if isUp and chghigh < 0 then Color.RED else if isUp then Color.YELLOW else if !isUp and chglow > 0 then Color.GREEN else if !isUp and chglow < 0 then Color.RED else Color.YELLOW, isUp);

#Price at High/Low
input showBubblesprice = no;
AddChartBubble(showBubblesprice and !IsNaN(zz) and BarNumber() != 1, if isUp then high * (1 + bubbleoffset)  else low * (1 - bubbleoffset)   , if isUp then "$" + high else "$" + low , if isUp and chghigh > 0 then Color.GREEN else if isUp and chghigh < 0 then Color.RED else if isUp then Color.YELLOW else if !isUp and chglow > 0 then Color.GREEN else if !isUp and chglow < 0 then Color.RED else Color.YELLOW, isUp);

#Label for Confirmed/Unconfirmed Status of Current Zigzag
AddLabel(BarNumber() != 1, (if isConf then "Confirmed " else "Unconfirmed ") + "ZigZag: " + chg, if !isConf then Color.DARK_ORANGE else if isUp then Color.GREEN else Color.RED);

#Bar Count between zigzags
rec zzcount = if zzSave[1] != zzSave then 1 else if zzSave[1] == zzSave then zzcount[1] + 1 else 0;
def zzcounthilo   =  if zzcounthilo[1] == 0 and (zzSave == high or zzSave == low) then 1 else if zzSave == high or zzSave == low then zzcounthilo[1] + 1 else zzcounthilo[1];
def zzhilo = if zzSave == high or zzSave == low then zzcounthilo else zzcounthilo + 1;
def zzcounthigh = if zzSave == high then zzcount[1] else Double.NaN;
def zzcountlow =  if zzSave == low then zzcount[1] else Double.NaN;
input showBubblesbarcount = no;
AddChartBubble(showBubblesbarcount and !IsNaN(zz) and BarNumber() != 1, if isUp then high * (1 + bubbleoffset)  else low * (1 - bubbleoffset)  , if zzSave == high then zzcounthigh else zzcountlow, if isUp and chghigh > 0 then Color.GREEN else if isUp and chghigh < 0 then Color.RED else if isUp then Color.YELLOW else if !isUp and chglow > 0 then Color.GREEN else if !isUp and chglow < 0 then Color.RED else Color.YELLOW, if isUp then yes else no );

#Arrows
def zzL = if !IsNaN(zz) and !isUp then low else GetValue(zzL, 1);
def zzH = if !IsNaN(zz) and isUp then high else GetValue(zzH, 1);
def dir = CompoundValue(1, if zzL != zzL[1] or low==zzl[1] and low==zzsave then 1 else if zzH != zzH[1] or high==zzh[1] and high==zzsave then -1 else dir[1], 0);
def signal = CompoundValue(1, if dir > 0 and low > zzL then if signal[1] <= 0 then 1 else signal[1] else if dir < 0 and high < zzH then if signal[1] >= 0 then -1 else signal[1]    else signal[1], 0);
input showarrows = no;
plot U1 = showarrows and signal > 0 and signal[1] <= 0;
U1.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
U1.SetDefaultColor(Color.GREEN);
U1.SetLineWeight(4);
plot D1 = showarrows and signal < 0 and signal[1] >= 0;
D1.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);
D1.SetDefaultColor(Color.RED);
D1.SetLineWeight(4);

#Alerts
input usealerts = no;
Alert(usealerts and U1, "ZIG-UP", Alert.BAR, Sound.Bell);
Alert(usealerts and D1, "ZAG-DOWN", Alert.BAR, Sound.Chimes);

#Supply Demand Areas
rec data1 = CompoundValue(1, if (zzSave == high or zzSave == low) then data1[1] + 1 else data1[1], 0);
def datacount1 = (HighestAll(data1) - data1[1]);
input numbersuppdemandtoshow = 2;
input showSupplyDemand = {default Pivot, Arrow, None};
def idx = if showSupplyDemand == showSupplyDemand.Pivot then 1 else 0;
def rLow;
def rHigh;
if signal crosses 0 {
    rLow = low[idx];
    rHigh = high[idx];
} else {
    rLow = rLow[1];
    rHigh = rHigh[1];
}
plot HighLine = if datacount1 <= numbersuppdemandtoshow and showSupplyDemand != showSupplyDemand.None and !isNaN(close) and rHigh != 0 then rHigh else Double.NaN;
HighLine.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
HighLine.AssignValueColor(if signal > 0 then Color.GREEN else Color.RED);

plot LowLine = if datacount1 <= numbersuppdemandtoshow and  showSupplyDemand != showSupplyDemand.None and !isNaN(close) and rLow != 0 then rLow else Double.NaN;
LowLine.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
LowLine.AssignValueColor(if signal > 0 then Color.GREEN else Color.RED);

def hlUp = if signal > 0 then HighLine else Double.NaN;
def hlDn = if signal < 0 then HighLine else Double.NaN;

input showsupplydemandcloud = yes;
AddCloud(if showsupplydemandcloud then hlUp else double.nan, LowLine, Color.LIGHT_GREEN, Color.LIGHT_GREEN);
AddCloud(if showsupplydemandcloud then hlDn else double.nan, LowLine, Color.LIGHT_RED, Color.LIGHT_RED);

#Store Previous Data
def zzsave1 = if !IsNaN(zzSave) then zzSave else zzsave1[1];
def zzsave2 = zzsave1;
rec priorzz1 = if zzsave2  != zzsave2[1]  then zzsave2[1]  else priorzz1[1];
rec priorzz2 = if priorzz1 != priorzz1[1] then priorzz1[1] else priorzz2[1];
rec priorzz3 = if priorzz2 != priorzz2[1] then priorzz2[1] else priorzz3[1];

#Fibonacci Extensions
rec data = CompoundValue(1, if (zzSave == high or zzSave == low) then data[1] + 1 else data[1], 0);
def datacount = (HighestAll(data) - data[1]);
input numberextfibstoshow = 2;
rec cpo = if dir[1] != dir then 0 else 1;
input showFibExtLines = yes;
input showtodayonly = no;
def today = if showtodayonly == yes then GetDay() == GetLastDay() else GetDay();
def extfib1 = if zzSave == high then high - AbsValue(priorzz2 - priorzz1) * 1
else extfib1[1];
plot extfib100 = if datacount <= numberextfibstoshow and today and showFibExtLines and !IsNaN(extfib1) and dir < 0 and cpo != 0 then extfib1[1] else Double.NaN;
extfib100.SetPaintingStrategy(PaintingStrategy.DASHES);
extfib100.SetDefaultColor(Color.RED);
extfib100.SetLineWeight(1);
extfib100.HideBubble();
def extfib1a = if zzSave == high then high - AbsValue(priorzz2 - priorzz1) * 0.382
else extfib1a[1];
plot extfib382 = if datacount <= numberextfibstoshow and today and showFibExtLines and !IsNaN(extfib1a) and dir < 0 and cpo != 0 then extfib1a[1] else Double.NaN;
extfib382.SetPaintingStrategy(PaintingStrategy.DASHES);
extfib382.SetDefaultColor(Color.RED);
extfib382.SetLineWeight(1);
extfib382.HideBubble();
def extfib2 = if zzSave == high then high - AbsValue(priorzz2 - priorzz1) *
0.618 else extfib2[1];
plot extfib618 = if datacount <= numberextfibstoshow and today and showFibExtLines and !IsNaN(extfib2) and dir < 0 and cpo != 0  then extfib2[1] else Double.NaN;
extfib618.SetPaintingStrategy(PaintingStrategy.DASHES);
extfib618.SetDefaultColor(Color.RED);
extfib618.SetLineWeight(1);
extfib618.HideBubble();
def extfib3 = if zzSave == high then high - AbsValue(priorzz2 - priorzz1) *
1.618 else extfib3[1];
plot extfib1618 = if datacount <= numberextfibstoshow and today and showFibExtLines and  !IsNaN(extfib3) and dir < 0  and cpo != 0  then extfib3[1] else Double.NaN;
extfib1618.SetPaintingStrategy(PaintingStrategy.DASHES);
extfib1618.SetDefaultColor(Color.RED);
extfib1618.SetLineWeight(1);
extfib1618.HideBubble();
def extfib3a = if zzSave == high then high - AbsValue(priorzz2 - priorzz1) *
2.000 else extfib3a[1];
plot extfib2000 = if datacount <= numberextfibstoshow and today and showFibExtLines and  !IsNaN(extfib3a) and dir < 0  and cpo != 0  then extfib3a[1] else Double.NaN;
extfib2000.SetPaintingStrategy(PaintingStrategy.DASHES);
extfib2000.SetDefaultColor(Color.RED);
extfib2000.SetLineWeight(1);
extfib2000.HideBubble();
def extfib4 = if zzSave == high then high - AbsValue(priorzz2 - priorzz1) *
2.618 else extfib4[1];
plot extfib2618 = if  datacount <= numberextfibstoshow and today and showFibExtLines and !IsNaN(extfib4) and dir < 0  and cpo != 0  then extfib4[1] else Double.NaN;
extfib2618.SetPaintingStrategy(PaintingStrategy.DASHES);
extfib2618.SetDefaultColor(Color.RED);
extfib2618.SetLineWeight(1);
extfib2618.HideBubble();
def extfib5 = if zzSave == high then high - AbsValue(priorzz2 - priorzz1) *
3.618 else extfib5[1];
plot extfib3618 = if  datacount <= numberextfibstoshow and today and showFibExtLines and !IsNaN(extfib5) and dir < 0  and cpo != 0  then extfib5[1] else Double.NaN;
extfib3618.SetPaintingStrategy(PaintingStrategy.DASHES);
extfib3618.SetDefaultColor(Color.RED);
extfib3618.SetLineWeight(1);
extfib3618.HideBubble();
def extfib1_ = if zzSave == low then low + AbsValue(priorzz2 - priorzz1) * 1
else extfib1_[1];
plot extfib100_ = if datacount <= numberextfibstoshow and today and showFibExtLines and !IsNaN(extfib1_) and dir > 0 and cpo != 0 then extfib1_[1] else Double.NaN;
extfib100_.SetPaintingStrategy(PaintingStrategy.DASHES);
extfib100_.SetDefaultColor(Color.GREEN);
extfib100_.SetLineWeight(1);
extfib100_.HideBubble();
def extfib1a_ = if zzSave == low then low + AbsValue(priorzz2 - priorzz1) * 0.382
else extfib1a_[1];
plot extfib382_ = if datacount <= numberextfibstoshow and today and showFibExtLines and !IsNaN(extfib1a_) and dir > 0 and cpo != 0 then extfib1a_[1] else Double.NaN;
extfib382_.SetPaintingStrategy(PaintingStrategy.DASHES);
extfib382_.SetDefaultColor(Color.GREEN);
extfib382_.SetLineWeight(1);
extfib382_.HideBubble();
def extfib2_ = if zzSave == low then low + AbsValue(priorzz2 - priorzz1) *
0.618 else extfib2_[1];
plot extfib618_ = if datacount <= numberextfibstoshow and today and showFibExtLines and !IsNaN(extfib2_) and dir > 0  and cpo != 0  then extfib2_[1] else Double.NaN;
extfib618_.SetPaintingStrategy(PaintingStrategy.DASHES);
extfib618_.SetDefaultColor(Color.GREEN);
extfib618_.SetLineWeight(1);
extfib618_.HideBubble();
def extfib3_ = if zzSave == low then low + AbsValue(priorzz2 - priorzz1) *
1.618 else extfib3_[1];
plot extfib1618_ = if datacount <= numberextfibstoshow and today and showFibExtLines and !IsNaN(extfib3_) and dir > 0  and cpo != 0  then extfib3_[1] else Double.NaN;
extfib1618_.SetPaintingStrategy(PaintingStrategy.DASHES);
extfib1618_.SetDefaultColor(Color.GREEN);
extfib1618_.SetLineWeight(1);
extfib1618_.HideBubble();
def extfib3a_ = if zzSave == low then low + AbsValue(priorzz2 - priorzz1) *
2.000 else extfib3a_[1];
plot extfib2000_ = if datacount <= numberextfibstoshow and today and showFibExtLines and !IsNaN(extfib3a_) and dir > 0  and cpo != 0  then extfib3a_[1] else Double.NaN;
extfib2000_.SetPaintingStrategy(PaintingStrategy.DASHES);
extfib2000_.SetDefaultColor(Color.GREEN);
extfib2000_.SetLineWeight(1);
extfib2000_.HideBubble();
def extfib4_ = if zzSave == low then low + AbsValue(priorzz2 - priorzz1) *
2.618 else extfib4_[1];
plot extfib2618_ = if datacount <= numberextfibstoshow and today and showFibExtLines and !IsNaN(extfib4_) and dir > 0  and cpo != 0  then extfib4_[1]  else Double.NaN;
extfib2618_.SetPaintingStrategy(PaintingStrategy.DASHES);
extfib2618_.SetDefaultColor(Color.GREEN);
extfib2618_.SetLineWeight(1);
extfib2618_.HideBubble();
def extfib5_ = if zzSave == low then low + AbsValue(priorzz2 - priorzz1) *
3.618 else extfib5_[1];
plot extfib3618_ = if datacount <= numberextfibstoshow and today and showFibExtLines and !IsNaN(extfib5_) and dir > 0  and cpo != 0  then extfib5_[1]  else Double.NaN;
extfib3618_.SetPaintingStrategy(PaintingStrategy.DASHES);
extfib3618_.SetDefaultColor(Color.GREEN);
extfib3618_.SetLineWeight(1);
extfib3618_.HideBubble();
input fibextbubblespacesinexpansion = 8;
def b = fibextbubblespacesinexpansion;
def direction = if !isUp then 1 else 0;
AddChartBubble( direction[b + 1] == 1 and showFibExtLines and !IsNaN(close[b + 1]) and IsNaN(close), extfib1[b + 2], "100%", Color.RED, no);
AddChartBubble( direction[b + 1] == 1 and showFibExtLines and !IsNaN(close[b + 1]) and IsNaN(close), extfib1a[b + 2], "38.2%", Color.RED, no);
AddChartBubble( direction[b + 1] == 1 and showFibExtLines and !IsNaN(close[b + 1]) and IsNaN(close), extfib2[b + 2], "61.8%", Color.RED, no);
AddChartBubble( direction[b + 1] == 1 and showFibExtLines and !IsNaN(close[b + 1]) and IsNaN(close), extfib3[b + 2], "161.8%", Color.RED, no);
AddChartBubble( direction[b + 1] == 1 and showFibExtLines and !IsNaN(close[b + 1]) and IsNaN(close), extfib3a[b + 2], "200%", Color.RED, no);
AddChartBubble( direction[b + 1] == 1 and showFibExtLines and !IsNaN(close[b + 1]) and IsNaN(close), extfib4[b + 2], "261.8%", Color.RED, no);
AddChartBubble( direction[b + 1] == 1 and showFibExtLines and !IsNaN(close[b + 1]) and IsNaN(close), extfib5[b + 2], "361.8%", Color.RED, no);
AddChartBubble( direction[b + 1] == 0 and showFibExtLines and !IsNaN(close[b + 1]) and IsNaN(close), extfib1_[b + 2], "100%", Color.GREEN, yes);
AddChartBubble( direction[b + 1] == 0 and showFibExtLines and !IsNaN(close[b + 1]) and IsNaN(close), extfib1a_[b + 2], "38.2%", Color.GREEN, yes);
AddChartBubble( direction[b + 1] == 0 and showFibExtLines and !IsNaN(close[b + 1]) and IsNaN(close), extfib2_[b + 2], "61.8%", Color.GREEN, yes);
AddChartBubble( direction[b + 1] == 0 and showFibExtLines and !IsNaN(close[b + 1]) and IsNaN(close), extfib3_[b + 2], "161.8%", Color.GREEN, yes);
AddChartBubble( direction[b + 1] == 0 and showFibExtLines and !IsNaN(close[b + 1]) and IsNaN(close), extfib3a_[b + 2], "200%", Color.GREEN, yes);
AddChartBubble( direction[b + 1] == 0 and showFibExtLines and !IsNaN(close[b + 1]) and IsNaN(close), extfib4_[b + 2], "261.8%", Color.GREEN, yes);
AddChartBubble( direction[b + 1] == 0 and showFibExtLines and !IsNaN(close[b + 1]) and IsNaN(close), extfib5_[b + 2], "361.8%", Color.GREEN, yes);

#Volume at Reversals
def vol = if BarNumber() == 0 then 0 else volume + vol[1];
def vol1 = if BarNumber() == 1 then volume else vol1[1];
def xxvol = if zzSave == high or zzSave == low then TotalSum(volume) else xxvol[1];
def chgvol =  if xxvol - xxvol[1] + vol1 == vol then vol else xxvol - xxvol[1];
input showBubblesVolume = no;
AddChartBubble(showBubblesVolume and !IsNaN(zz) and BarNumber() != 1, if isUp then high * (1 + bubbleoffset)  else low * (1 - bubbleoffset), chgvol,if isUp and chghigh > 0 then Color.GREEN else if isUp and chghigh < 0 then Color.RED else if isUp then Color.YELLOW else if !isUp and chglow > 0 then Color.GREEN else if !isUp and chglow < 0 then Color.RED else Color.YELLOW, if isUp then yes else no );

Shareable Link

https://tos.mx/ZbuQDX
Ben, I am testing this study and I cannot get it to recognize the 96 supply zone for AMD. Can you offer any insight? I have altered the settings and TF's. I would imagine it should pick it up. Am I correct that this is a major supply zone for AMD? Wandering if I have it wrong.
 
ty @RobertPayne, very helpful.



So is it correct to conclude that it's not possible with thinkScript to setup a loop where the script will draw lines on all swing h/l points and extend them to the right of the chart?

Ideally, I was looking at including an input variable that would allow me to change the number of lines drawn per chart and not hard code the number of lines to be drawn.
How can I add a bubble only to those swing lows where the following swing low is below the previews swing low? See image.

Correct. A plot is just a variable that displays its value on the screen. A variable can only hold ONE value at a time. That's why when you try to do it with a single plot, the line stops when a new swing point is identified. That is, you can have the variable remember the old swing point's value, but when a new swing point is encountered, the old value is discarded and the new value is remembered.

Ruby:
# define swing low points
input length = 10;
def bn = BarNumber();
def lastBar = HighestAll(if IsNaN(close) then 0 else bn);
def offset = Min(length - 1, lastBar - bn);
def swingLow = low < Lowest(low[1], length - 1) and low == GetValue(Lowest(low, length), -offset);
# change candle colors just to make it easier to see what we are working with
AssignPriceColor(if swingLow then Color.LIME else Color.DARK_GRAY);

# using a single plot to show the swing low points
def l1 = if swingLow then low else l1[1];
plot low1 = l1;
low1.SetDefaultColor(Color.RED);
low1.SetPaintingStrategy(12);

View attachment 5856

In order to have two lines overlapping (both lines extending to the right of the chart) requires TWO plot lines because two different values must be displayed simultaneously---the new swing point and the old swing point.
The code that @netarchitech linked is quite old. I have since developed better methods.

I'll give an example below.

For this example, we will be projecting the low point of the last few 10 bar swing low points. We will start with this code to identify those points.

Ruby:
# define swing low points
input length = 10;
def bn = BarNumber();
def lastBar = HighestAll(if IsNaN(close) then 0 else bn);
def offset = Min(length - 1, lastBar - bn);
def swingLow = low < Lowest(low[1], length - 1) and low == GetValue(Lowest(low, length), -offset);
# change candle colors just to make it easier to see what we are working with
AssignPriceColor(if swingLow then Color.LIME else Color.DARK_GRAY);

View attachment 5849

Ruby:
# identify the very last swing low point
def lowPointOneBarNumber = HighestAll(if swingLow then bn else 0);
def lowPointOneValue = if bn == lowPointOneBarNumber then low else lowPointOneValue[1];
plot low1 = if bn < lowPointOneBarNumber then Double.NaN else lowPointOneValue;
low1.SetDefaultColor(Color.RED);

View attachment 5851

Ruby:
# identify the 2nd to last swing low point
def lowPointTwoBarNumber = HighestAll(if swingLow and bn < lowPointOneBarNumber then bn else 0);
def lowPointTwoValue = if bn == lowPointTwoBarNumber then low else lowPointTwoValue[1];
plot low2 = if bn < lowPointTwoBarNumber then Double.NaN else lowPointTwoValue;
low2.SetDefaultColor(Color.RED);

View attachment 5852

Ruby:
#  +------------------------------------------------------------+
#  |  Example: How to extend levels to the right of the chart   |
#  |                        Robert Payne                        |
#  |               https://funwiththinkscript.com               |
#  +------------------------------------------------------------+
# define swing low points
input length = 10;
def bn = BarNumber();
def lastBar = HighestAll(if IsNaN(close) then 0 else bn);
def offset = Min(length - 1, lastBar - bn);
def swingLow = low < Lowest(low[1], length - 1) and low == GetValue(Lowest(low, length), -offset);

# change candle colors just to make it easier to see what we are working with
AssignPriceColor(if swingLow then Color.LIME else Color.DARK_GRAY);

# identify the very last swing low point
def lowPointOneBarNumber = HighestAll(if swingLow then bn else 0);
def lowPointOneValue = if bn == lowPointOneBarNumber then low else lowPointOneValue[1];
plot low1 = if bn < lowPointOneBarNumber then Double.NaN else lowPointOneValue;
low1.SetDefaultColor(Color.RED);

# identify the 2nd to last swing low point
def lowPointTwoBarNumber = HighestAll(if swingLow and bn < lowPointOneBarNumber then bn else 0);
def lowPointTwoValue = if bn == lowPointTwoBarNumber then low else lowPointTwoValue[1];
plot low2 = if bn < lowPointTwoBarNumber then Double.NaN else lowPointTwoValue;
low2.SetDefaultColor(Color.RED);

# just keep doing ths for as many lines as you want to add to the chart
def lowPointThreeBarNumber = HighestAll(if swingLow and bn < lowPointTwoBarNumber then bn else 0);
def lowPointThreeValue = if bn == lowPointThreeBarNumber then low else lowPointThreeValue[1];
plot low3 = if bn < lowPointThreeBarNumber then Double.NaN else lowPointThreeValue;
low3.SetDefaultColor(Color.RED);

View attachment 5854
This is perfect for what I need. Is is possible to add a bubble only to those swing lows where the following swing low is below the previous swing low? The image below has an arrow below the swing low where I would like the bubble to be displayed.
 

Attachments

  • example.jpg
    example.jpg
    99.5 KB · Views: 48
  • example.jpg
    example.jpg
    99.5 KB · Views: 51
Last edited by a moderator:
How can I add a bubble only to those swing lows where the following swing low is below the previews swing low? See image.



This is perfect for what I need. Is is possible to add a bubble only to those swing lows where the following swing low is below the previous swing low? The image below has an arrow below the swing low where I would like the bubble to be displayed.

This is meant to place a bubble at the last test of following swing low being below the previous swing low
Code:
#  +------------------------------------------------------------+
#  |  Example: How to extend levels to the right of the chart   |
#  |                        Robert Payne                        |
#  |               https://funwiththinkscript.com               |
#  +------------------------------------------------------------+
# define swing low points
# bubble @ final test of low points > next low point
# low point length modified to try to match user bubble request

input length = 3;#10;
def bn = BarNumber();
def lastBar = HighestAll(if IsNaN(close) then 0 else bn);
def offset = Min(length - 1, lastBar - bn);
def swingLow = low < Lowest(low[1], length - 1) and low == GetValue(Lowest(low, length), -offset);

# change candle colors just to make it easier to see what we are working with
AssignPriceColor(if swingLow then Color.LIME else Color.DARK_GRAY);

# identify the very last swing low point
def lowPointOneBarNumber = HighestAll(if swingLow then bn else 0);
def lowPointOneValue = if bn == lowPointOneBarNumber then low else lowPointOneValue[1];
plot low1 = if bn < lowPointOneBarNumber then Double.NaN else lowPointOneValue;
low1.SetDefaultColor(Color.RED);

# identify the 2nd to last swing low point
def lowPointTwoBarNumber = HighestAll(if swingLow and bn < lowPointOneBarNumber then bn else 0);
def lowPointTwoValue = if bn == lowPointTwoBarNumber then low else lowPointTwoValue[1];
plot low2 = if bn < lowPointTwoBarNumber then Double.NaN else lowPointTwoValue;
low2.SetDefaultColor(Color.RED);

# just keep doing ths for as many lines as you want to add to the chart
def lowPointThreeBarNumber = HighestAll(if swingLow and bn < lowPointTwoBarNumber then bn else 0);
def lowPointThreeValue = if bn == lowPointThreeBarNumber then low else lowPointThreeValue[1];
plot low3 = if bn < lowPointThreeBarNumber then Double.NaN else lowPointThreeValue;
low3.SetDefaultColor(Color.RED);


def back =  lastBar - lowPointThreeBarNumber + 1;
def x1 = fold i1 = 0 to back with t1 do GetValue(low1, -i1);
def x2 = fold i2 = 0 to back with t2 do GetValue(low2, -i2);
def x3 = fold i3 = 0 to back with t3 do GetValue(low3, -i3);

AddChartBubble(if x2 > x1 then bn == lowPointTwoBarNumber else Double.NaN, low2, low2, low2.TakeValueColor(), no);
AddChartBubble(if x2 < x1 and x3 > x2 then bn == lowPointThreeBarNumber else Double.NaN, low3, low3, low3.TakeValueColor(), no);

#
 
This is meant to place a bubble at the last test of following swing low being below the previous swing low
Would it be possible to modify this script so it also identifies and plots the swing high to the right or left (whichever is lower) of the chart bubble?
 

Attachments

  • example2.png
    example2.png
    119.4 KB · Views: 35
  • example3.jpg
    example3.jpg
    107 KB · Views: 36
Last edited:
Would it be possible to modify this script so it also identifies and plots the swing high to the right or left (whichever is lower) of the chart bubble?

This is meant to plot the lower of the swing high before or after the swing low bubble
Code:
#  +------------------------------------------------------------+
#  |  Example: How to extend levels to the right of the chart   |
#  |                        Robert Payne                        |
#  |               https://funwiththinkscript.com               |
#  +------------------------------------------------------------+
# define swing low points
# bubble @ final test of low points > next low point
# low point length modified to try to match user bubble request
# line at lower of swing high before or after swing low bubble

input length = 3;#10;
def bn = BarNumber();
def lastBar = HighestAll(if IsNaN(close) then 0 else bn);
def offset = Min(length - 1, lastBar - bn);
def swingLow = low < Lowest(low[1], length - 1) and low == GetValue(Lowest(low, length), -offset);

# identify the very last swing low point
def lowPointOneBarNumber = HighestAll(if swingLow then bn else 0);
def lowPointOneValue = if bn == lowPointOneBarNumber then low else lowPointOneValue[1];
plot low1 = if bn < lowPointOneBarNumber then Double.NaN else lowPointOneValue;
low1.SetDefaultColor(Color.RED);

# identify the 2nd to last swing low point
def lowPointTwoBarNumber = HighestAll(if swingLow and bn < lowPointOneBarNumber then bn else 0);
def lowPointTwoValue = if bn == lowPointTwoBarNumber then low else lowPointTwoValue[1];
plot low2 = if bn < lowPointTwoBarNumber then Double.NaN else lowPointTwoValue;
low2.SetDefaultColor(Color.RED);

# just keep doing ths for as many lines as you want to add to the chart
def lowPointThreeBarNumber = HighestAll(if swingLow and bn < lowPointTwoBarNumber then bn else 0);
def lowPointThreeValue = if bn == lowPointThreeBarNumber then low else lowPointThreeValue[1];
plot low3 = if bn < lowPointThreeBarNumber then Double.NaN else lowPointThreeValue;
low3.SetDefaultColor(Color.RED);


def back =  lastBar - lowPointThreeBarNumber + 1;
def x1 = fold i1 = 0 to back with t1 do GetValue(low1, -i1);
def x2 = fold i2 = 0 to back with t2 do GetValue(low2, -i2);
def x3 = fold i3 = 0 to back with t3 do GetValue(low3, -i3);

AddChartBubble(if x2 > x1 then bn == lowPointTwoBarNumber else Double.NaN, low2, low2, low2.TakeValueColor(), no);
AddChartBubble(if x2 < x1 and x3 > x2 then bn == lowPointThreeBarNumber else Double.NaN, low3, low3, low3.TakeValueColor(), no);

def swingHigh = high > Highest(high[1], length - 1) and high == GetValue(Highest(high, length), -offset);

# change candle colors just to make it easier to see what we are working with
AssignPriceColor(if swingLow then Color.LIME else if swingHigh then Color.PINK else Color.DARK_GRAY);

# identify the very last swing high point at the swing low bubble
def highPointOneBarNumber = if x2 > x1 then lowPointTwoBarNumber else if x2 < x1 and x3 > x2 then lowPointThreeBarNumber else Double.NaN;

# identify the swing high point before and after bubble swing low
def highPointTwoBarNumber = HighestAll(if swingHigh and bn < HighestAll(highPointOneBarNumber) then bn else 0);
def highPointTwoValue = if bn == highPointTwoBarNumber then high else highPointTwoValue[1];
def highbefore = if bn < highPointTwoBarNumber then Double.NaN else highPointTwoValue;

def highPointTwo_BarNumber = LowestAll(if swingHigh and bn > HighestAll(highPointOneBarNumber) then bn else Double.NaN);
def highPointTwo_Value = if bn == highPointTwo_BarNumber then high else highPointTwo_Value[1];
def highafter = if bn < highPointTwo_BarNumber then Double.NaN else highPointTwo_Value;

def lower_of_highs_barnumber = if highbefore < highafter then highPointTwoBarNumber else if highbefore > highafter then highPointTwo_BarNumber else Double.NaN;
plot high2 = if bn < HighestAll(lower_of_highs_barnumber) then Double.NaN else HighestAll(Min(highbefore, highafter));
high2.SetDefaultColor(Color.PINK);

#
 
This is meant to plot the lower of the swing high before or after the swing low bubble
I'm trying to call this latest plot (high2) in a scan but it's showing me this error: "Folding: integer 'to' is expected. NaN>" Do you know what's wrong?
 
Last edited:
I'm trying to call this latest plot (high2) in a scan but it's showing me this error: "Folding: integer 'to' is expected. NaN>" Do you know what's wrong?
This seems to work in the scanner after changing 'back' to an integer

Copy and then Paste it as a custom study
It will find when high2 is true (that it plots)
Code:
input length = 3;#10;
def bn = BarNumber();
def lastBar = HighestAll(if IsNaN(close) then 0 else bn);
def offset = Min(length - 1, lastBar - bn);
def swingLow = low < Lowest(low[1], length - 1) and low == GetValue(Lowest(low, length), -offset);

# identify the very last swing low point
def lowPointOneBarNumber = HighestAll(if swingLow then bn else 0);
def lowPointOneValue = if bn == lowPointOneBarNumber then low else lowPointOneValue[1];
def low1 = if bn < lowPointOneBarNumber then Double.NaN else lowPointOneValue;
#low1.SetDefaultColor(Color.RED);

# identify the 2nd to last swing low point
def lowPointTwoBarNumber = HighestAll(if swingLow and bn < lowPointOneBarNumber then bn else 0);
def lowPointTwoValue = if bn == lowPointTwoBarNumber then low else lowPointTwoValue[1];
def low2 = if bn < lowPointTwoBarNumber then Double.NaN else lowPointTwoValue;
#low2.SetDefaultColor(Color.RED);

# just keep doing ths for as many lines as you want to add to the chart
def lowPointThreeBarNumber = HighestAll(if swingLow and bn < lowPointTwoBarNumber then bn else 0);
def lowPointThreeValue = if bn == lowPointThreeBarNumber then low else lowPointThreeValue[1];
def low3 = if bn < lowPointThreeBarNumber then Double.NaN else lowPointThreeValue;
#low3.SetDefaultColor(Color.RED);


def back =  99;#lastBar - lowPointThreeBarNumber + 1;
def x1 = fold i1 = 0 to back with t1 do GetValue(low1, -i1);
def x2 = fold i2 = 0 to back with t2 do GetValue(low2, -i2);
def x3 = fold i3 = 0 to back with t3 do GetValue(low3, -i3);


def swingHigh = high > Highest(high[1], length - 1) and high == GetValue(Highest(high, length), -offset);

# change candle colors just to make it easier to see what we are working with
AssignPriceColor(if swingLow then Color.LIME else if swingHigh then Color.PINK else Color.DARK_GRAY);

# identify the very last swing high point at the swing low bubble
def highPointOneBarNumber = if x2 > x1 then lowPointTwoBarNumber else if x2 < x1 and x3 > x2 then lowPointThreeBarNumber else Double.NaN;

# identify the swing high point before and after bubble swing low
def highPointTwoBarNumber = HighestAll(if swingHigh and bn < HighestAll(highPointOneBarNumber) then bn else 0);
def highPointTwoValue = if bn == highPointTwoBarNumber then high else highPointTwoValue[1];
def highbefore = if bn < highPointTwoBarNumber then Double.NaN else highPointTwoValue;

def highPointTwo_BarNumber = LowestAll(if swingHigh and bn > HighestAll(highPointOneBarNumber) then bn else Double.NaN);
def highPointTwo_Value = if bn == highPointTwo_BarNumber then high else highPointTwo_Value[1];
def highafter = if bn < highPointTwo_BarNumber then Double.NaN else highPointTwo_Value;

def lower_of_highs_barnumber = if highbefore < highafter then highPointTwoBarNumber else if highbefore > highafter then highPointTwo_BarNumber else Double.NaN;
def high2 = if bn < HighestAll(lower_of_highs_barnumber) then Double.NaN else HighestAll(Min(highbefore, highafter));
#high2.SetDefaultColor(Color.PINK);
plot scan = high2 is true;
#
 
This seems to work in the scanner after changing 'back' to an integer

Copy and then Paste it as a custom study
It will find when high2 is true (that it plots)
One last request if I may. I'd like to add a plot for the latest high and add some dash lines to it for visualization. This will help me find a 50 percent retracement from the most recent rally.
 

Attachments

  • example3.jpg
    example3.jpg
    96 KB · Views: 23
One last request if I may. I'd like to add a plot for the latest high and add some dash lines to it for visualization. This will help me find a 50 percent retracement from the most recent rally.

Lasthighpoint's dashed line is added at the bottom of the code
Code:
#  +------------------------------------------------------------+
#  |  Example: How to extend levels to the right of the chart   |
#  |                        Robert Payne                        |
#  |               https://funwiththinkscript.com               |
#  +------------------------------------------------------------+
# define swing low points
# bubble @ final test of low points > next low point
# low point length modified to try to match user bubble request
# line at lower of swing high before or after swing low bubble

input length = 3;#10;
def bn = BarNumber();
def lastBar = HighestAll(if IsNaN(close) then 0 else bn);
def offset = Min(length - 1, lastBar - bn);
def swingLow = low < Lowest(low[1], length - 1) and low == GetValue(Lowest(low, length), -offset);

# identify the very last swing low point
def lowPointOneBarNumber = HighestAll(if swingLow then bn else 0);
def lowPointOneValue = if bn == lowPointOneBarNumber then low else lowPointOneValue[1];
plot low1 = if bn < lowPointOneBarNumber then Double.NaN else lowPointOneValue;
low1.SetDefaultColor(Color.RED);

# identify the 2nd to last swing low point
def lowPointTwoBarNumber = HighestAll(if swingLow and bn < lowPointOneBarNumber then bn else 0);
def lowPointTwoValue = if bn == lowPointTwoBarNumber then low else lowPointTwoValue[1];
plot low2 = if bn < lowPointTwoBarNumber then Double.NaN else lowPointTwoValue;
low2.SetDefaultColor(Color.RED);

# just keep doing ths for as many lines as you want to add to the chart
def lowPointThreeBarNumber = HighestAll(if swingLow and bn < lowPointTwoBarNumber then bn else 0);
def lowPointThreeValue = if bn == lowPointThreeBarNumber then low else lowPointThreeValue[1];
plot low3 = if bn < lowPointThreeBarNumber then Double.NaN else lowPointThreeValue;
low3.SetDefaultColor(Color.RED);


def back =  lastBar - lowPointThreeBarNumber + 1;
def x1 = fold i1 = 0 to back with t1 do GetValue(low1, -i1);
def x2 = fold i2 = 0 to back with t2 do GetValue(low2, -i2);
def x3 = fold i3 = 0 to back with t3 do GetValue(low3, -i3);

AddChartBubble(if x2 > x1 then bn == lowPointTwoBarNumber else Double.NaN, low2, low2, low2.TakeValueColor(), no);
AddChartBubble(if x2 < x1 and x3 > x2 then bn == lowPointThreeBarNumber else Double.NaN, low3, low3, low3.TakeValueColor(), no);

def swingHigh = high > Highest(high[1], length - 1) and high == GetValue(Highest(high, length), -offset);

# change candle colors just to make it easier to see what we are working with
AssignPriceColor(if swingLow then Color.LIME else if swingHigh then Color.PINK else Color.DARK_GRAY);

# identify the very last swing high point at the swing low bubble
def highPointOneBarNumber = if x2 > x1 then lowPointTwoBarNumber else if x2 < x1 and x3 > x2 then lowPointThreeBarNumber else Double.NaN;

# identify the swing high point before and after bubble swing low
def highPointTwoBarNumber = HighestAll(if swingHigh and bn < HighestAll(highPointOneBarNumber) then bn else 0);
def highPointTwoValue = if bn == highPointTwoBarNumber then high else highPointTwoValue[1];
def highbefore = if bn < highPointTwoBarNumber then Double.NaN else highPointTwoValue;

def highPointTwo_BarNumber = LowestAll(if swingHigh and bn > HighestAll(highPointOneBarNumber) then bn else Double.NaN);
def highPointTwo_Value = if bn == highPointTwo_BarNumber then high else highPointTwo_Value[1];
def highafter = if bn < highPointTwo_BarNumber then Double.NaN else highPointTwo_Value;

def lower_of_highs_barnumber = if highbefore < highafter then highPointTwoBarNumber else if highbefore > highafter then highPointTwo_BarNumber else Double.NaN;
plot high2 = if bn < HighestAll(lower_of_highs_barnumber) then Double.NaN else HighestAll(Min(highbefore, highafter));
high2.SetDefaultColor(Color.PINK);

# identify the very last swing high point
def highPointlastBarNumber = HighestAll(if swingHigh then bn else 0);
def highPointlastValue = if bn == highPointlastBarNumber then high else highPointlastValue[1];
plot lasthighpoint = if bn < highPointlastBarNumber then Double.NaN else highPointlastValue;
lasthighpoint.SetStyle(Curve.LONG_DASH);
lasthighpoint.SetDefaultColor(Color.PINK);

#
 

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

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
318 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