ZigZag High Low Stats for ThinkorSwim

T

tomsk

Well-known member
VIP
Extracted idea from RDMercer's post #369 of a variant of a massive Zig Zag High Low Supply Demand study that comprises many different components

https://usethinkscript.com/threads/...-signals-for-thinkorswim.183/page-19#post-369
I heavily modified, cleaned up and extracted some interesting Zig Zag statistical information resulting in this study called Zig Zag High Low Stats. It displays the following information represented via bubbles at each of the Zig zag turning points

Label for Confirmed/Unconfirmed Status of Current Zigzag
Price Change between Zigzags
Price at Zigzag High/Low
Bar Count between Zigzags
Volume at Zigzag Reversals

Here's the study - you might like to load this study on a Daily chart of AAPL, AMZN or your favorite ticker
You can turn off any information you don't want via the user interface

Code:
# ZigZag High Low Stats
# tomsk
# 11.16.2019

# V1.0 - 11.16.2019 - tomsk - Initial release of ZigZag High Low Stats

# Extracted idea from RDMercer's post #369 of a variant of a massive
# Zig Zag High Low Supply Demand study that comprises many different
# components
#
# https://usethinkscript.com/threads/trend-reversal-indicator-with-signals-for-thinkorswim.183/page-19#post-369
#
# I heavily modified, cleaned up and extracted some interesting Zig Zag statistical information resulting in this study called Zig Zag High
# Low Stats. It displays the following information represented via bubbles at each of the Zig zag turning points
#
# Label for Confirmed/Unconfirmed Status of Current Zigzag
# Price Change between Zigzags
# Price at Zigzag High/Low
# Bar Count between Zigzags
# Volume at Zigzag Reversals

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 BubbleOffset = .0005;
input PercentAmount = .01;
input RevAmount = .05;
input ATRreversal = 3.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 * reference ATR(ATRlength), RevAmount)
                     then (close * PercentAmount / 100)
                     else if RevAmount < ATRreversal * reference ATR(ATRlength)
                          then ATRreversal * reference ATR(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 Specific Data

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 Specific Data

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 Specific Data

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];

# Zigzag Status Label

