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:
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.
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);