Looking for a indicator for a scan that chooses those stocks whose highest high and lowest low is within a given percent of each other over a period of time.
# hilo_within_wper_xmin_lower2
# https://usethinkscript.com/threads/highest-high-and-lowest-low-within-2-over-time.10068/
# Highest high and lowest low within 2% over time
# Smile Feb 9, 2022
# Looking for a indicator for
# a scan that finds stocks,
# highest high and lowest low is within a given percent of each other,
# over a period of time.
declare lower;
def na = Double.NaN;
def bn = BarNumber();
input bars_back = 30;
def hi = Highest(high, bars_back);
def lo =...
Looking for a indicator for a scan that chooses those stocks whose highest high and lowest low is within a given percent of each other over a period of time.
# hilo_within_wper_xmin_lower2
# https://usethinkscript.com/threads/highest-high-and-lowest-low-within-2-over-time.10068/
# Highest high and lowest low within 2% over time
# Smile Feb 9, 2022
# Looking for a indicator for
# a scan that finds stocks,
# highest high and lowest low is within a given percent of each other,
# over a period of time.
declare lower;
def na = Double.NaN;
def bn = BarNumber();
input bars_back = 30;
def hi = Highest(high, bars_back);
def lo = Lowest(low, bars_back);
input max_percent = 2.0;
def per = Round(100 * (hi - lo) / lo, 2);
plot per_ok = (per < max_percent);
per_ok.SetDefaultColor(Color.CYAN);
#----------------------
# test data if used in a lower
input test_labels = no;
AddLabel(test_labels, "look back " + bars_back + " bars", Color.YELLOW);
AddLabel(test_labels, "highest " + hi, Color.YELLOW);
AddLabel(test_labels, "lowest " + lo, Color.YELLOW);
AddLabel(test_labels, "diff " + (hi - lo), Color.YELLOW);
AddLabel(test_labels, per + "%", ( if per_ok then Color.GREEN else Color.GRAY));
#
# hilo_within_wper_xmin
# upper study
def na= double.nan;
def bn = barnumber();
def lastbar = (!isnan(close[0]) and isnan(close[-1]));
input bars_back = 30;
def len = bars_back;
def len_rng = if (!isnan(close[0]) and isnan(close[-len])) then 1 else 0;
def hi = if bn == 1 then na
else if lastbar[-(len-1)] then highest(high[-(len-1)], len+0)
else if lastbar[1] then na
else hi[1];
def lo = if bn == 1 then na
else if lastbar[-(len-1)] then lowest(low[-(len-1)], len+0)
else if lastbar[1] then na
else lo[1];
input max_percent = 2.0;
def per = round(100 * (hi-lo)/lo, 2);
def per_ok = (per < max_percent);
addlabel(1, "look back " + len + " bars", color.yellow);
addlabel(1, "highest " + hi, color.yellow);
addlabel(1, "lowest " + lo, color.yellow);
addlabel(1, "diff " + (hi - lo), color.yellow);
addlabel(1, per + "%", ( if per_ok then color.green else color.gray));
plot hiz = hi;
plot loz = lo;
hiz.SetDefaultColor(Color.cyan);
loz.SetDefaultColor(Color.cyan);
#
# hilo_within_wper_xmin_lower
# lower study
declare lower;
def na= double.nan;
def bn = barnumber();
def lastbar = (!isnan(close[0]) and isnan(close[-1]));
input bars_back = 30;
def len = bars_back;
#def len_rng = if (!isnan(close[0]) and isnan(close[-len])) then 1 else 0;
def hi = if bn == 1 then na
else if lastbar[-(len-1)] then highest(high[-(len-1)], len+0)
else if lastbar[1] then na
else hi[1];
def lo = if bn == 1 then na
else if lastbar[-(len-1)] then lowest(low[-(len-1)], len+0)
else if lastbar[1] then na
else lo[1];
input max_percent = 2.0;
def per = round(100 * (hi-lo)/lo, 2);
def per_ok = (per < max_percent);
plot z = if bn == 1 then 0 else
if !isnan(per_ok) then per_ok
else 0;
# may have to disable this label when used in a scan
addlabel(1, "look back " + len + " bars", color.yellow);
#
Can't quite wrap my head around the bar number logic. How can you shift those hi and low snippets to only find the highest highs that occur after the lows. So we're looking for low to high gain percentage and not including high to low moves.i think the lower study will work as a scan. the upper can be used to verify the data.
i don't scan, so i made 2 chart studies, to test my formulas, an upper and a lower.
both studies,
. ask for how many bars back to compare the highest and lowest, from the last bar.
. calculate the ratio of the range to the lowest. (highest - lowest)/lowest
. compare the ratio (percent) to a target percent(2).
the upper study,
. draws horizontal lines, at the highest and lowest prices, for x bars back from the last bar.
. has labels to display values. the % label turns green when the % is less than the target %.
the lower study,
. plots a line,
. = 1 if the hi-lo range % < target %
. = 0 if not
. draws a label, listing how many bars back.
Upper
Ruby:# hilo_within_wper_xmin # upper study def na= double.nan; def bn = barnumber(); def lastbar = (!isnan(close[0]) and isnan(close[-1])); input bars_back = 30; def len = bars_back; def len_rng = if (!isnan(close[0]) and isnan(close[-len])) then 1 else 0; def hi = if bn == 1 then na else if lastbar[-(len-1)] then highest(high[-(len-1)], len+0) else if lastbar[1] then na else hi[1]; def lo = if bn == 1 then na else if lastbar[-(len-1)] then lowest(low[-(len-1)], len+0) else if lastbar[1] then na else lo[1]; input max_percent = 2.0; def per = round(100 * (hi-lo)/lo, 2); def per_ok = (per < max_percent); addlabel(1, "look back " + len + " bars", color.yellow); addlabel(1, "highest " + hi, color.yellow); addlabel(1, "lowest " + lo, color.yellow); addlabel(1, "diff " + (hi - lo), color.yellow); addlabel(1, per + "%", ( if per_ok then color.green else color.gray)); plot hiz = hi; plot loz = lo; hiz.SetDefaultColor(Color.cyan); loz.SetDefaultColor(Color.cyan); #
Lower / scan
Ruby:# hilo_within_wper_xmin_lower # lower study declare lower; def na= double.nan; def bn = barnumber(); def lastbar = (!isnan(close[0]) and isnan(close[-1])); input bars_back = 30; def len = bars_back; #def len_rng = if (!isnan(close[0]) and isnan(close[-len])) then 1 else 0; def hi = if bn == 1 then na else if lastbar[-(len-1)] then highest(high[-(len-1)], len+0) else if lastbar[1] then na else hi[1]; def lo = if bn == 1 then na else if lastbar[-(len-1)] then lowest(low[-(len-1)], len+0) else if lastbar[1] then na else lo[1]; input max_percent = 2.0; def per = round(100 * (hi-lo)/lo, 2); def per_ok = (per < max_percent); plot z = if bn == 1 then 0 else if !isnan(per_ok) then per_ok else 0; # may have to disable this label when used in a scan addlabel(1, "look back " + len + " bars", color.yellow); #
this shows the upper and lower chart studies. BK 5min 2/28/22
View attachment 13680
Can't quite wrap my head around the bar number logic. How can you shift those hi and low snippets to only find the highest highs that occur after the lows. So we're looking for low to high gain percentage and not including high to low moves.
*edit: For clarification, I'm trying to learn the logic of how to scan for (and check by plotting the high and lows) the largest % gain from lowest low to highest high within 50 bars.
Can't quite wrap my head around the bar number logic. How can you shift those hi and low snippets to only find the highest highs that occur after the lows. So we're looking for low to high gain percentage and not including high to low moves.
*edit: For clarification, I'm trying to learn the logic of how to scan for (and check by plotting the high and lows) the largest % gain from lowest low to highest high within 50 bars.
# hilo_within_wper_xmin3
# https://usethinkscript.com/threads/highest-high-and-lowest-low-within-2-over-time.10068/
# post3
# how to scan for (and check by plotting the high and lows) the largest % gain from lowest low to highest high within 50 bars.
#declare lower;
def na = Double.NaN;
def bn = BarNumber();
input bars_back = 50;
def hi = Highest(high, bars_back);
def lo = Lowest(low, bars_back);
input max_percent = 2.0;
def per = Round(100 * (hi - lo) / lo, 2);
def per_ok = (per < max_percent);
def chg = (per - per[1]);
def biggest_change = highest(chg, bars_back);
input test_bubble = yes;
addchartbubble(test_bubble, low * 0.999,
hi + " hi\n" +
lo + " lo\n" +
(hi - lo) + " diff\n" +
per + " %\n" +
chg + " chg"
, ( if per_ok then Color.GREEN else Color.GRAY), no);
#per_ok.SetDefaultColor(Color.CYAN);
#----------------------
# test data if used in a lower
input test_labels = no;
AddLabel(test_labels, "look back " + bars_back + " bars", Color.YELLOW);
AddLabel(test_labels, "highest " + hi, Color.YELLOW);
AddLabel(test_labels, "lowest " + lo, Color.YELLOW);
AddLabel(test_labels, "diff " + (hi - lo), Color.YELLOW);
AddLabel(test_labels, per + "%", ( if per_ok then Color.GREEN else Color.GRAY));
#
oh nono, i get how the scans work, I just didn't explain it very well (was gettin late haha) Let's say you set 50 bars and you want to see if at some point within those last 50 days, was there a move of at least 50%. You don't know if that took place over 3 days or 20 days, etc all that matters is that from the lowest low to the highest high that comes after the low, did it hit that 50% threshold. Finding the highest 1 day change would be the easy part, its the not knowing the exact beginning and end point or the length between the 2, or stipulating that the high comes after the low is where my head goes full-on 100% derp mode. As a scan, the true condition in this case would effectively be "yes, within the last 50 bars there was a low to high move of at least 50% " Thanks for your help btw*edit: For clarification, I'm trying to learn the logic of how to scan for (and check by plotting the high and lows) the largest % gain from lowest low to highest high within 50 bars.
you can't scan for a number. scanning finds true conditions.
you will have to come up with some percent to compare the % numbers to.
maybe this will help you
Code:# hilo_within_wper_xmin3 # https://usethinkscript.com/threads/highest-high-and-lowest-low-within-2-over-time.10068/ # post3 # how to scan for (and check by plotting the high and lows) the largest % gain from lowest low to highest high within 50 bars. #declare lower; def na = Double.NaN; def bn = BarNumber(); input bars_back = 50; def hi = Highest(high, bars_back); def lo = Lowest(low, bars_back); input max_percent = 2.0; def per = Round(100 * (hi - lo) / lo, 2); def per_ok = (per < max_percent); def chg = (per - per[1]); def biggest_change = highest(chg, bars_back); input test_bubble = yes; addchartbubble(test_bubble, low * 0.999, hi + " hi\n" + lo + " lo\n" + (hi - lo) + " diff\n" + per + " %\n" + chg + " chg" , ( if per_ok then Color.GREEN else Color.GRAY), no); #per_ok.SetDefaultColor(Color.CYAN); #---------------------- # test data if used in a lower input test_labels = no; AddLabel(test_labels, "look back " + bars_back + " bars", Color.YELLOW); AddLabel(test_labels, "highest " + hi, Color.YELLOW); AddLabel(test_labels, "lowest " + lo, Color.YELLOW); AddLabel(test_labels, "diff " + (hi - lo), Color.YELLOW); AddLabel(test_labels, per + "%", ( if per_ok then Color.GREEN else Color.GRAY)); #
how-do-i-code-a-sequence-of-events Update: read through the code in this thread and still can't figure out how to make this work. Please halpI was thinking you could use the getminvalueoffset to get the lowest low bar number, but how do I proceed to get the high that's after the low since you cant do like "bar number +1" in the length bracket?
oh nono, i get how the scans work, I just didn't explain it very well (was gettin late haha) Let's say you set 50 bars and you want to see if at some point within those last 50 days, was there a move of at least 50%. You don't know if that took place over 3 days or 20 days, etc all that matters is that from the lowest low to the highest high that comes after the low, did it hit that 50% threshold. Finding the highest 1 day change would be the easy part, its the not knowing the exact beginning and end point or the length between the 2, or stipulating that the high comes after the low is where my head goes full-on 100% derp mode. As a scan, the true condition in this case would effectively be "yes, within the last 50 bars there was a low to high move of at least 50% " Thanks for your help btw
# scan - was there a 50% rise?
input bars_back = 50;
input percent_rise = 50.0;
# find bar with lowest low
def lo_off = getminvalueoffset( bars_back );
# get low price from lowest low
def lolo = getvalue( low, lo_off );
# calc the price at a 50% rise
def dollar_rise = lolo * (1 + (percent_rise/100));
# loop, find bar qty after lowest low, when/if price rises more than x %
# use this for offset, (lo_off - i))
# so loop starts at bar after the lowest low, not current bar.
def rise_off = fold i = 1 to lo_off+1
with p
while getvalue(high, (lo_off - i)) <= dollar_rise
do p + 1;
# check if loop ran thru all the numbers.
# if it didn't rise high enough, set to 0.
def rise_off2 = if rise_off == lo_off and high < dollar_rise then 0 else rise_off;
# if rise_off2 is > 0 then should mean a rise of 50% was found
# lo_off , offset back to the lowest low.
# rise_off2 , bars after lowest low, when price was x % higher. if 0 then it didn't get x% higher.
plot scan = rise_off2 > 0;
This helped alot in trying to understand the fold function, but there's some kind of error as far as getting the actual pass/fail and I cant seem to find it.i might be away a few days, so i typed this on my cell. untested.
find offset back to lowest low.
run a loop, starting from the lowest low, to current bar.
looking to see if high - (lowest low) is a 50% rise. if it is, stop loop and and save loop index number.
scan code. true if it finds a rise of x %
Code:# scan - was there a 50% rise? input bars_back = 50; input percent_rise = 50.0; # find bar with lowest low def lo_off = getminvalueoffset( bars_back ); # get low price from lowest low def lolo = getvalue( low, lo_off ); # calc the price at a 50% rise def dollar_rise = lolo * (1 + (percent_rise/100)); # loop, find bar qty after lowest low, when/if price rises more than x % # use this for offset, (lo_off - i)) # so loop starts at bar after the lowest low, not current bar. def rise_off = fold i = 1 to lo_off+1 with p while getvalue(high, (lo_off - i)) <= dollar_rise do p + 1; # check if loop ran thru all the numbers. # if it didn't rise high enough, set to 0. def rise_off2 = if rise_off == lo_off and high < dollar_rise then 0 else rise_off; # if rise_off2 is > 0 then should mean a rise of 50% was found # lo_off , offset back to the lowest low. # rise_off2 , bars after lowest low, when price was x % higher. if 0 then it didn't get x% higher. plot scan = rise_off2 > 0;
https://tlc.thinkorswim.com/center/reference/thinkScript/Functions/Tech-Analysis/GetMinValueOffset
# scan - was there a 50% rise?
input bars_back = 50;
input percent_rise = 50.0;
# find bar with lowest low
def lo_off = getminvalueoffset(low, bars_back );
# get low price from lowest low
def lolo = getvalue( low, lo_off );
# calc the price at a 50% rise
def dollar_rise = lolo * (1 + (percent_rise/100));
# loop, find bar qty after lowest low, when/if price rises more than x %
# use this for offset, (lo_off - i))
# so loop starts at bar after the lowest low, not current bar.
def rise_off = fold i = 1 to bars_back + 1
with p
while getValue(high, lo_off - i) <= dollar_rise
do p + 1;
# check if loop ran thru all the numbers.
# if it didn't rise high enough, set to 0.
def rise_off2 = if high < dollar_rise then 0 else rise_off; # rise_off == lo_off and
# if rise_off2 is > 0 then should mean a rise of 50% was found
# lo_off , offset back to the lowest low.
# rise_off2 , bars after lowest low, when price was x % higher. if 0 then it didn't get x% higher.
plot scan = rise_off2 > 0;
Join useThinkScript to post your question to a community of 21,000+ developers and traders.
Start a new thread and receive assistance from our community.
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.
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.