AddLabel(BarNumber() != 1, (if isConf then "Confirmed " else "Unconfirmed ") + "ZigZag: " + chg + "  ATRrev " + Round(reference ATR(ATRlength) * ATRreversal, 2) + "  RevAmt " + Round(ReversalAmount, 2), 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();
zzp.HideBubble();

# Bubbles

# Price Change between Zigzags

AddChartBubble(showBubblesChange and !IsNaN(zz) and BarNumber() != 1, if isUp then high * (1 + BubbleOffset) else low * (1 - BubbleOffset), "$" + Round(chg, 2), 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);

# End ZigZag High Low Stats
 
T

tomsk

Well-known member
VIP
@BenTen Thanks, it took me the better part of a day, it sure was a monster study, that's for sure ;)
 
tenacity11

tenacity11

Active member
2019 Donor


ZigZag with Swing H Swing L stats and Iron Rod SMI Histogram has proven to work nicely in my quest for simplicity
 
Last edited by a moderator:
tenacity11

tenacity11

Active member
2019 Donor
how do you use this indicator
I look for either a cyan candle for swing low in conjunction with the smi crossing above the average smi and I like it -30 or below. The opposite is for the pink candle high.
 
T

TrueDepth

Member
VIP
What does 'confirmed' mean? ZigZag is a highly repainting indicator that moves after the fact. Once it is confirmed, does that mean it won't repaint anymore?
 
B

brandoita

New member
@tomsk You have made an excellent job!!! Is there any possibility to add the function to show the percentage of retracement in each swing? Thank you very much for your time!!
 
tenacity11

tenacity11

Active member
2019 Donor
@mikeraya

Code:
# IronRod SMI Histogram (Lower)
# BuyLow
# MA - yellow hma's are weak, red is bearish, green bullish.
# On the lower (shows hma angle)- anything above (green) the 0 angle line is bullish, below (red) bearish.
#
# The angle size is directly proportional to trend strength, so you easily see increasing or decreasing trend strength/momentum.
# I use the dark/light graduation as a doubling signal for strong moves.
declare lower;
input audioalarm=yes;
input Price = hlc3;
input RsqLength = 5;
input RsqLimit = .5;
input SmiLimit = 30;
input chopband2= 70;
input smibarbufr = 4;
def overbought = SmiLimit;
def oversold = -SmiLimit;
def percentDLength = 4;
def percentKLength = 5;
# Stochastic Momentum Index (SMI)
def min_low = Lowest(low, percentKLength);
def max_high = Highest(high, percentKLength);
def rel_diff = close - (max_high + min_low) / 2;
def diff = max_high - min_low;
def avgrel = ExpAverage(ExpAverage(rel_diff, percentDLength), percentDLength);
def avgdiff = ExpAverage(ExpAverage(diff, percentDLength), percentDLength);
plot chopband = if IsNaN(close) then Double.NaN else 0;
plot SMI = if avgdiff != 0 then avgrel / (avgdiff / 2) * 100 else 0;
#SMI.SetDefaultColor(Color.BLUE);
SMI.DefineColor("Up", CreateColor(0, 153, 51));
SMI.definecolor("Weak", Color.LIGHT_GRAY);
SMI.DefineColor("Down", Color.RED);
SMI.AssignValueColor(if SMI > SMI[1] then SMI.Color("Up") else if SMI < SMI[1] then SMI.Color("Down") else SMI.Color("Weak"));
SMI.SetLineWeight(2);
SMI.SetStyle(Curve.SHORT_DASH);
SMI.SetLineWeight(3);
plot AvgSMI = ExpAverage(SMI, percentDLength);
AvgSMI.DefineColor("Up", CreateColor(0, 153, 51));
AvgSMI.definecolor("Weak", Color.LIGHT_GRAY);
AvgSMI.DefineColor("Down", Color.RED);
AvgSMI.AssignValueColor(if AvgSMI > AvgSMI[1] then AvgSMI.Color("Up") else if AvgSMI < AvgSMI[1] then AvgSMI.Color("Down") else AvgSMI.Color("Weak"));
AvgSMI.SetLineWeight(3);
#SMI1.SetPaintingStrategy(PaintingStrategy.DASHES);
plot SMIBAR = AvgSMI;
SMIBAR.SetPaintingStrategy(PaintingStrategy.HISTOGRAM);
SMIBAR.SetLineWeight(3);
SMIBAR.DefineColor("Upstrong", CreateColor (0, 255, 0));
SMIBAR.DefineColor("Weak", Color.LIGHT_GRAY);
SMIBAR.DefineColor("Downstrong", CreateColor(255, 51, 51));
SMIBAR.AssignValueColor (if (SMI + smibarbufr) >= SMI[1] and SMI > -SmiLimit then SMIBAR.Color("Upstrong") else if (SMI - smibarbufr) <= SMI[1] and SMI < SmiLimit then SMIBAR.Color("Downstrong") else SMIBAR.Color("Weak"));
# r-Square Centerline Indicator
#def sma = Average(close, RsqLength);
#def RSq = Sqr(WMA(close, RsqLength) - sma) / (Average(Sqr(close), RsqLength) - Sqr(sma)) * 3 * (RsqLength + 1) / (RsqLength - 1);
chopband.HideBubble();
chopband.SetLineWeight(5);
chopband.DefineColor("Trade", CreateColor(0, 150,200));
chopband.DefineColor("Hold", Color.ORANGE);
chopband.AssignValueColor(if SMI > -smiLimit and SMI < smilimit then chopband.Color("Hold") else chopband.Color("Trade"));
# Chop Cloud
plot upper= smilimit;
plot lower= -smilimit;
upper.setDefaultColor(Color.GRAY);
lower.setDefaultColor(Color.GRAY);
def choplimits = SmiLimit;
#input choplimits= 1;
AddCloud(choplimits, -choplimits, CreateColor(210,210,210));
#addcloud(-choplimits, -chopband2, CreateColor(175,175,175));
#addcloud(chopband2, choplimits, CreateColor(175,175,175));
# Labels
AddLabel(yes, "SMI Legend: ", Color.WHITE);
AddLabel(yes, "Bullish", Color.UPTICK);
AddLabel(yes, "Bearish", Color.DOWNTICK);
AddLabel(yes, "Changing", Color.GRAY);
AddLabel(yes, "MidLine: ", Color.WHITE);
AddLabel(yes, "Trending", CreateColor(0,150,200));
AddLabel(yes, "In ChopZone", Color.ORANGE);
AddLabel(yes, "SmiLimit: " + SmiLimit, Color.GRAY);
alert (audioalarm and SMI crosses AvgSMI and SMI <= -smilimit or SMI crosses AvgSMI AND SMI >= smilimit, "SMI CROSS", alert.bar, sound.ding);
# End Study
 
Last edited by a moderator:
K

kshires4

Member
Can you share your chart? Thank you!
@tenacity11 nice work on the lower ironrod smi. anyway to get arrows on the crossovers instead of the alarm or can i get the alarm only on certain time frames?
 
Tradervic

Tradervic

New member
VIP
I look for either a cyan candle for swing low in conjunction with the smi crossing above the average smi and I like it -30 or below. The opposite is for the pink candle high.
I downloaded tomsk's ZigZag indicator but don't see the cyan and pink candles like you do. What am I doing wrong? Thanks!
 
tenacity11

tenacity11

Active member
2019 Donor
I downloaded tomsk's ZigZag indicator but don't see the cyan and pink candles like you do. What am I doing wrong? Thanks!
@Tradervic The colored candles come from this

Code:
# Swing High and Swing Low
# tomsk
# 11.18.2019
# As requested by chillc15 I have modified [USER=1174]@RobertPayne[/USER] code to include SwingHigh
# points which are now plotted in CYAN with the swing high points painted in PINK.
# So now you have both swing high and low on your charts
#  +------------------------------------------------------------+
# | Example: How to extend levels to the right of the chart |
# | Robert Payne |
# | https://funwiththinkscript.com |
#  +------------------------------------------------------------+
# SWING LOW
# 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);
# 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.LIGHT_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.Light_RED);
# just keep doing ths for as many lines as you want to add to the chart
# identify then 3rd to last swingHigh point low
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.Light_RED);
# identify then 4th to last swingHigh point low
def lowPointFourBarNumber = HighestAll(if swingLow and bn < lowPointThreeBarNumber then bn else 0);
def lowPointFourValue = if bn == lowPointFourBarNumber then low else lowPointFourValue[1];
plot low4 = if bn < lowPointFourBarNumber then Double.NaN else lowPointFourValue;
low4.SetDefaultColor(Color.Light_RED);
# identify then 5th to last swingHigh point low
def lowPointFiveBarNumber = HighestAll(if swingLow and bn < lowPointFourBarNumber then bn else 0);
def lowPointFiveValue = if bn == lowPointFiveBarNumber then low else lowPointFiveValue[1];
plot low5 = if bn < lowPointFiveBarNumber then Double.NaN else lowPointFiveValue;
low5.SetDefaultColor(Color.Light_RED);
# identify then 6th to last swingHigh point low
def lowPointSixBarNumber = HighestAll(if swingLow and bn < lowPointFiveBarNumber then bn else 0);
def lowPointSixValue = if bn == lowPointSixBarNumber then low else lowPointSixValue[1];
plot low6 = if bn < lowPointSixBarNumber then Double.NaN else lowPointSixValue;
low6.SetDefaultColor(Color.Light_RED);
# identify then 7th to last swingHigh point low
def lowPointSevenBarNumber = HighestAll(if swingLow and bn < lowPointSixBarNumber then bn else 0);
def lowPointSevenValue = if bn == lowPointSevenBarNumber then low else lowPointSevenValue[1];
plot low7 = if bn < lowPointSevenBarNumber then Double.NaN else lowPointSevenValue;
low7.SetDefaultColor(Color.Light_RED);
# identify then 8th to last swingHigh point low
def lowPointEightBarNumber = HighestAll(if swingLow and bn < lowPointSevenBarNumber then bn else 0);
def lowPointEightValue = if bn == lowPointEightBarNumber then low else lowPointEightValue[1];
plot low8 = if bn < lowPointEightBarNumber then Double.NaN else lowPointEightValue;
low8.SetDefaultColor(Color.Light_RED);
# identify then 9th to last swingHigh point low
def lowPointNineBarNumber = HighestAll(if swingLow and bn < lowPointEightBarNumber then bn else 0);
def lowPointNineValue = if bn == lowPointNineBarNumber then low else lowPointNineValue[1];
plot low9 = if bn < lowPointNineBarNumber then Double.NaN else lowPointNineValue;
low9.SetDefaultColor(Color.Light_RED);
# identify then 10th to last swingHigh point low
def lowPointTenBarNumber = HighestAll(if swingLow and bn < lowPointNineBarNumber then bn else 0);
def lowPointTenValue = if bn == lowPointTenBarNumber then low else lowPointTenValue[1];
plot low10 = if bn < lowPointTenBarNumber then Double.NaN else lowPointTenValue;
low10.SetDefaultColor(Color.Light_RED);


