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 useatr = yes;#Hint useatr: set to no to use manual zigzagamount for reversalamount before a new zigzag is drawn. The ATR will still be used for auto fibs.
input zigzagpercent = 0.20;
input zigzagamount = .15;
def ATR = reference ATR(length = ATRlength);
#def reversalAmount = if useatr == yes then ATRreversalfactor * ATR else zigzagamount;
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;
#addlabel(yes,(zigzagpercent*close/100)+" "+zigzagamount+" "+(atrreversalfactor*ATR));
input showsupplydemand = no;
input showhorizontal = no;#Hint showhorizontal: set yes to display horizontal lines at low/high of each zigzag high/low reversal bar to use for possible entry point
input bubbleoffset = .0005;
input pricecolor = no;
input showVolumeWave = no;#Hint showvolumewave: set all other bubbles to no if showvolumeWave is selected yes
input showArrows = no;
input useAlerts = no;
input showconfirmedLabel = yes;#Hint showconfirmedLabel: Select yes to see current status of ZigZag, either unconfirmed or confirmed
input showBubblewaveC = no;#Hint showbubblewave123: Not complete, work in progress
#Assert(reversalAmount > 0, "'reversal amount' should be positive: " + reversalAmount);
#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)) ;
rec isconfreal = if isConf[1] == 0 and isConf then close else Double.NaN;
"ZZ$".EnableApproximation();
"ZZ$".DefineColor("Up Trend", Color.GREEN);
"ZZ$".DefineColor("Down Trend", Color.RED);
"ZZ$".DefineColor("Undefined", Color.YELLOW);
"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.YELLOW);
DefineGlobalColor("Up", Color.GREEN);
DefineGlobalColor("Down", Color.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];
rec priorzz4 = if priorzz3 != priorzz3[1] then priorzz3[1] else priorzz4[1];
rec priorzz5 = if priorzz4 != priorzz4[1] then priorzz4[1] else priorzz5[1];
rec priorzz6 = if priorzz5 != priorzz5[1] then priorzz5[1] else priorzz6[1];
rec upmove = if currentPoints == 0 and upmove[1] == 0 then 1 else if upmove[1] == 1 and currentPoints != 0 then 1 else 0;
rec dnmove = if currentPoints == 0 and upmove[1] == 1 then 1 else if dnmove[1] == 1 and currentPoints != 0 then 1 else 0;
#Higher/Lower/Equal High, Higher/Lower/Equal Low
def xxhigh = if zzSave == priceH then high else xxhigh[1];
def chghigh = high - xxhigh[1];
def xxlow = if zzSave == priceL then low else xxlow[1];
def chglow = low - xxlow[1];
#Bar Count between zigzags
#Bar Count
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 == priceH or zzSave == priceL) then 1 else if zzSave == priceH or zzSave == priceL then zzcounthilo[1] + 1 else zzcounthilo[1];
def zzhilo = if zzSave == priceH or zzSave == priceL then zzcounthilo else zzcounthilo + 1;
def zzcounthigh = if zzSave == priceH then zzcount[1] else Double.NaN;
def zzcountlow = if zzSave == priceL then zzcount[1] else Double.NaN;
#Supply Demand Areas
def cp = if currentPoints == 0 then 1 else if currentPoints != 0 then cp[1] + 1 else 0;
#def zzhigh = if zzSave == priceH and (sum(close[-1]>close[-2],10)>=5 or cp[-30]>=30) then l else zzhigh[1];
def sdhigh = if zzSave == priceH then low else sdhigh[1];
plot sdupline = if showsupplydemand == no then Double.NaN else sdhigh[1];
sdupline.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
sdupline.SetDefaultColor(color = Color.RED);
sdupline.SetLineWeight(1);
#def zzhigh1 = if zzsave == priceH and (sum(close[-1]>close[-2],10)>=5 or cp[-30]>=30) then h else zzhigh1[1];
def sdhigh1 = if zzSave == priceH then high else sdhigh1[1];
plot sdupline1 = if showsupplydemand == no then Double.NaN else sdhigh1[1];
sdupline1.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
sdupline1.SetDefaultColor(color = Color.RED);
sdupline1.SetLineWeight(1);
AddCloud(if showsupplydemand then sdupline1 else Double.NaN, sdupline, Color.GRAY, Color.GRAY);
#def zzlow = if zzSave == priceL and (sum(close[-1]<close[-2],10)>=5 or or cp[-30]>=30) then h else zzlow[1];
def sdlow = if zzSave == priceL then high else sdlow[1];
plot sdlowline = if showsupplydemand == no then Double.NaN else sdlow[1];
sdlowline.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
sdlowline.SetDefaultColor(color = Color.GREEN);
sdlowline.SetLineWeight(1);
#def zzlow1 = if zzSave == priceL and (sum(close[-1]<close[-2],10)>=5 or or cp[-30]>=30) then l else zzlow1[1];
def sdlow1 = if zzSave == priceL then low else sdlow1[1];
plot sdlowline1 = if showsupplydemand == no then Double.NaN else sdlow1[1];
sdlowline1.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
sdlowline1.SetDefaultColor(color = Color.GREEN);
sdlowline1.SetLineWeight(1);
AddCloud(if showsupplydemand then sdlowline1 else Double.NaN, sdlowline, Color.GRAY, Color.GRAY);
#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(5);
Alert(U1, "LONG", Alert.Bar, Sound.Ring);
plot isconfdn = if showArrows and !isUp and isconfreal then high + .05 else Double.NaN;
isconfdn.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);
isconfdn.SetLineWeight(5);
isconfdn.SetDefaultColor(Color.WHITE);
plot isconfup = if showArrows and isUp and isconfreal then low - .05 else Double.NaN;
isconfup.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
isconfup.SetLineWeight(5);
isconfup.SetDefaultColor(Color.WHITE);
plot D1 = showArrows and signal < 0 and signal[1] >= 0;
D1.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);
D1.SetDefaultColor(Color.RED);
D1.SetLineWeight(5);
Alert(D1, "SHORT", Alert.Bar, Sound.Ring);
|