Extend ZigZag Highs and Lows indefinitely in ThinkorSwim?

Y

Yoda

New member
Hi Robert,

I'm using the zig zag indicator posted by @BenTen here: https://usethinkscript.com/threads/zigzag-high-low-with-supply-demand-zones-for-thinkorswim.172/

I would like to plot a line at the zig zag highs and lows and have the line extended indefinitely to the right.

I have tried two options, neither of them work:

Option 1 extends the lines, but not indefinitely. The high line extends until the next high starts, and the low line extends until the next low line starts.

Option 2 extends the lines, but it creates an extended line only the length of the original line and if the length of the extension is greater than the length of the original line, it puts in spaces between the original line and the new line.

Any suggestions on what I need to do to have the high and low lines extend indefinitely to the right?

Here is the code that I've tried (inserting it just below the Price Change between zigzags section:

#Extend S&R Lines indefinitely to the right (WIP)
#Option 1
plot xxxhigh = xxhigh;
xxxhigh.setlineWeight(2);
xxxhigh.setDefaultColor(color.Red);
xxxhigh.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);

plot xxxlow = xxlow;
xxxlow.setlineWeight(2);
xxxlow.setDefaultColor(color.DARK_GREEN);
xxxlow.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);

#Option 2
input pp = 1;
plot xxxhigh4 = fold index = 1 to pp + 1 with p = 1 do xxhigh[200];
@RobertPayne
 
Y

Yoda

New member
ty @BenTen for the suggestion. I have looked into that code, but it also stops drawing the support horizontal line when a new support line starts (same for the resistance lines)
 
Y

Yoda

New member
@BenTen, unfortunately that script also doesn't address the issue either, but I very much appreciate the suggestions.

ty @netarchitech, that script is very close to what I'm trying to do. But it also is not extending the lines to the right of the chart.

Although @RobertPayne comments inside the code state "extend the current valley line to the right edge of the chart", I'm finding is that the lines only extend to the start of the 3rd line. i.e.
1st support line starts as a solid horizontal line
2nd support line starts as a solid line and the 1st support line switches to a dashed line (which is really nice)
3rd support line starts, the 1st line stops and the 2nd line switches to a dashed line. (And this is where the issue lies, I don't want the 1st support line to stop).

I need to figure out a way to continue the dashed lines for all support/resistance lines to the end of the chart.
 
RobertPayne

RobertPayne

Member
@BenTen, unfortunately that script also doesn't address the issue either, but I very much appreciate the suggestions.

ty @netarchitech, that script is very close to what I'm trying to do. But it also is not extending the lines to the right of the chart.

Although @RobertPayne comments inside the code state "extend the current valley line to the right edge of the chart", I'm finding is that the lines only extend to the start of the 3rd line. i.e.
1st support line starts as a solid horizontal line
2nd support line starts as a solid line and the 1st support line switches to a dashed line (which is really nice)
3rd support line starts, the 1st line stops and the 2nd line switches to a dashed line. (And this is where the issue lies, I don't want the 1st support line to stop).

I need to figure out a way to continue the dashed lines for all support/resistance lines to the end of the chart.
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);


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


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


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);
 
Last edited:
Y

Yoda

New member
ty @RobertPayne, very helpful.

# just keep doing ths for as many lines as you want to add to the chart
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.
 
RobertPayne

RobertPayne

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



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.
 
C

chillc15

New member
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);



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.
Robert,

So is it possible to do the reverse and define swing high points?

Thanks
 
T

tomsk

Well-known member
VIP
Warehouse
@chillc15 Per your request, I have modified @RobertPayne 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.

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

# 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);

# ADJUST CANDLE COLORS

# 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);
# End Swing High and Swing Low
 
C

chillc15

New member
@chillc15 Per your request, I have modified @RobertPayne 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.

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

# 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);

# ADJUST CANDLE COLORS

# 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);
# End Swing High and Swing Low
WOW! Thanks tomsk very much appreciated.

If you don’t mind I have a few questions that will help me learn and maybe others.

Obviously this swing-high-swing- low is similar to the Trend Reversal indicator as discussed on here and also the Zig-Zag.

As I watched Roberts swing-low this is a repainter as it waits to determine its bottom. With the addition of the swing-high I assume it will repaint as well until the top is determined as well.

The burning question is what condition in the code eventually keeps the bar locked in either high or low and it will no longer repaint.