# SWING HIGH
# define swing high points
def swingHigh = high > Highest(high[1], length - 1) and high == GetValue(Highest(high, length), -offset);
# identify the very last swing high point
def highPointOneBarNumber = HighestAll(if swingHigh then bn else 0);
def highPointOneValue = if bn == highPointOneBarNumber then high else highPointOneValue[1];
plot high1 = if bn < highPointOneBarNumber then Double.NaN else highPointOneValue;
high1.SetDefaultColor(Color.CYAN);
# identify the 2nd to last swing high point
def highPointTwoBarNumber = HighestAll(if swingHigh and bn < highPointOneBarNumber then bn else 0);
def highPointTwoValue = if bn == highPointTwoBarNumber then high else highPointTwoValue[1];
plot high2 = if bn < highPointTwoBarNumber then Double.NaN else highPointTwoValue;
high2.SetDefaultColor(Color.CYAN);
# just keep doing ths for as many lines as you want to add to the chart
def highPointThreeBarNumber = HighestAll(if swingHigh and bn < highPointTwoBarNumber then bn else 0);
def highPointThreeValue = if bn == highPointThreeBarNumber then high else highPointThreeValue[1];
plot high3 = if bn < highPointThreeBarNumber then Double.NaN else highPointThreeValue;
high3.SetDefaultColor(Color.CYAN);
def highPointFourBarNumber = HighestAll(if swingHigh and bn < highPointThreeBarNumber then bn else 0);
def highPointFourValue = if bn == highPointFourBarNumber then high else highPointFourValue[1];
plot high4 = if bn < highPointFourBarNumber then Double.NaN else highPointFourValue;
high4.SetDefaultColor(Color.CYAN);
def highPointFiveBarNumber = HighestAll(if swingHigh and bn < highPointFourBarNumber then bn else 0);
def highPointFiveValue = if bn == highPointFiveBarNumber then high else highPointFiveValue[1];
plot high5 = if bn < highPointFiveBarNumber then Double.NaN else highPointFiveValue;
high5.SetDefaultColor(Color.CYAN);
def highPointSixBarNumber = HighestAll(if swingHigh and bn < highPointFiveBarNumber then bn else 0);
def highPointSixValue = if bn == highPointSixBarNumber then high else highPointSixValue[1];
plot high6 = if bn < highPointsixBarNumber then Double.NaN else highPointsixValue;
high6.SetDefaultColor(Color.CYAN);
def highPointSevenBarNumber = HighestAll(if swingHigh and bn < highPointSixBarNumber then bn else 0);
def highPointSevenValue = if bn == highPointSevenBarNumber then high else highPointSevenValue[1];
plot high7 = if bn < highPointSevenBarNumber then Double.NaN else highPointSevenValue;
high7.SetDefaultColor(Color.CYAN);
def highPointEightBarNumber = HighestAll(if swingHigh and bn < highPointSevenBarNumber then bn else 0);
def highPointEightValue = if bn == highPointEightBarNumber then high else highPointEightValue[1];
plot high8 = if bn < highPointEightBarNumber then Double.NaN else highPointEightValue;
high4.SetDefaultColor(Color.CYAN);
def highPointNineBarNumber = HighestAll(if swingHigh and bn < highPointEightBarNumber then bn else 0);
def highPointNineValue = if bn == highPointNineBarNumber then high else highPointNineValue[1];
plot high9 = if bn < highPointNineBarNumber then Double.NaN else highPointNineValue;
high4.SetDefaultColor(Color.CYAN);
def highPointTenBarNumber = HighestAll(if swingHigh and bn < highPointNineBarNumber then bn else 0);
def highPointTenValue = if bn == highPointTenBarNumber then high else highPointTenValue[1];
plot high10 = if bn < highPointTenBarNumber then Double.NaN else highPointTenValue;
high4.SetDefaultColor(Color.CYAN);

