scan for stocks that have traded within a 20% range over the past year

jimbo-d

New member
Can anyone tell me how to scan for stocks that have traded within a 20% range over the past year? For example, today's price is 30. 20% of 30 is 6. So a stock that has traded between 24 and 36 over the last year would meet the criteria. Looking for stocks under $50/share. Thanks for reading...
 
Solution
Can anyone tell me how to scan for stocks that have traded within a 20% range over the past year? For example, today's price is 30. 20% of 30 is 6. So a stock that has traded between 24 and 36 over the last year would meet the criteria. Looking for stocks under $50/share. Thanks for reading...

i figured my range differently, the total from lowest to highest, not just from midlevel to highest.
so you will want to use 40% to get the equivelent of the 20% in your example.

-----------------------

check if past prices stayed within a % range of the current price

here are several versions

these studies calculate a total $ range that is some % of the close.
the default is 20%. this range is centered on the close price.
the...

halcyonguy

Well-known member
VIP
Lifetime
Can anyone tell me how to scan for stocks that have traded within a 20% range over the past year? For example, today's price is 30. 20% of 30 is 6. So a stock that has traded between 24 and 36 over the last year would meet the criteria. Looking for stocks under $50/share. Thanks for reading...

i figured my range differently, the total from lowest to highest, not just from midlevel to highest.
so you will want to use 40% to get the equivelent of the 20% in your example.

-----------------------

check if past prices stayed within a % range of the current price

here are several versions

these studies calculate a total $ range that is some % of the close.
the default is 20%. this range is centered on the close price.
the upper limit is close + 10%. the lower limit is close - 10%.


when i want a column or scan study, i usually start with a lower study, and get it to work. then remove most of the output code to make a column/scan study. since this applied to prices, i started with an upper study.

---------------------------

test study - upper
draw lines for close, upper and lower limits.
a vertical line for the start of the period.
default data is days , and 252 bars , which is a year.

several labels display some $ and % stats.
the last 3 labels show if price stayed within the limits or went outside them.

set the percent to a big number to test if price stayed within the desired range.


Ruby:
# price_in_rng_past_xbars_upper_0
# price_in_rng_past_xmonths_0_lower

# test , upper study
# check if a stock has stayed within a price range, over a time period

declare upper;
def na = double.nan;

input range_percent = 20.0;

# 1 year of data
input time_period = AggregationPeriod.day;
input quantity_of_time_periods = 252;

def rnghi = highest(high(period = time_period), quantity_of_time_periods);
def rnglo = lowest(low(period = time_period), quantity_of_time_periods);

def rng_first = (!isnan(close[-(quantity_of_time_periods-1)]) and isnan(close[-(quantity_of_time_periods-0)]));

#----------------------------------------
# save the current close price, on all bars
# https://usethinkscript.com/threads/current-price-line-indicator-for-thinkorswim.8793/
# Line At Price  Mobius
# Alternative to using the HighestAll() function
def barsBack = 1000;
def c = if !IsNaN(close) and IsNaN(close[-1])
        then close
        else c[1];
def lastcls = if isNaN(close[-barsBack])
            then c[-barsBack]
            else Double.NaN;
input show_close_line = yes;
plot line = if show_close_line then lastcls else na;
line.SetLineWeight(1);
line.SetDefaultColor(Color.LIME);
line.SetStyle(Curve.MEDIUM_DASH);
 
#-----------------------------------------
# compare current close price to price highest and lowest
def range1 = round(lastcls * range_percent/100, 2);
def top = round(lastcls + (range1/2),2);
def bot = round(lastcls - (range1/2),2);

#---------------------
## for testing in a lower study
#input months_back = 12;
#input agg1 = AggregationPeriod.month;
#def rnghi = highest(high(period = agg1), months_back);
#def rnglo = lowest(low(period = agg1), months_back);

#--------------------

# show a vertical line, x days back. start of data range
input show_vertical_line = yes;
addverticalline(show_vertical_line and rng_first,"    RANGE START", color.yellow);

# = 1 if price was out of range
def above_rng = (rnghi > top);
def below_rng = (rnglo < bot);
# = 1 if price stayed in the range
def within_rng = (!above_rng and !below_rng);

