Improving High Low Zigzag Indicator

sbhyde

New member
First Post after a few months of lurking around ---

I started with the script for SwingHL_Fibs v1.3 -- Kudos to the original author
I stripped out the Fibs portion since I wanted to focus on identification of High/Lows only.
There are some oddities in the original script that allowed multiple highs or multiple lows to occur in a row, rather than alternating. It's not really a swing high if it is followed by another swing high w/o an intervening low.

This modification eliminates the problem High/Lows when the problem occurs after the correct High/Low. The problem I am having with this indicator is when the problem High/Low occurs before the correct High/Low. I can detect the problem, but am at a loss for how to address it. My understanding is I can't modify a variable defined in a prior time period and I am not sure how to implement a "look-ahead" for an unknown time period.

The first included image shows the nominal output as defined in the original SwingHL_Fibs script. The circled items are the problems.
The second included image is for the included script. Note it removes the one item where the problem occurs after the valid Swing Low.

I would appreciate any insights or code bending that can be provided.

Code:
#SwingHL
# Derived from SwingHL_Fibs V1.3
# Determine the H/L by looking back swing_back1 bars and forward swing_forward1 bars.
#   Total of 1 + swing_forward1 + swing_back1 bars are considered
# If the Current bar is the H/L, a flag is set and the BarNumber is recorded
# The last bar can be neither a high nor a low

input Last_Swing_Only = yes; # Yes = show Last HL2  No = Show All HL
input swing_back1 = 5;       # Look Back Period in Bars
input swing_forward1 = 5;    # Look Forward Period in Bars

# Set onLow true if the low for the current bar is the lowest Low within swing_forward1 and swing_back1 bars
def onLow = low < Lowest(low, swing_forward1)[-swing_forward1] and low < Lowest(low, swing_back1)[1] and !IsNan(close[-1]) ;

# Set onHigh true if the high for the current bar is the highest high within swing_forward1 and swing_back1 bars
def onHigh = high > Highest(high, swing_forward1)[-swing_forward1] and high > Highest(high, swing_back1)[1] and !IsNan(close[-1]) ;

def swinglow1;
def swinglowbar;
def swinghigh1;
def swinghighbar;
def lastlow;
def lasthigh;

# Get bar number for last low and the last high
def PriorLow = Highest(swinglowbar[1], 100);
def PriorHigh = Highest(swinghighbar[1], 100);
# Compare bar number locations for last low/high to determine what is in the rear view
def LastSwingWasHigh = PriorHigh > PriorLow;
def LastSwingWasLow = PriorHigh < PriorLow;

# Identify as swinglow if this is a local low and either the prior pivot was a high or a higher low
swinglow1 = if onLow and (!LastSwingWasLow or low < lastlow[1]) then 1 else 0  ;
swinglowbar = if swinglow1 then BarNumber() else 0;
lastlow = if !swinglow1 or BarNumber() == 1 then lastlow[1] else low;

# Identify as swinghigh if this is a local high and either the prior pivot was a low or a lower high
swinghigh1 = if onHigh and (!LastSwingWasHigh or high > lasthigh[1]) then 1 else 0  ;
swinghighbar = if swinghigh1 then BarNumber() else 0;
lasthigh = if !swinghigh1 or BarNumber() == 1 then lasthigh[1] else high;

#Plot OverwritePreviousHigh = if swinghigh1 and highest(swinghighbar[1], 1000) > highest(swinglowbar[1], 1000) then highest(swinghighbar[1], 1000) else highest(swinglowbar[1], 1000);
#Plot OverwritePreviousHigh = if swinghigh1 and highest(swinghighbar[1], 100) > highest(swinglowbar[1], 100) then 300 else 0;

# Measure the distance in bars between the Last High and Low
def lastswing = HighestAll(swinghighbar) > HighestAll(swinglowbar);

# Visual Representaion
plot SwingHighs = if Last_Swing_Only and BarNumber() == HighestAll(swinghighbar) then high else if !Last_Swing_Only and swinghigh1 then high else Double.NaN;
plot SwingLows = if Last_Swing_Only and BarNumber() == HighestAll(swinglowbar) then low else if !Last_Swing_Only and swinglow1 then low else Double.NaN;

input Bubble_Offset_Factor  = 3;
input Show_Bubbles = yes ;
AddChartBubble(Show_Bubbles and SwingHighs, high + TickSize() * Bubble_Offset_Factor, "H", Color.GREEN, yes);
AddChartBubble(Show_Bubbles and SwingLows, low - TickSize() * Bubble_Offset_Factor, "L", Color.RED, no);