# ADJUST CANDLE COLORS
# change candle colors just to make it easier to see what we are working with
AssignPriceColor(if swingLow then Color.cyan else if swingHigh then Color.mageNTA else Color.current);
# End Swing High and Swing Low
 
Tradervic

Tradervic

New member
VIP
So I will need to delete what I downloaded and upload what you just posted? Thank you so much for your reply.
 
tenacity11

tenacity11

Active member
2019 Donor
So I will need to delete what I downloaded and upload what you just posted? Thank you so much for your reply.
I don't use the high and low lines. I just use the cyan and pink candles along with trend lines for my trading. Be aware that if a cyan or pink candle is exceeded the color goes away and a new one will appear. I always look for confirmation once the colors appear. I also use the colors in conjunction with the True Momentum Oscillator. I'm happy to show you a chart if that will help. I trade a 3m and 9m but certainly this is applicable to higher timeframes.
 
M

marine

New member
Lifetime
I don't use the high and low lines. I just use the cyan and pink candles along with trend lines for my trading. Be aware that if a cyan or pink candle is exceeded the color goes away and a new one will appear. I always look for confirmation once the colors appear. I also use the colors in conjunction with the True Momentum Oscillator. I'm happy to show you a chart if that will help. I trade a 3m and 9m but certainly this is applicable to higher timeframes.
can i see the chart
 

Similar threads

Top