Average Daily Range Indicator for ThinkorSwim

BenTen

Administrative
Staff member
Staff
VIP
Lifetime
This indicator displays the Average Daily Range for the last 5 days. Could potentially be useful for finding hidden support and resistance levels on intraday chart.

0rE6hN5.png


Notes:
  • The blue line = high of average daily range
  • The pink line = low of average daily range

thinkScript Code

Rich (BB code):
#Hint: Average Daily Range

def len = 2;

def dayHigh = DailyHighLow(AggregationPeriod.DAY, len, 0, no).dailyhigh;
def dayLow = DailyHighLow(AggregationPeriod.DAY, len, 0, no).DailyLow;

def ADR_high = (dayHigh + dayHigh[1] + dayHigh[2] + dayHigh[3] + dayHigh[4]) / 5;
def ADR_low = (dayLow + dayLow[1] + dayLow[2] + dayLow[3] + dayLow[4]) / 5;

plot ADR_H = ADR_high;
plot ADR_L = ADR_low;

Shareable Link

https://tos.mx/1yaAuM

Credit:
 

Attachments

  • 0rE6hN5.png
    0rE6hN5.png
    168.2 KB · Views: 417
Last edited:
@BenTen one of those IV scripts from last week also plots like the indicator you have above.

 
Last edited:
That's pretty useful. What would I use to plot a percentage of that? Say I want to plot 70% of the range?
 
Hello,

I'm trying to build a screener that would find stocks that are at 100% or more of their Average True Range (ATR) on the day but I don't think it's possible with the default screener options on TOS. Does anyone know how to code something like that? Thank you so much!
 
Here's another angle:

@jdstrader Here's how you can see any percentage you desire in a scan.

Code:
# Code for Average Range Scan - User selects Percentage of Range covered by changing the ScanRange

# The number of days you'd like average
input RangePeriod = 5;

# ScanRange = .25 (25%) .50 (50%) .75 (75%) 1 (100%)
input ScanRange = 1;

def DayRange = high-low;
def AvgRange = average(DayRange,RangePeriod);

# How to address seeing what % of daily range has been achieved
def TodayAgainstAvgRange = (high-low)/AvgRange;

Add This line for a scan:

Code:
plot scanyes = TodayAgainstAvgRange is greater than ScanRange;

Add This line for a custom watchlist column:

Code:
AddLabel(yes,"AVR: "+todayagainstavgrange*100+"%",color.yellow);

Different colors can be used for different amounts of range also if desired.
 
Last edited:
@K_O_Trader

I scratched that out while mobile. Try making rangeperiod rangelength instead. Rangeperiod in the avgrange statement will need to change as well.

Still mobile...tag me here if that doesn't solve it. My guess is "period" being a constant is why the error is happening.
 
@K_O_Trader

I scratched that out while mobile. Try making rangeperiod rangelength instead. Rangeperiod in the avgrange statement will need to change as well.

Still mobile...tag me here if that doesn't solve it. My guess is "period" being a constant is why the error is happening.
Its solved the problem when it came to any red highlights, but i still cant press OK and implement the scan into my system
 
@K_O_Trader

Did you add the "plot scanyes" line into your scan code?

Code:
plot scanyes = TodayAgainstAvgRange is greater than ScanRange;

That's likely why you weren't able to click OK - no plot....

Apologies for that duplication of the rangeperiod variable...That's why you got the error you did initially.

I wrote the "core" of the code in the original reply then added two possibilities:

One for a scan, and the other for a watchlist custom column if you desire.
 
Thanks for the script @autolox I added it to my watchlist. I have another indicator on my chart that shows me the DTR vs ATR of the stock I'm watching on a little bubble. For some reason the percentage doesn't match with the one shown on the watchlist using your script. I'm attaching a screenshot so you see what I mean.

Annotation-2020-05-04-203052.jpg


Here's the code of the indicator I'm using.

Code:
# Custom ATR Plot by 7of9 for BRT
# edited 3/20/19

declare upper;

input AtrAvgLength = 14;

def ATR = WildersAverage(TrueRange(high(period = aggregationPeriod.DAY), close(period = aggregationPeriod.DAY), low(period = aggregationPeriod.DAY)), AtrAvgLength);

def TodayHigh = Highest(high(period = aggregationPeriod.DAY), 1);
def TodayLow = Lowest(low(period = aggregationPeriod.DAY), 1);

