Identifying Market Pullback (i.e. 5%+)

scottsamesame

New member
I am looking to document corrections on the S&P over the last 10 years. Specifically, I am looking to find corrections of 5%+ and then count the number of days of the decline, what the high was prior to the decline, what the low was once we put in the bottom of the decline, and what the ultimate % change was during the decline. Does anyone know of a script that's already been created to do this? Or, would it be easier to do this by hand by looking a the charts? TY
 
Solution
I am looking to document corrections on the S&P over the last 10 years. Specifically, I am looking to find corrections of 5%+ and then count the number of days of the decline, what the high was prior to the decline, what the low was once we put in the bottom of the decline, and what the ultimate % change was during the decline. Does anyone know of a script that's already been created to do this? Or, would it be easier to do this by hand by looking a the charts? TY


find peaks and valleys, based on x bars, before and after them.
draw horizontal lines from them. skip over +2 of the same signal
( if 2 peaks in a row, skip 2nd peak)
find the price and percent difference between them.
enter a minimum %. bubble colors determined by...
I am looking to document corrections on the S&P over the last 10 years. Specifically, I am looking to find corrections of 5%+ and then count the number of days of the decline, what the high was prior to the decline, what the low was once we put in the bottom of the decline, and what the ultimate % change was during the decline. Does anyone know of a script that's already been created to do this? Or, would it be easier to do this by hand by looking a the charts? TY


find peaks and valleys, based on x bars, before and after them.
draw horizontal lines from them. skip over +2 of the same signal
( if 2 peaks in a row, skip 2nd peak)
find the price and percent difference between them.
enter a minimum %. bubble colors determined by this.
can change color of bars.

Code:
# corrections_peak_to_valley_00

#https://usethinkscript.com/threads/identifying-market-pullback-i-e-5.12744/
#Identifying Market Pullback (i.e. 5%+)
# Thread starterscottsamesame  Start dateToday at 9:01 AM

#.........................................
# ref: peak/valley code , robert  post#10
# https://usethinkscript.com/threads/zigzag-high-low-with-supply-demand-zones-for-thinkorswim.172/#post-7048
#.........................................

input min_percent_change = 5;
input length = 10;

def na = double.nan;
def bn = BarNumber();
def lastBar = HighestAll(if IsNaN(close) then 0 else bn);
def offset = Min(length - 1, lastBar - bn);

def peak = high > highest(high[1], length - 1) and high == GetValue(highest(high, length), -offset);
def valley = low < Lowest(low[1], length - 1) and low == GetValue(Lowest(low, length), -offset);

# set to 0 if peak and valley happen on same bar
def pv = if bn == 1 then 0
  else if peak and valley then 0
  else if peak then 1
  else if valley then -1
  else pv[1];

def peak2 = if bn == 1 then 0
  else if peak and pv[1] != -1 then 0
  else peak;

def valley2 = if bn == 1 then 0
  else if valley and pv[1] != 1 then 0
  else valley;

input color_peak_valley_bars = yes;
input color_remaining_bars = yes;

AssignPriceColor(
       if (peak and color_peak_valley_bars) then Color.LIME 
  else if (valley and color_peak_valley_bars) then Color.magenta
  else if (peak and !color_peak_valley_bars) then Color.current
  else if (valley and !color_peak_valley_bars) then Color.current
  else if color_remaining_bars then Color.DARK_GRAY
  else color.current);

def peak_line = if bn == 1 then 0
  else if peak2 then close
  else if valley2[1] then 0
  else peak_line[1]; 

def valley_line = if bn == 1 then 0
  else if valley2 then close
  else if peak2[1] then 0
  else valley_line[1]; 

plot zp = if peak_line > 0 then peak_line else na;
zp.setdefaultcolor(color.red);
zp.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);

plot zv = if valley_line > 0 then valley_line else na;
zv.setdefaultcolor(color.green);
zv.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);

#----------------------------
input gain_drop_stats = yes;

def gain = if pv[1] == 0 then 0
  else if peak2 then round(close - valley_line, 2)
  else 0;
def gain_per = if pv[1] == 0 then 0 else round( 100 * gain/valley_line, 1);
def is_gain_big = (gain_per >= min_percent_change);

addchartbubble((gain_drop_stats and peak2 and valley_line > 0), high,
gain + "\n" +
gain_per + " %"
, ( if is_gain_big then color.green else color.gray), yes);

#----------------------------
def drop = if pv[1] == 0 then 0
  else if valley2 then round(peak_line - close, 2)
  else 0;
def drop_per = if pv[1] == 0 then 0 else round( 100 * drop/peak_line, 1);
def is_drop_big = (drop_per >= min_percent_change);

addchartbubble((gain_drop_stats and valley2 and peak_line > 0), low,
drop + "\n" +
drop_per + " %"
, ( if is_drop_big then color.red else color.gray), no);
#

3UJtlja.jpg
 