# Debug Statement
#AddChartBubble(Show_Bubbles and SwingHighs, high + TickSize() * Bubble_Offset_Factor, lasthigh[1], Color.GREEN, yes);
#AddChartBubble(Show_Bubbles and SwingLows, low - TickSize() * Bubble_Offset_Factor, lastlow[1], Color.RED, no);


 
First Post after a few months of lurking around ---

I started with the script for SwingHL_Fibs v1.3 -- Kudos to the original author
I stripped out the Fibs portion since I wanted to focus on identification of High/Lows only.
There are some oddities in the original script that allowed multiple highs or multiple lows to occur in a row, rather than alternating. It's not really a swing high if it is followed by another swing high w/o an intervening low.

This modification eliminates the problem High/Lows when the problem occurs after the correct High/Low. The problem I am having with this indicator is when the problem High/Low occurs before the correct High/Low. I can detect the problem, but am at a loss for how to address it. My understanding is I can't modify a variable defined in a prior time period and I am not sure how to implement a "look-ahead" for an unknown time period.

The first included image shows the nominal output as defined in the original SwingHL_Fibs script. The circled items are the problems.
The second included image is for the included script. Note it removes the one item where the problem occurs after the valid Swing Low.

I would appreciate any insights or code bending that can be provided.

Code:
#SwingHL
# Derived from SwingHL_Fibs V1.3
# Determine the H/L by looking back swing_back1 bars and forward swing_forward1 bars.
#   Total of 1 + swing_forward1 + swing_back1 bars are considered
# If the Current bar is the H/L, a flag is set and the BarNumber is recorded
# The last bar can be neither a high nor a low

input Last_Swing_Only = yes; # Yes = show Last HL2  No = Show All HL
input swing_back1 = 5;       # Look Back Period in Bars
input swing_forward1 = 5;    # Look Forward Period in Bars

# Set onLow true if the low for the current bar is the lowest Low within swing_forward1 and swing_back1 bars
def onLow = low < Lowest(low, swing_forward1)[-swing_forward1] and low < Lowest(low, swing_back1)[1] and !IsNan(close[-1]) ;

# Set onHigh true if the high for the current bar is the highest high within swing_forward1 and swing_back1 bars
def onHigh = high > Highest(high, swing_forward1)[-swing_forward1] and high > Highest(high, swing_back1)[1] and !IsNan(close[-1]) ;

def swinglow1;
def swinglowbar;
def swinghigh1;
def swinghighbar;
def lastlow;
def lasthigh;

# Get bar number for last low and the last high
def PriorLow = Highest(swinglowbar[1], 100);
def PriorHigh = Highest(swinghighbar[1], 100);
# Compare bar number locations for last low/high to determine what is in the rear view
def LastSwingWasHigh = PriorHigh > PriorLow;
def LastSwingWasLow = PriorHigh < PriorLow;

# Identify as swinglow if this is a local low and either the prior pivot was a high or a higher low
swinglow1 = if onLow and (!LastSwingWasLow or low < lastlow[1]) then 1 else 0  ;
swinglowbar = if swinglow1 then BarNumber() else 0;
lastlow = if !swinglow1 or BarNumber() == 1 then lastlow[1] else low;

# Identify as swinghigh if this is a local high and either the prior pivot was a low or a lower high
swinghigh1 = if onHigh and (!LastSwingWasHigh or high > lasthigh[1]) then 1 else 0  ;
swinghighbar = if swinghigh1 then BarNumber() else 0;
lasthigh = if !swinghigh1 or BarNumber() == 1 then lasthigh[1] else high;

#Plot OverwritePreviousHigh = if swinghigh1 and highest(swinghighbar[1], 1000) > highest(swinglowbar[1], 1000) then highest(swinghighbar[1], 1000) else highest(swinglowbar[1], 1000);
#Plot OverwritePreviousHigh = if swinghigh1 and highest(swinghighbar[1], 100) > highest(swinglowbar[1], 100) then 300 else 0;

# Measure the distance in bars between the Last High and Low
def lastswing = HighestAll(swinghighbar) > HighestAll(swinglowbar);

# Visual Representaion
plot SwingHighs = if Last_Swing_Only and BarNumber() == HighestAll(swinghighbar) then high else if !Last_Swing_Only and swinghigh1 then high else Double.NaN;
plot SwingLows = if Last_Swing_Only and BarNumber() == HighestAll(swinglowbar) then low else if !Last_Swing_Only and swinglow1 then low else Double.NaN;

input Bubble_Offset_Factor  = 3;
input Show_Bubbles = yes ;
AddChartBubble(Show_Bubbles and SwingHighs, high + TickSize() * Bubble_Offset_Factor, "H", Color.GREEN, yes);
AddChartBubble(Show_Bubbles and SwingLows, low - TickSize() * Bubble_Offset_Factor, "L", Color.RED, no);