addlabel(1, "range : " + aspercent(range_percent/100), color.yellow);
addlabel(1, " of " + asdollars(close), color.yellow);
addlabel(1, "range : " + asdollars(range1), color.yellow);
addlabel(1, "  ", color.black);
addlabel(1, " +- range : " + asdollars(range1/2), color.yellow);

addlabel(1, " ", color.black);
addlabel(1, "range top " + top, color.yellow);
addlabel(1, "range bottom " + bot, color.yellow);
addlabel(1, "  ", color.black);

addlabel(1, "Above" , ( if above_rng then color.red else color.gray));
addlabel(1, "Within range" , ( if within_rng then color.green else color.gray));
addlabel(1, "Below" , ( if below_rng then color.red else color.gray));

input show_range_lines = yes;
plot ztop = top;
ztop.SetDefaultColor(Color.gray);
ztop.SetHiding(!show_range_lines);
plot zbot = bot;
zbot.SetDefaultColor(Color.gray);
zbot.SetHiding(!show_range_lines);
#

chart set to day
when prices for the past 252 days are within the % high and low limits, the 'within range' label is green, and the above and below labels are gray.
KzGHnyT.jpg


when prices for the past 252 days are higher or lower than the % high and low limits, the 'within range' label is gray, and the above label and/or the below label are red.
hONcbJw.jpg


---------------------------

test study - lower

Ruby:
# price_in_rng_past_xbars_lower_0

# test , lower study
# check if a stock has stayed within a price range, over a time period
# show a value of 1 if price stayed within the range, over the past x days

declare lower;
def na = double.nan;
def bn = barnumber();

input range_percent = 20.0;

# 1 year of data
input time_period = AggregationPeriod.day;
input quantity_of_time_periods = 252;

def rnghi = highest(high(period = time_period), quantity_of_time_periods);
def rnglo = lowest(low(period = time_period), quantity_of_time_periods);

def rng_first = (!isnan(close[-(quantity_of_time_periods-1)]) and isnan(close[-(quantity_of_time_periods-0)]));

#----------------------------------------
# save the current close price, on all bars
# https://usethinkscript.com/threads/current-price-line-indicator-for-thinkorswim.8793/
# Line At Price  Mobius
# Alternative to using the HighestAll() function
def barsBack = 1000;
def c = if !IsNaN(close) and IsNaN(close[-1])
        then close
        else c[1];
def lastcls = if isNaN(close[-barsBack])
            then c[-barsBack]
            else Double.NaN;
input show_close_line = no;
plot line = if show_close_line then lastcls else na;
line.SetLineWeight(1);
line.SetDefaultColor(Color.LIME);
line.SetStyle(Curve.MEDIUM_DASH);
 
#-----------------------------------------
# compare current close price to price highest and lowest
def range1 = round(lastcls * range_percent/100, 2);
def top = round(lastcls + (range1/2),2);
def bot = round(lastcls - (range1/2),2);

#---------------------
## for testing in a lower study
#input months_back = 12;
#input agg1 = AggregationPeriod.month;
#def rnghi = highest(high(period = agg1), months_back);
#def rnglo = lowest(low(period = agg1), months_back);

#--------------------

# show a vertical line, x days back. start of data range
input show_vertical_line = yes;
addverticalline(show_vertical_line and rng_first,"    RANGE START", color.yellow);

# = 1 if price was out of range
def above_rng = (rnghi > top);
def below_rng = (rnglo < bot);
# = 1 if price stayed in the range
def within_rng = (!above_rng and !below_rng);

addlabel(1, "range : " + aspercent(range_percent/100), color.yellow);
addlabel(1, " of " + asdollars(close), color.yellow);
addlabel(1, "range : " + asdollars(range1), color.yellow);
addlabel(1, "  ", color.black);
addlabel(1, " +- range : " + asdollars(range1/2), color.yellow);

addlabel(1, " ", color.black);
addlabel(1, "range top " + top, color.yellow);
addlabel(1, "range bottom " + bot, color.yellow);
addlabel(1, "  ", color.black);

addlabel(1, "Above" , ( if above_rng then color.red else color.gray));
addlabel(1, "Within range" , ( if within_rng then color.green else color.gray));
addlabel(1, "Below" , ( if below_rng then color.red else color.gray));

input show_range_lines = no;
plot ztop = top;
ztop.SetDefaultColor(Color.gray);
ztop.SetHiding(!show_range_lines);
plot zbot = bot;
zbot.SetDefaultColor(Color.gray);
zbot.SetHiding(!show_range_lines);