def DTR = TodayHigh - TodayLow;

def DTRpct = Round((DTR / ATR) * 100, 0);

AddLabel (yes, "DTR " + Round (DTR , 2) + " vs ATR " + round (ATR,2)+ "  " + round (DTRpct,0) + "%", (if DTRpct <= 70 then Color.GREEN else if DTRpct >= 90 then Color.RED else Color.ORANGE));

I can't figure out why I'm getting different values of the DTR. Thanks again for your help.
 
@jdstrader

Assuming you loaded the script I shared with no adjustments, that script was written for 5 periods.

It looks like your code is written for 14.

The other part that is probably causing some variant is the use of "WildersAverage()" in your code. (I have zero proficiency with WildersAverage...)

In lieu of trying to squeeze answers out of this WildersAverage turnip, Here's some information on the function itself directly from TD and "The Learning Center":

Think Or Swim Learning Center - WildersAverage() function

It looks like your code is also averaging together the HIGH, LOW, and CLOSE while I'm simply applying the difference between high and low.

(Just thinking out loud - what does CLOSE have to do with TRUE RANGE? - I'm really not trying to be as snarky as that question may read, I'm just honestly curious....)
 
Yes, sorry I forgot to mention that I did change your code to 14 periods so it must be the WildersAverage part that is giving different percentages. I'll look into it further. Thanks for your help.
 
Does anyone have a TOS Display with this information - See Link. The attached image if coded for Ninja Trader which I do not like nor trust as it locks up in fast markets all the time friends tell me. This Display Tracks in lower Left Corner the Average Daily Volume ( see black square in lower left corner ) and Automatically Plots the Over Night High and Low of each time zone as the global markets trade. Asian Range, London Range, as well as Previous Days Session. https://www.nobstools.com/big-picture/market-maker-floor-levels
 
The idea of it is Track day by day consecutively so at a glance one can see specifically - instantly by the number of ticks current day is less than or greater than the tracking history. Very helpful information on several levels.
 
Does anyone have a TOS Display with this information - See Link. The attached image if coded for Ninja Trader which I do not like nor trust as it locks up in fast markets all the time friends tell me. This Display Tracks in lower Left Corner the Average Daily Volume ( see black square in lower left corner ) and Automatically Plots the Over Night High and Low of each time zone as the global markets trade. Asian Range, London Range, as well as Previous Days Session. https://www.nobstools.com/big-picture/market-maker-floor-levels

i know we're supposed to post code, but i don't have access to my tos computer now. i searched my notes and found this.
maybe it can be used as a starting point for what txsroper wants.

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

last year, i made this for someone who wanted to highlight the session times of a couple of markets ( us, eu, asian,...)
...
hilolines_05
http://tos.mx/M3vXysB

draw shading, bounded by start/stop times and highest/lowest levels
enter start and end times, (24 hour EST), for a period < 24 hours.
The time period can span over Midnight.
can choose to show/not show several parameters , labels, lines, shading

shading color is used on chart and on labels
shading color is created by entering RGB color numbers, 0-255 , for red,green,blue
can load this study multiple times and pick different colors and start/end times

pick choice for session - US, EU, Asian, none
if current bar is during a time period, it can't draw horizontal lines or shading
but it does show labels with high and low values and bar count

notes
https://www.w3schools.com/colors/colors_picker.asp
pick /es for testing. it trades most of the day
SecondsTillTime(2400) is illegal value
SecondsTillTime(0000) is ok
 
here is the code for the previous post, about market sessions.
i updated it to be able to pick 1 of 3 preset markets, US, UK, HK

can pick ' choose ' , if you want to enter custom times
input market = { default "U.S." , "EU" , "H.K." , "choose"};


https://www.thebalance.com/stock-market-hours-4773216

Ruby:
# hilolines_08

# market session time period , high/low levels
#  test with  /es , it has bars 23 hours a day

# add default times for 3 markets.
#  https://www.thebalance.com/stock-market-hours-4773216
#   US   9:30am to  4:00pm EST
#   UK   3:00am to 11:30am EST
#   H.K. 9:30pm to  4:00am EST
#
# if choose is picked for a market, can enter your own start and stop times.
# can pick a RGB color for time period shading.
#  same color used for label stats
# load study multiple times, and pick different times and colors


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