Solution
find peaks and valleys, based on x bars, before and after them.
draw horizontal lines from them. skip over +2 of the same signal
( if 2 peaks in a row, skip 2nd peak)
find the price and percent difference between them.
enter a minimum %. bubble colors determined by this.
can change color of bars.

Code:
# corrections_peak_to_valley_00

#https://usethinkscript.com/threads/identifying-market-pullback-i-e-5.12744/
#Identifying Market Pullback (i.e. 5%+)
# Thread starterscottsamesame  Start dateToday at 9:01 AM

#.........................................
# ref: peak/valley code , robert  post#10
# https://usethinkscript.com/threads/zigzag-high-low-with-supply-demand-zones-for-thinkorswim.172/#post-7048
#.........................................

input min_percent_change = 5;
input length = 10;

def na = double.nan;
def bn = BarNumber();
def lastBar = HighestAll(if IsNaN(close) then 0 else bn);
def offset = Min(length - 1, lastBar - bn);

def peak = high > highest(high[1], length - 1) and high == GetValue(highest(high, length), -offset);
def valley = low < Lowest(low[1], length - 1) and low == GetValue(Lowest(low, length), -offset);

# set to 0 if peak and valley happen on same bar
def pv = if bn == 1 then 0
  else if peak and valley then 0
  else if peak then 1
  else if valley then -1
  else pv[1];

def peak2 = if bn == 1 then 0
  else if peak and pv[1] != -1 then 0
  else peak;

def valley2 = if bn == 1 then 0
  else if valley and pv[1] != 1 then 0
  else valley;

input color_peak_valley_bars = yes;
input color_remaining_bars = yes;

AssignPriceColor(
       if (peak and color_peak_valley_bars) then Color.LIME
  else if (valley and color_peak_valley_bars) then Color.magenta
  else if (peak and !color_peak_valley_bars) then Color.current
  else if (valley and !color_peak_valley_bars) then Color.current
  else if color_remaining_bars then Color.DARK_GRAY
  else color.current);

def peak_line = if bn == 1 then 0
  else if peak2 then close
  else if valley2[1] then 0
  else peak_line[1];

def valley_line = if bn == 1 then 0
  else if valley2 then close
  else if peak2[1] then 0
  else valley_line[1];

plot zp = if peak_line > 0 then peak_line else na;
zp.setdefaultcolor(color.red);
zp.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);

plot zv = if valley_line > 0 then valley_line else na;
zv.setdefaultcolor(color.green);
zv.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);

#----------------------------
input gain_drop_stats = yes;

def gain = if pv[1] == 0 then 0
  else if peak2 then round(close - valley_line, 2)
  else 0;
def gain_per = if pv[1] == 0 then 0 else round( 100 * gain/valley_line, 1);
def is_gain_big = (gain_per >= min_percent_change);

addchartbubble((gain_drop_stats and peak2 and valley_line > 0), high,
gain + "\n" +
gain_per + " %"
, ( if is_gain_big then color.green else color.gray), yes);

#----------------------------
def drop = if pv[1] == 0 then 0
  else if valley2 then round(peak_line - close, 2)
  else 0;
def drop_per = if pv[1] == 0 then 0 else round( 100 * drop/peak_line, 1);
def is_drop_big = (drop_per >= min_percent_change);

addchartbubble((gain_drop_stats and valley2 and peak_line > 0), low,
drop + "\n" +
drop_per + " %"
, ( if is_drop_big then color.red else color.gray), no);
#

3UJtlja.jpg
This is a nice indicator to track corrections. Can you briefly explain how it works? Does it repaint? Thanks for posting!
 
This is a nice indicator to track corrections. Can you briefly explain how it works? Does it repaint? Thanks for posting!

it finds peaks and valleys, based on this,
input length = 10;
on every bar, it looks back 10 bars and forward 10 bars and checks if the current bar is,
..the highest , for a peak
..or the lowest, for a valley.

it uses code from robert, that uses a changing offset to look for valleys and peaks, so it can still find them on the last 10 bars. if this wasn't used , and it looked ahead 10 bars and tried to read from a bar that doesn't exist, there would be an error, and it wouldn't draw a line.
def offset = Min(length - 1, lastBar - bn);

it could redraw/undraw a line... during the last 10 bars on the chart.
it is looking at different quantities of bars in the future. when it gets to the 11th bar from the last, it won't change anymore.

sometimes 2 of the same, peak or valley, happen in a row. if they do, i wanted the 2nd one to be ignored, and the line from the first to keep going. i left in code to highlight every peak and valley, so users could see when one is skipped (no line from it)

this calculates the price level for a peak line,
def peak_line = if bn == 1 then 0 # if the 1st bar , set to 0
else if peak2 then close # if a peak occurs, read the close
else if valley2[1] then 0 # if a valley occurs , reset the price
else peak_line[1]; # if no signals , then read the previous value to keep it going.
 