# Debug Statement
#AddChartBubble(Show_Bubbles and SwingHighs, high + TickSize() * Bubble_Offset_Factor, lasthigh[1], Color.GREEN, yes);
#AddChartBubble(Show_Bubbles and SwingLows, low - TickSize() * Bubble_Offset_Factor, lastlow[1], Color.RED, no);

the simplest way would be to increase these 2 variables, to 10 or something
input swing_back1 = 5;
input swing_forward1 = 5;
 
the simplest way would be to increase these 2 variables, to 10 or something
input swing_back1 = 5;
input swing_forward1 = 5;
Thanks. Thought about that, even tried it ....
That does not fix the issue. It would catch one of the highs but not the lows. Increasing the variables opens the indicator up to not identifying some of the clear swing points.
 
This works
Code:
#SwingHL
# Derived from SwingHL_Fibs V1.3
# Determine the H/L by looking back swing_back1 bars and forward swing_forward1 bars.
#   Total of 1 + swing_forward1 + swing_back1 bars are considered
# If the Current bar is the H/L, a flag is set and the BarNumber is recorded
# Neither the the first swing_back1 bars nor the last swing_forward1 bars can be contain a high or low

input Last_Swing_Only = yes; # Yes = show Last HL2  No = Show All HL
input swing_back1 = 5;       # Look Back Period in Bars
input swing_forward1 = 5;    # Look Forward Period in Bars

# Set onLow true if the low for the current bar is the lowest Low within swing_forward1 and swing_back1 bars
def onLow = low < Lowest(low, swing_forward1)[-swing_forward1] and low < Lowest(low, swing_back1)[1] and BarNumber() > swing_back1 + 1;

# Set onHigh true if the high for the current bar is the highest high within swing_forward1 and swing_back1 bars
def onHigh = high > Highest(high, swing_forward1)[-swing_forward1] and high > Highest(high, swing_back1)[1] and BarNumber() > swing_back1 + 1;

def swinglow1;
def swinglowbar;
def swinghigh1;
def swinghighbar;
def barCount = HighestAll(If(IsNaN(open), 0, BarNumber()));
def offset = barCount - BarNumber() - swing_forward1;

# Get bar number for last low and the last high
def PriorLow = Highest(swinglowbar[1], 100);
def PriorHigh = Highest(swinghighbar[1], 100);
# Compare bar number locations for last low/high to determine what is in the rear view
def LastSwingWasHigh = PriorHigh > PriorLow;
def LastSwingWasLow = PriorHigh < PriorLow;

# Identify as swinglow if this is a local low and either the prior pivot was a high or a higher low
swinglow1 = if onLow and (!LastSwingWasLow or low < GetValue(low, BarNumber()-PriorLow)) then 1 else 0  ;
swinglowbar = if swinglow1 then BarNumber() else 0;

# Identify as swinghigh if this is a local high and either the prior pivot was a low or a lower high
swinghigh1 = if onHigh and (!LastSwingWasHigh or high > GetValue(high, BarNumber()-PriorHigh)) then 1 else 0  ;
swinghighbar = if swinghigh1 then BarNumber() else 0;

# Mark the prior Low/High as canceled if it is part or the same swing and higher/lower than the prior Low/High
def cancelpriorlowbar = if onLow and LastSwingWasLow and low <= GetValue(low, BarNumber()-PriorLow) then PriorLow else 0 ;
def cancelpriorhighbar = if onHigh and LastSwingWasHigh and high >= GetValue(high, BarNumber()-PriorHigh) then PriorHigh else 0 ;

# Visual Representaion
plot SwingHighs = if Last_Swing_Only and BarNumber() == HighestAll(swinghighbar) then high else if !Last_Swing_Only and swinghigh1 then (fold iH = 1 to offset + 1 with ShowHigh while ShowHigh == 0 do if BarNumber() == GetValue(cancelpriorhighbar, -iH) then Double.NaN else if BarNumber() < GetValue(cancelpriorhighbar, -iH) or iH == offset then high else 0) else Double.NaN;
plot SwingLows = if Last_Swing_Only and BarNumber() == HighestAll(swinglowbar) then low else if !Last_Swing_Only and swinglow1 then (fold iL = 1 to offset + 1 with ShowLow while ShowLow == 0 do if BarNumber() == GetValue(cancelpriorlowbar, -iL) then Double.NaN else if BarNumber() < GetValue(cancelpriorlowbar, -iL) or iL == offset then low else 0) else Double.NaN;