# skip 6,7 , experimental code that didn't work out

# hilolines_05
# 2020-07-17
# halcyonguy
# draw shading, bounded by start/stop times and highest/lowest levels
#  enter start and end times, (24 hour EST), for a period < 24 hours
#  can choose to show several parameters , labels, lines, shading
#   pick  /es  for testing.  trades most of day


declare hide_on_daily;
#input market = { default "U.S." , "EU" , "H.K." , "-"};
input market = { default "U.S." , "EU" , "H.K." , "choose"};


def startx;
def stopx;
switch (market) {
  case "U.S.":
#  US   9:30am to  4:00pm EST
    startx = 0930;
    stopx = 1600;
  case "EU":
#  UK   3:00am to 11:30am EST
    startx = 0300;
    stopx = 1130;
  case "H.K.":
#  H.K. 9:30pm to  4:00am EST
    startx = 2130;
    stopx = 0400;
  case "choose":
    startx = 0;
    stopx = 0;
}

# manual pick time period
input custom_start1_est = 0930;
input custom_end1_est = 1600;

def start1;
def end1;
if startx == 0 then {
  start1 = custom_start1_EST;
  end1 = custom_end1_est;
 } else {
  start1 = startx;
  end1 = stopx;
}


input show_start_end_vertical_lines = yes;
def ssevl = show_start_end_vertical_lines;
input show_midnight_vertical_line = yes;
def smvl = show_midnight_vertical_line;
input show_current_period_labels = yes;
def scpl = show_current_period_labels;

def na = Double.NaN;
def hi = high;
def lo = low;
def bn = BarNumber();

# color alts  gray 90,90,90    tan 70,70,70    grn 70,110,20
input show_shading = yes;
#input color_numbers_0to255 = yes;
#shading color is created by entering RGB color numbers, 0-255 , for red,green,blue
input shade_color_red_num0to255 = 70;
def cred = shade_color_red_num0to255;
input shade_color_green_num0to255 = 110;
def cgrn = shade_color_green_num0to255;
input shade_color_blue_num0to255 = 20;
def cblu = shade_color_blue_num0to255;

# show test data in labels and bubbles
input showtest = no;
def lastbar = !isnan(close[0]) and isnan(close[-1]);

# define the shading color
DefineGlobalColor( "shade1" , CreateColor(cred, cgrn, cblu));
addlabel(yes, market, GlobalColor( "shade1" ));

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

#  calc total minutes , from midnight , to each time
def start1hr = Floor(start1 / 100);
def start1min = start1 - (start1hr * 100);
def start1minttl = (start1hr * 60) + start1min;
AddLabel(showtest, start1 + ".." + "st hrs=" + start1hr + ".." + start1min + ".." + start1minttl, Color.CYAN);

def end1hr = Floor(end1 / 100);
def end1min = end1 - (end1hr * 100);
def end1minttl = (end1hr * 60) + end1min;
AddLabel(showtest, end1 + ".." + "end hrs=" + end1hr + ".." + end1min + ".." + end1minttl, Color.RED);

# ===========================>>>>>>>>>>>>>>>>>>>>

#  elapsed min in current period
def stmin2 = SecondsFromTime(start1);
def stmin = stmin2 / (60);
AddLabel(showtest, "period min=" + stmin , Color.GREEN);

# ===========================>>>>>>>>>>>>>>>>>>>

#  is bar in a time period? , minutes in a day , 24 x 60 = 1440
def daymin = 1440;
def endz = 2359;
def startz = 0000;
def  first1 = if SecondsTillTime(start1) == 0 then 1 else 0;
def  last1 = if SecondsFromTime(end1) == 0 then 1 else 0;

def period1min;
def period1;
if start1minttl > end1minttl
then {
   # spans midnight , period=(24-start)+end , end to start
    period1min = (daymin - start1minttl) + end1minttl;
    period1 = if ((SecondsFromTime(start1) >= 0 and SecondsTillTime(endz) > 0) or ( SecondsFromTime(startz) >= 0 and SecondsTillTime(end1) > 0)) then 1 else 0;
} else {
   # ok , period=end-start , start to end
    period1min = (end1minttl - start1minttl);
    period1 = if SecondsFromTime(start1) >= 0 and SecondsTillTime(end1) > 0 then 1 else 0;
}