I added the following at the bottom of this script and it works but it "dings" whenever the next candle appears regardless of whether there's a new pullback or not. Example being if I have a red or green line showing it will ding and show I'm currently at a peak or a valley every time rather than only dinging when a new peak or valley shows. My first attempt at this so I think I'm headed in the right direction. :)

#Alerts
Alert(zp, “Peak”, Alert.BAR, Sound.Ding);

Alert(zv, “Valley”, Alert.BAR, Sound.Ding);
 
I added the following at the bottom of this script and it works but it "dings" whenever the next candle appears regardless of whether there's a new pullback or not. Example being if I have a red or green line showing it will ding and show I'm currently at a peak or a valley every time rather than only dinging when a new peak or valley shows. My first attempt at this so I think I'm headed in the right direction. :)

#Alerts
Alert(zp, “Peak”, Alert.BAR, Sound.Ding);

Alert(zv, “Valley”, Alert.BAR, Sound.Ding);
I can't say whether there is an issue with your logic. I don't get involved with repainting alerts.

Any scripts that is identifying higher highs and lower lows repaint.
Attempting to get repainting alerts is a lesson in futility.

Scripts that repaint should NOT be used in Backtesting Strategies, Conditional Orders or Scans, Watchlists, Alerts.
a. The script will fire on a false alert. The signal will not appear on your chart. You will be left wondering why you got the alert. You will think the script is broken.
b. In other cases, the script will not fire an alert. But the trigger will appear on the chart. You will think the script is broken.
That is because it wasn't there in real time, so real time alerts don't function. It was painted on afterward.
 
find peaks and valleys, based on x bars, before and after them.
draw horizontal lines from them. skip over +2 of the same signal
( if 2 peaks in a row, skip 2nd peak)
find the price and percent difference between them.
enter a minimum %. bubble colors determined by this.
can change color of bars.

Code:
# corrections_peak_to_valley_00

#https://usethinkscript.com/threads/identifying-market-pullback-i-e-5.12744/
#Identifying Market Pullback (i.e. 5%+)
# Thread starterscottsamesame  Start dateToday at 9:01 AM

#.........................................
# ref: peak/valley code , robert  post#10
# https://usethinkscript.com/threads/zigzag-high-low-with-supply-demand-zones-for-thinkorswim.172/#post-7048
#.........................................

input min_percent_change = 5;
input length = 10;

def na = double.nan;
def bn = BarNumber();
def lastBar = HighestAll(if IsNaN(close) then 0 else bn);
def offset = Min(length - 1, lastBar - bn);

def peak = high > highest(high[1], length - 1) and high == GetValue(highest(high, length), -offset);
def valley = low < Lowest(low[1], length - 1) and low == GetValue(Lowest(low, length), -offset);

# set to 0 if peak and valley happen on same bar
def pv = if bn == 1 then 0
  else if peak and valley then 0
  else if peak then 1
  else if valley then -1
  else pv[1];

def peak2 = if bn == 1 then 0
  else if peak and pv[1] != -1 then 0
  else peak;

def valley2 = if bn == 1 then 0
  else if valley and pv[1] != 1 then 0
  else valley;

input color_peak_valley_bars = yes;
input color_remaining_bars = yes;

AssignPriceColor(
       if (peak and color_peak_valley_bars) then Color.LIME
  else if (valley and color_peak_valley_bars) then Color.magenta
  else if (peak and !color_peak_valley_bars) then Color.current
  else if (valley and !color_peak_valley_bars) then Color.current
  else if color_remaining_bars then Color.DARK_GRAY
  else color.current);

def peak_line = if bn == 1 then 0
  else if peak2 then close
  else if valley2[1] then 0
  else peak_line[1];

def valley_line = if bn == 1 then 0
  else if valley2 then close
  else if peak2[1] then 0
  else valley_line[1];

plot zp = if peak_line > 0 then peak_line else na;
zp.setdefaultcolor(color.red);
zp.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);

plot zv = if valley_line > 0 then valley_line else na;
zv.setdefaultcolor(color.green);
zv.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);

#----------------------------
input gain_drop_stats = yes;

def gain = if pv[1] == 0 then 0
  else if peak2 then round(close - valley_line, 2)
  else 0;
def gain_per = if pv[1] == 0 then 0 else round( 100 * gain/valley_line, 1);
def is_gain_big = (gain_per >= min_percent_change);

addchartbubble((gain_drop_stats and peak2 and valley_line > 0), high,
gain + "\n"
, ( if is_gain_big then color.green else color.gray), yes);

#----------------------------
def drop = if pv[1] == 0 then 0
  else if valley2 then round(peak_line - close, 2)
  else 0;
def drop_per = if pv[1] == 0 then 0 else round( 100 * drop/peak_line, 1);
def is_drop_big = (drop_per >= min_percent_change);

addchartbubble((gain_drop_stats and valley2 and peak_line > 0), low,
drop + "\n" 
, ( if is_drop_big then color.red else color.gray), no);
#

View attachment 15931
I removed the % in the bubble and looks a little tighter.
 

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
324 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