input Bubble_Offset_Factor  = 3;
input Show_Bubbles = yes ;
AddChartBubble(Show_Bubbles and SwingHighs, high + TickSize() * Bubble_Offset_Factor, "H", Color.GREEN, yes);
AddChartBubble(Show_Bubbles and SwingLows, low - TickSize() * Bubble_Offset_Factor, "L", Color.RED, no);

 
This works
Code:
#SwingHL
# Derived from SwingHL_Fibs V1.3
# Determine the H/L by looking back swing_back1 bars and forward swing_forward1 bars.
#   Total of 1 + swing_forward1 + swing_back1 bars are considered
# If the Current bar is the H/L, a flag is set and the BarNumber is recorded
# Neither the the first swing_back1 bars nor the last swing_forward1 bars can be contain a high or low

input Last_Swing_Only = yes; # Yes = show Last HL2  No = Show All HL
input swing_back1 = 5;       # Look Back Period in Bars
input swing_forward1 = 5;    # Look Forward Period in Bars

# Set onLow true if the low for the current bar is the lowest Low within swing_forward1 and swing_back1 bars
def onLow = low < Lowest(low, swing_forward1)[-swing_forward1] and low < Lowest(low, swing_back1)[1] and BarNumber() > swing_back1 + 1;

# Set onHigh true if the high for the current bar is the highest high within swing_forward1 and swing_back1 bars
def onHigh = high > Highest(high, swing_forward1)[-swing_forward1] and high > Highest(high, swing_back1)[1] and BarNumber() > swing_back1 + 1;

def swinglow1;
def swinglowbar;
def swinghigh1;
def swinghighbar;
def barCount = HighestAll(If(IsNaN(open), 0, BarNumber()));
def offset = barCount - BarNumber() - swing_forward1;

# Get bar number for last low and the last high
def PriorLow = Highest(swinglowbar[1], 100);
def PriorHigh = Highest(swinghighbar[1], 100);
# Compare bar number locations for last low/high to determine what is in the rear view
def LastSwingWasHigh = PriorHigh > PriorLow;
def LastSwingWasLow = PriorHigh < PriorLow;

# Identify as swinglow if this is a local low and either the prior pivot was a high or a higher low
swinglow1 = if onLow and (!LastSwingWasLow or low < GetValue(low, BarNumber()-PriorLow)) then 1 else 0  ;
swinglowbar = if swinglow1 then BarNumber() else 0;

# Identify as swinghigh if this is a local high and either the prior pivot was a low or a lower high
swinghigh1 = if onHigh and (!LastSwingWasHigh or high > GetValue(high, BarNumber()-PriorHigh)) then 1 else 0  ;
swinghighbar = if swinghigh1 then BarNumber() else 0;

# Mark the prior Low/High as canceled if it is part or the same swing and higher/lower than the prior Low/High
def cancelpriorlowbar = if onLow and LastSwingWasLow and low <= GetValue(low, BarNumber()-PriorLow) then PriorLow else 0 ;
def cancelpriorhighbar = if onHigh and LastSwingWasHigh and high >= GetValue(high, BarNumber()-PriorHigh) then PriorHigh else 0 ;

# Visual Representaion
plot SwingHighs = if Last_Swing_Only and BarNumber() == HighestAll(swinghighbar) then high else if !Last_Swing_Only and swinghigh1 then (fold iH = 1 to offset + 1 with ShowHigh while ShowHigh == 0 do if BarNumber() == GetValue(cancelpriorhighbar, -iH) then Double.NaN else if BarNumber() < GetValue(cancelpriorhighbar, -iH) or iH == offset then high else 0) else Double.NaN;
plot SwingLows = if Last_Swing_Only and BarNumber() == HighestAll(swinglowbar) then low else if !Last_Swing_Only and swinglow1 then (fold iL = 1 to offset + 1 with ShowLow while ShowLow == 0 do if BarNumber() == GetValue(cancelpriorlowbar, -iL) then Double.NaN else if BarNumber() < GetValue(cancelpriorlowbar, -iL) or iL == offset then low else 0) else Double.NaN;

input Bubble_Offset_Factor  = 3;
input Show_Bubbles = yes ;
AddChartBubble(Show_Bubbles and SwingHighs, high + TickSize() * Bubble_Offset_Factor, "H", Color.GREEN, yes);
AddChartBubble(Show_Bubbles and SwingLows, low - TickSize() * Bubble_Offset_Factor, "L", Color.RED, no);

This script has still issues. It gives error "Folding 'from' cannot be greater than 'to' 1>0"
Do you fixed study?
 

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

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
340 Online
Create Post

Similar threads

Similar threads

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