Is it a certain amount of bars looking back?

For a swing-high does there have to be a certain amount of down bars before it locks itself in? Vice-versa at the low.

I know there are some zig-zag indicators using an ATR reversal factor and other conditions. Is it possible to implement this swing-high-swing-low into a zig-zag as well?

If you are open I can send you a zig-zag I have been working with to see if they could be implemented together.

Thanks again


For those that may be visual like me you can adjust the colors of the candles if you like. Here is another version.

# ADJUST CANDLE COLORS

# change candle colors just to make it easier to see what we are working with

AssignPriceColor(if swingLow then Color.YELLOW else if swingHigh then Color.BLUE else Color.CURRENT);
 
T

tomsk

Well-known member
VIP
Warehouse
WOW! Thanks tomsk very much appreciated.

If you don’t mind I have a few questions that will help me learn and maybe others.

Obviously this swing-high-swing- low is similar to the Trend Reversal indicator as discussed on here and also the Zig-Zag.

As I watched Roberts swing-low this is a repainter as it waits to determine its bottom. With the addition of the swing-high I assume it will repaint as well until the top is determined as well.

The burning question is what condition in the code eventually keeps the bar locked in either high or low and it will no longer repaint.

Is it a certain amount of bars looking back?

For a swing-high does there have to be a certain amount of down bars before it locks itself in? Vice-versa at the low.

I know there are some zig-zag indicators using an ATR reversal factor and other conditions. Is it possible to implement this swing-high-swing-low into a zig-zag as well?

If you are open I can send you a zig-zag I have been working with to see if they could be implemented together.

Thanks again


For those that may be visual like me you can adjust the colors of the candles if you like. Here is another version.

# ADJUST CANDLE COLORS

# change candle colors just to make it easier to see what we are working with

AssignPriceColor(if swingLow then Color.YELLOW else if swingHigh then Color.BLUE else Color.CURRENT);
@chillc15 This study was originally designed by @RobertPayne so if you have any specific queries regarding the design of the code you might like to check with him. I essentially added the associated swing high logic based on Robert's underlying design

My understanding is that whenever a new swing low is detected, the code notes the price together with the bar number at that point
If the bar number that is being processed matches the bar number that had earlier been noted, then a line is plotted. Ditto for the swing high code
 
T

TK_44

New member
Can anyone explain to me how to extend the previous valley past each new valley as a dashed line like in @RobertPayne original version here using the code he posted above instead of the original?

Code:
# 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);
 
H

horserider

Well-known member
VIP
Warehouse
@TK_44 Why not just use support/resistance zones with ATR or theotrade pivots?
 
T

TK_44

New member
@horserider Basically I was just wanting to use this as a base code in order to backtest various signals that test prior pivot levels as well as certain breakout patterns off them as well. I can use Robert's original one if I need to, but this code looks much more streamlined. This code allows me to visualize all the swing highs/lows, where as the ones you mentioned show only the most recent ones.
 
H

horserider

Well-known member
VIP
Warehouse
OK thought it will solve your extension problem and more levels could be added. I forgot I did on the shows high/low of past 10 days. It is on here somewhere.
 
tenacity11

tenacity11

Active member
VIP
@tomsk
Is there a scan that can be set up for the swing low when the lime candle appears on a 15, 60m or D chart?
TIA
 
T

tomsk

Well-known member
VIP
Warehouse
@tenacity11 Sure thing, here is your customized scan code to scan for a swing low.
I have just tested this scanning against the S&P 500 with the following results:

Daily - 19 hits
15m - 15 hits
60m - 6 hits

Code:
# Swing Low Scan
# tomsk
# 12.1.2019

# I have modified @RobertPayne code to scan for the most recent swing low
#
#  +------------------------------------------------------------+
#  |  Example: How to extend levels to the right of the chart   |
#  |                        Robert Payne                        |
#  |               https://funwiththinkscript.com               |
#  +------------------------------------------------------------+

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);
def lowPointOneBarNumber = HighestAll(if swingLow then bn else 0);
plot scan = bn == lowPointOneBarNumber;
# End Swing Low Scan
 
Last edited:
tenacity11

tenacity11

Active member
VIP
@tomsk
Greatly appreciate your setting this up. I'm finding the indicator very useful in conjunction with the TMO.
I was able to resolve the error issue.
 

Top