# ====================================

AddVerticalLine(ssevl and first1, "Start " + start1 , Color.GREEN, Curve.MEDIUM_DASH);
AddVerticalLine(ssevl and last1, "End " + end1 , Color.ORANGE, Curve.MEDIUM_DASH);

#  display time as hr:min ,  but trailing 0 not shown
#AddVerticalLine(ssevl and first1, "start " + start1hr + ":" + start1min , Color.GREEN, Curve.MEDIUM_DASH);
#AddVerticalLine(ssevl and last1, "end " + end1hr + ":" + end1min , Color.ORANGE, Curve.MEDIUM_DASH);
AddChartBubble(showtest, low - 1, period1, if period1 then Color.GREEN else Color.CYAN, no);

# midnight
def midn = 0000;
def midnite = if (smvl and SecondsTillTime(midn) == 0) then 1 else 0;
AddVerticalLine(midnite, "midnight" , Color.BLUE, Curve.MEDIUM_DASH);
AddLabel(showtest, "daymin=" + daymin + "  end1minttl=" + end1minttl + "  start1minttl=" + start1minttl, Color.GREEN);

AddLabel(showtest, "period1 min=" + period1min, Color.YELLOW);
AddLabel(scpl and period1, "hrs: " + round((period1min/60),1), GlobalColor("shade1"));

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

# get chart agg minutes
def chagg = GetAggregationPeriod();
def aggmin = chagg / (1000 * 60);
AddLabel(showtest, "agg=" + aggmin, Color.CYAN);

# calc qty of bars of period1, for the current chart time
def period1bars = period1min / aggmin;
AddLabel(showtest, "period1 bars=" + period1bars, Color.YELLOW);

# ex. trade session = 6.5 hrs = 390 min
# 5 min chart = 390/5 = 78 bars  over 6.5 hours
# def len = 78;

# =====================<<<<<<<<<<<<<<<<<<<<<<

#  add check if in period and if last bar
def currentperiodbars = if (period1 and lastbar) then (stmin / aggmin) else 0;
AddLabel(showtest, "current period bars=" + currentperiodbars, Color.magenta);
AddLabel(scpl and period1, "bars " + currentperiodbars + "/" + period1bars, GlobalColor("shade1"));


#  find the high of active period, only on last bar
def xhi = fold xi = 0 to currentperiodbars
    with n = hi
    do Max(n, GetValue(hi, xi));

AddLabel(scpl and period1, "highest: " + xhi , GlobalColor("shade1"));

#  find the low of active period, only on last bar
def xlo = fold xj = 0 to currentperiodbars
    with m = lo
    do Min(m, GetValue(lo, xj));

AddLabel(scpl and period1, "lowest: " + xlo , GlobalColor("shade1"));

def len = period1bars - 1;

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

# find high value for previous/complete time period, draw a line
def hi2 = if first1 then Highest(hi[-len], len + 1)
   else if last1 then na
   else if period1 then hi2[1]
   else na;

plot hiline = hi2;
hiline.SetDefaultColor(Color.WHITE);
#hiline.SetStyle(Curve.MEDIUM_DASH);
hiline.SetLineWeight(1);
hiline.HideBubble();

# ------------------------------------------------
# find low value for previous/complete time period, draw a line

def lo2 = if first1 then Lowest(lo[-len], len + 1)
   else if last1 then na
   else if period1 then lo2[1]
   else na;

plot loline = lo2;
loline.SetDefaultColor(Color.WHITE);
#loline.SetStyle(Curve.MEDIUM_DASH);
loline.SetLineWeight(1);
loline.HideBubble();

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

# shading
def hiline2 = if show_shading then hiline else na;
def loline2 = if show_shading then loline else na;

#addcloud(hiline,loline,color.light_gray,color.light_gray);
AddCloud(hiline2, loline2, GlobalColor( "shade1" ), GlobalColor( "shade1" ) );
#

OG1yI4z.jpg

hal_ses
 
Last edited:
The screen shot above looks great. I copied and saved the code like normal. Nothing paints on the chart ? Not sure what I did wrong. Seems simple.
 
The screen shot above looks great. I copied and saved the code like normal. Nothing paints on the chart ? Not sure what I did wrong. Seems simple.
have to pick a symbol that has data during the time period. try /ES , or a symbol from a foreign market.
 

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