plot z = within_rng;
z.SetDefaultColor(Color.cyan);

plot w = 0;
w.SetDefaultColor(Color.gray);

# count bars after being within the range
def after = if bn == 1 then 0 else if within_rng then 0 else after[1] + 1;
addlabel(1, after + " bars since being within range", color.yellow);

#

currently within range, 0 bars since
moGH0J7.jpg


out of range, for past 101 bars
Q1HnA0N.jpg



---------------------------

test study - column
zinrng_xbars
http://tos.mx/0g2CoLN

set time to day
shows x days since price was within a range, for a year

for some reason, the background colors didn't work, so i left them disabled. maybe i am overlooking something simple...
n/a's were green, others not colored.

Ruby:
# zinrng_xbars

# test , column study
# check if a stock has stayed within a price range, over a time period
# show a number of days since price stayed within the range, over the past 252 days

#declare lower;
def na = double.nan;
def bn = barnumber();

input range_percent = 20.0;

# 1 year of data , 252 days
input quantity_of_time_periods = 252;


def rnghi = highest(high, quantity_of_time_periods);
def rnglo = lowest(low, quantity_of_time_periods);


#def rng_first = (!isnan(close[-(quantity_of_time_periods-1)]) and isnan(close[-(quantity_of_time_periods-0)]));

#----------------------------------------
# save the current close price, on all bars
# https://usethinkscript.com/threads/current-price-line-indicator-for-thinkorswim.8793/
# Line At Price  Mobius
# Alternative to using the HighestAll() function

#def barsBack = 1000;
#def c = if !IsNaN(close) and IsNaN(close[-1])
#        then close
#        else c[1];
#def lastcls3 = if isNaN(close[-barsBack])
#            then c[-barsBack]
#            else Double.NaN;

#input show_close_line = no;
#plot line = if show_close_line then lastcls else na;
#line.SetLineWeight(1);
#line.SetDefaultColor(Color.LIME);
#line.SetStyle(Curve.MEDIUM_DASH);
 

# wasn't sure if alt priceline code would work in a scan, so changed it to highestall()
def lastcls2 = highestall(if isnan(close[-1]) then close else 0);

def lastcls = if isnan(lastcls2) then 0 else lastcls2;

#-----------------------------------------
# compare current close price to price highest and lowest
def range1 = round(lastcls * range_percent/100, 2);
def top = round(lastcls + (range1/2),2);
def bot = round(lastcls - (range1/2),2);

#---------------------
## for testing in a lower study
#input months_back = 12;
#input agg1 = AggregationPeriod.month;
#def rnghi = highest(high(period = agg1), months_back);
#def rnglo = lowest(low(period = agg1), months_back);

#--------------------

# show a vertical line, x days back. start of data range
#input show_vertical_line = yes;
#addverticalline(show_vertical_line and rng_first,"    RANGE START", color.yellow);

# = 1 if price was out of range
def above_rng = (rnghi > top);
def below_rng = (rnglo < bot);
# = 1 if price stayed in the range
def within_rng = (!above_rng and !below_rng);

#addlabel(1, "range : " + aspercent(range_percent/100), color.yellow);
#addlabel(1, " of " + asdollars(close), color.yellow);
#addlabel(1, "range : " + asdollars(range1), color.yellow);
#addlabel(1, "  ", color.black);
#addlabel(1, " +- range : " + asdollars(range1/2), color.yellow);

#addlabel(1, " ", color.black);
#addlabel(1, "range top " + top, color.yellow);
#addlabel(1, "range bottom " + bot, color.yellow);
#addlabel(1, "  ", color.black);

#addlabel(1, "Above" , ( if above_rng then color.red else color.gray));
#ddlabel(1, "Within range" , ( if within_rng then color.green else color.gray));
#addlabel(1, "Below" , ( if below_rng then color.red else color.gray));

#input show_range_lines = no;
#plot ztop = top;
#ztop.SetDefaultColor(Color.gray);
#ztop.SetHiding(!show_range_lines);
#plot zbot = bot;
#zbot.SetDefaultColor(Color.gray);
#zbot.SetHiding(!show_range_lines);

#plot z = within_rng;
#z.SetDefaultColor(Color.cyan);

# count bars after being within the range
def after = if bn == 1 then 0 else if within_rng then 0 else after[1] + 1;
#addlabel(1, after + " bars since being within range", color.yellow);
plot z = after;


#AssignBackgroundColor(color.magenta);

#assignbackgroundcolor( if z < 1 then color.green else if z > 60 then color.yellow else  color.magenta);

#



---------------------------

this is a modified lower study, untested

test study - scan
set time to day
finds when price has been within a range, for a year

Ruby:
# price_in_rng_past_xbars_lower_0_scan

# test , lower study-scan
# check if a stock has stayed within a price range, over a time period
# show a value of 1 if price stayed within the range, over the past x days

# set time period to day

declare lower;
def na = double.nan;
def bn = barnumber();

input range_percent = 20.0;

# 1 year of data
#input time_period = AggregationPeriod.day;
input quantity_of_time_periods = 252;

#def rnghi = highest(high(period = time_period), quantity_of_time_periods);
#def rnglo = lowest(low(period = time_period), quantity_of_time_periods);
def rnghi = highest(high, quantity_of_time_periods);
def rnglo = lowest(low, quantity_of_time_periods);

def rng_first = (!isnan(close[-(quantity_of_time_periods-1)]) and isnan(close[-(quantity_of_time_periods-0)]));

#----------------------------------------
# save the current close price, on all bars
# https://usethinkscript.com/threads/current-price-line-indicator-for-thinkorswim.8793/
# Line At Price  Mobius
# Alternative to using the HighestAll() function

#def barsBack = 1000;
#def c = if !IsNaN(close) and IsNaN(close[-1])
#        then close
#        else c[1];
#def lastcls = if isNaN(close[-barsBack])
#            then c[-barsBack]
#            else Double.NaN;
#input show_close_line = no;
#plot line = if show_close_line then lastcls else na;
#line.SetLineWeight(1);
#line.SetDefaultColor(Color.LIME);
#line.SetStyle(Curve.MEDIUM_DASH);


# wasn't sure if alt priceline code would work in a scan, so changed it to highestall()
def lastcls = highestall(if isnan(close[-1]) then close else 0);

#-----------------------------------------
# compare current close price to price highest and lowest
def range1 = round(lastcls * range_percent/100, 2);
def top = round(lastcls + (range1/2),2);
def bot = round(lastcls - (range1/2),2);

#---------------------
## for testing in a lower study
#input months_back = 12;
#input agg1 = AggregationPeriod.month;
#def rnghi = highest(high(period = agg1), months_back);
#def rnglo = lowest(low(period = agg1), months_back);

#--------------------

# show a vertical line, x days back. start of data range
#input show_vertical_line = yes;
#addverticalline(show_vertical_line and rng_first,"    RANGE START", color.yellow);

# = 1 if price was out of range
def above_rng = (rnghi > top);
def below_rng = (rnglo < bot);
# = 1 if price stayed in the range
def within_rng = (!above_rng and !below_rng);

#addlabel(1, "range : " + aspercent(range_percent/100), color.yellow);
#addlabel(1, " of " + asdollars(close), color.yellow);
#addlabel(1, "range : " + asdollars(range1), color.yellow);
#addlabel(1, "  ", color.black);
#addlabel(1, " +- range : " + asdollars(range1/2), color.yellow);

#addlabel(1, " ", color.black);
#addlabel(1, "range top " + top, color.yellow);
#addlabel(1, "range bottom " + bot, color.yellow);
#addlabel(1, "  ", color.black);

#addlabel(1, "Above" , ( if above_rng then color.red else color.gray));
#addlabel(1, "Within range" , ( if within_rng then color.green else color.gray));
#addlabel(1, "Below" , ( if below_rng then color.red else color.gray));

#input show_range_lines = no;
#plot ztop = top;
#ztop.SetDefaultColor(Color.gray);
#ztop.SetHiding(!show_range_lines);
#plot zbot = bot;
#zbot.SetDefaultColor(Color.gray);
#zbot.SetHiding(!show_range_lines);

plot z = within_rng;
#z.SetDefaultColor(Color.cyan);

# count bars after being within the range
#def after = if bn == 1 then 0 else if within_rng then 0 else after[1] + 1;
#addlabel(1, after + " bars since being within range", color.yellow);
#
 
Solution

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