Time Based Volume Indicator for ThinkorSwim

BenTen

Administrative
Staff member
Staff
VIP
Lifetime
Volume is the second most important trading indicator, according to CustomizedTrading. Here is a quick snippet of their introductory to the indicator.

Time Based Volume completely eliminates the high volume distortion that occurs after the open of a market, just before the close of a market, and the low volume that occurs at market lunch times. Since the Time Based Volume Indicator is time based it will work on any intraday time based chart and symbol (including Forex).

Robert from Researchtrade was able to convert the Time Based Volume indicator over to ThinkorSwim. Here is the full script.

Notes:
  • Cyan = Bullish
  • Darker blue = Bullish smaller
  • Magenta = Bearish
  • Darker purple = Bearish smaller

ekndLKf.png


thinkScript Code

Rich (BB code):
# Time Based Volume
# Robert Payne
declare lower;
input LookBack = 20;
def nMinutes = GetAggregationPeriod() / 60000;
def nBars = RoundUp(390 / nMinutes, 0);

def pvSum = fold idx = 1 to LookBack + 1 with a=0 do a + GetValue(volume, idx * nBars, LookBack * nBars);

def pvAvg = pvSum / LookBack;
def VolPct = (volume / pvAvg) * 100;

plot avgLine = 100;
avgLine.SetDefaultColor(Color.GRAY);
avgLine.SetStyle(Curve.LONG_DASH);

def lastUp = if IsNaN(lastUp[1]) then 0 else if (close > open) then VolPct else lastUp[1];
def lastDn = if IsNaN(lastDn[1]) then 0 else if (close < open) then VolPct else lastDn[1];

plot Vol = VolPct;
Vol.SetPaintingStrategy(PaintingStrategy.HISTOGRAM);
Vol.DefineColor("Bullish", Color.CYAN);
Vol.DefineColor("Bullish Smaller", CreateColor(0, 128, 128));
Vol.DefineColor("Bearish", Color.MAGENTA);
Vol.DefineColor("Bearish Smaller", CreateColor(128, 0, 128));
Vol.AssignValueColor(if (close > open) and (VolPct > lastUp[1]) then Vol.Color("bullish" ) else if close > open then Vol.Color("bullish smaller" ) else if close < open and VolPct > lastDn[1] then Vol.Color("bearish" ) else Vol.Color("bearish smaller" ));
Vol.SetLineWeight(3);

Shareable Link

https://tos.mx/nxOBq1
 

Attachments

  • ekndLKf.png
    ekndLKf.png
    107.8 KB · Views: 209
Last edited:
Thanks, BenTen :) Given the importance of the relationship between Price and Volume, here is time based Volume and Price linked together by color:

AMif78D.png


Rich (BB code):
# source: Time Based Volume
# original author: Robert Payne

declare lower;

input LookBack = 20;
def nMinutes = GetAggregationPeriod() / 60000;
def nBars = RoundUp(390 / nMinutes, 0);

def pvSum = fold idx = 1 to LookBack + 1 with a=0 do a + GetValue(volume, idx * nBars, LookBack * nBars);

def pvAvg = pvSum / LookBack;
def VolPct = (volume / pvAvg) * 100;

plot avgLine = 100;
avgLine.SetDefaultColor(Color.GRAY);
avgLine.SetStyle(Curve.LONG_DASH);

def lastUp = if IsNaN(lastUp[1]) then 0 else if (close > open) then VolPct else lastUp[1];
def lastDn = if IsNaN(lastDn[1]) then 0 else if (close < open) then VolPct else lastDn[1];

plot Vol = VolPct;
Vol.SetPaintingStrategy(PaintingStrategy.HISTOGRAM);
Vol.SetLineWeight(3);
Vol.DefineColor("Bullish", Color.GREEN);
Vol.DefineColor("Bullish Smaller", Color.DARK_GREEN);
Vol.DefineColor("Bearish", Color.RED);
Vol.DefineColor("Bearish Smaller", Color.DARK_RED);
Vol.AssignValueColor(if (close > open) and (VolPct > lastUp[1]) then Vol.Color("bullish" ) else if close > open then Vol.Color("bullish smaller" ) else if close < open and VolPct > lastDn[1] then Vol.Color("bearish" ) else Vol.Color("bearish smaller" ));
AssignPriceColor(if (close > open) and (VolPct > lastUp[1]) then Vol.Color("bullish" ) else if close > open then Vol.Color("bullish smaller" ) else if close < open and VolPct > lastDn[1] then Vol.Color("bearish" ) else Vol.Color("bearish smaller" ));
Hope this helps!

Good Luck and Good Trading :)

 

Attachments

  • AMif78D.png
    AMif78D.png
    102 KB · Views: 178
Last edited:
Ben/Netarchitech, Can you confirm this will work 1day 1mintues? I see only on 5mts time frame.

 
Last edited:
@San I just checked again and it doesn't work for me on the 1m timeframe either. Sorry about that.

 
Last edited:
Hi all. I am looking for assistance for code that scans the first hour of the day for the past twenty days and compares it to the first hour of today's volume.

Example: 9:30-10:30 volume for today, 9:30-10:30 volume for last Friday, etc. etc. for the past twenty (or specified) days. This way you can plot to see what % of volume today is returning compared to other opening days. Not just the last twenty hours.

Thank you.

This plot only compares the last twenty hours. It does not compare the first hour of the day for the past twenty days. Any help?

Use FB as an example on the 20D 1H plot. If you go into Excel and plot the volume from 9:30 to 10:30 for the past twenty days and average them out, you'll get an average of 4,537,000 (rounded). If this code is true, then today's volume from 9:30-10:30 would have been 140% (this morning we saw approximately 6,368,000 shares traded). BUT, this plot gives us a value of 333%...odd. So, I recorded hourly volume for the past 20 hours and took an average, which was 1,912,794. Today's morning volume? 3.33x that number. So, that proves that this is not taking the first hour of each day, but the last 20 hours. Read through the code and you can confirm this with the fold idx loop. Any help would be appreciated @BenTen


@horserider any ideas here?
 
Last edited by a moderator:
This plot only compares the last twenty hours. It does not compare the first hour of the day for the past twenty days. Any help?

EDIT - sorry for not including code in original. i added it after the image


short answer, try turning off extended hours.

long answer
I think robert's study is working as intended. In my modified version of it, values are displayed that match up to values of previous bars.

Most stocks will have a different quantity of bars (trades) in after hours, from one day to the next. Because of this you can't count x bars back and get to the same time of day. Roberts volume study looks back x number of bars, it doesn't check for time of day. It is looking back multiples of 390, to find previous days data. It uses the chart time to determine how many bars exist during a day on the chart. A trading day has 390 min, 6.5 hrs.

I modified robert's study, so it will show values in bubbles, that can be compared. I changed the length from 20 to 3. That should be enough values to see what is going on. In the bubbles are several variables. It reads the volume from 3 bars in the past. I divided all the numbers by
1000, to reduce the quantity of digits displayed. The values should be unique enough to verify the data. A day has 6.5 hours. so if a chart is set to 1 hour, nbars will be 7 , 6.5 rounded up. Every 7th bar, the bubbles are yellow, to make it easier to find and compare the values.

the variables are, starting from the top,
volume0 , current bar volume
volume1 , a bar that is [1 * nbars] ago , using getvalue
volume2 , a bar that is [2 * nbars] ago , using getvalue
volume3 , a bar that is [3 * nbars] ago , using getvalue
sum of 3 volumes shown above
pvsum variable
pvavg variable
volpct

VolumeTimeBasedcompare_01
http://tos.mx/6iFLCn7

pic from 3/19/2021
VK5TxLI.jpg



Code:
# VolumeTimeBasedcompare_01

# ------------------------------------------------------
# 21-03-21
# modified by halcyonguy
# to verify data
# replace histogram with bubbles, showing variable values
# ------------------------------------------------------

# https://usethinkscript.com/threads/time-based-volume-indicator-for-thinkorswim.124/

#Volume is the second most important trading indicator, according to CustomizedTrading.
# Here is a quick snippet of their introductory to the indicator.

#Time Based Volume completely eliminates the high volume distortion that occurs after the open of a
#market, just before the close of a market, and the low volume that occurs at market lunch times. Since
#the Time Based Volume Indicator is time based it will work on any intraday time based chart and symbol
#(including Forex).

#Robert from Researchtrade was able to convert the Time Based Volume indicator over to ThinkorSwim.
# Here is the full script.


#Notes:
#Cyan = Bullish
#Darker blue = Bullish smaller
#Magenta = Bearish
#Darker purple = Bearish smaller

# ------------------------------
# Time Based Volume
# Robert Payne
# ------------------------------

declare lower;

input show_bubbles = yes;

#input LookBack = 20;
input LookBack = 3;
def nMinutes = GetAggregationPeriod() / 60000;
def nBars = RoundUp(390 / nMinutes, 0);

def bn = barnumber();
def nmulti = (floor(bn/nbars) == (bn/nbars));

addlabel(yes,"voltime" + "chart min:" + nminutes + " day bars " + nbars, color.yellow);

def pvSum = fold idx = 1 to LookBack + 1 with a=0 do a + GetValue(volume, idx * nBars, LookBack *
nBars);

def pvAvg = pvSum / LookBack;
def VolPct = (volume / pvAvg) * 100;

plot avgLine = 100;
avgLine.SetDefaultColor(Color.GRAY);
avgLine.SetStyle(Curve.LONG_DASH);

def lastUp = if IsNaN(lastUp[1]) then 0 else if (close > open) then VolPct else lastUp[1];
def lastDn = if IsNaN(lastDn[1]) then 0 else if (close < open) then VolPct else lastDn[1];

# disable the histogram
#plot Vol = VolPct;
input show_histogram = no;
plot Vol = if show_histogram then VolPct else double.nan;
Vol.SetPaintingStrategy(PaintingStrategy.HISTOGRAM);
Vol.DefineColor("Bullish", Color.CYAN);
Vol.DefineColor("Bullish Smaller", CreateColor(0, 128, 128));
Vol.DefineColor("Bearish", Color.MAGENTA);
Vol.DefineColor("Bearish Smaller", CreateColor(128, 0, 128));
Vol.AssignValueColor(if (close > open) and (VolPct > lastUp[1]) then Vol.Color("bullish" )
 else if close
> open then Vol.Color("bullish smaller" )
 else if close < open and VolPct > lastDn[1] then Vol.Color
("bearish" )
 else Vol.Color("bearish smaller" ));
Vol.SetLineWeight(3);



plot w = 0;

# get prev 3 volumes
def vol1 = GetValue(volume, 1 * nBars, LookBack * nBars);
def vol2 = GetValue(volume, 2 * nBars, LookBack * nBars);
def vol3 = GetValue(volume, 3 * nBars, LookBack * nBars);

# change values to be in units of thousands (fewer digits to display)
def vol1k = round(vol1/1000,0);
def vol2k = round(vol2/1000,0);
def vol3k = round(vol3/1000,0);

def volk = round(volume/1000,0);
def pvsumk = round(pvsum/1000,0);
def pvavgk = round(pvavg/1000,0);
def volpctz = round(volpct,0);

addchartbubble(show_bubbles and !isnan(volume), 0,
 "v0 " + volk + "k" + "\n" +
 "v1 " + vol1k + "k" + "\n" +
 "v2 " + vol2k + "k" + "\n" +
 "v3 " + vol3k + "k" + "\n" +
 "sm " + (vol1k + vol2k + vol3k) + "k" + "\n" +
 "s " + pvsumk + "k" + "\n" +
 "av " + pvavgk + "k" + "\n" + 
 "% " + volpctz, 
if nmulti then color.yellow else color.cyan,yes);

#
 
Last edited:
Say the current time is 9am, I want to find all stocks whose volume upto 9am today is n times the average volume up to 9am of m previous days.

I tried to look at the script of AverageVol. The function Average() just takes the whole period average. I don't see how to adapt it to just take acount into the volume upto now for each previous days.

Code:
declare lower;
declare zerobase;

input length = 50;

plot Vol = volume;
plot VolAvg = Average(volume, length);

Vol.SetPaintingStrategy(PaintingStrategy.HISTOGRAM);
Vol.SetLineWeight(3);
Vol.DefineColor("Up", Color.UPTICK);
Vol.DefineColor("Down", Color.DOWNTICK);
Vol.AssignValueColor(if close > close[1] then Vol.color("Up") else if close < close[1] then Vol.color("Down") else GetColor(1));
VolAvg.SetDefaultColor(GetColor(8));
 
Say the current time is 9am, I want to find all stocks whose volume upto 9am today is n times the average volume up to 9am of m previous days.

I tried to look at the script of AverageVol. The function Average() just takes the whole period average. I don't see how to adapt it to just take acount into the volume upto now for each previous days.

Code:
declare lower;
declare zerobase;

input length = 50;

plot Vol = volume;
plot VolAvg = Average(volume, length);

Vol.SetPaintingStrategy(PaintingStrategy.HISTOGRAM);
Vol.SetLineWeight(3);
Vol.DefineColor("Up", Color.UPTICK);
Vol.DefineColor("Down", Color.DOWNTICK);
Vol.AssignValueColor(if close > close[1] then Vol.color("Up") else if close < close[1] then Vol.color("Down") else GetColor(1));
VolAvg.SetDefaultColor(GetColor(8));

i'm not sure, but i think the code to do this, may be too complex to run in a scan.
the code from the link below could be altered to work on chart. maybe on a short watchlist?

https://usethinkscript.com/threads/time-based-volume-indicator-for-thinkorswim.124/
Time Based Volume Indicator for ThinkorSwim
BenTen
Apr 25, 2019
 
Could anyone help me to modify this study to work as a watchlist column? I can do fine tuning and color tweaks and such once it's in the format, but I am not clear on how to make the critical changes to def's and plots. Thank you!
 
Here you go
Could anyone help me to modify this study to work as a watchlist column? I can do fine tuning and color tweaks and such once it's in the format, but I am not clear on how to make the critical changes to def's and plots. Thank you!
Code:
# Time Based Volume
# Robert Payne
# Watchllist add_on Whenimgone (knowledge is free)
declare lower;
input LookBack = 20;
def nMinutes = GetAggregationPeriod() / 60000;
def nBars = RoundUp(390 / nMinutes, 0);

def pvSum = fold idx = 1 to LookBack + 1 with a=0 do a + GetValue(volume, idx * nBars, LookBack * nBars);

def pvAvg = pvSum / LookBack;
def VolPct = (volume / pvAvg) * 100;

def lastUp = if IsNaN(lastUp[1]) then 0 else if (close > open) then VolPct else lastUp[1];
def lastDn = if IsNaN(lastDn[1]) then 0 else if (close < open) then VolPct else lastDn[1];

#NOTE: I have removed the exact volume number, it's hidden. If you want to have it instead of it being hidden, just substitute the addLabel code with this addlabel(yes, vol, color.black); You still need the assignbackgroundColor line to have the background change.

def Vol = VolPct;
addlabel(yes, vol, if (close > open) and (VolPct > lastUp[1]) then Color.CYAN else if close > open then CreateColor(0, 128, 128) else if close < open and VolPct > lastDn[1] then color.magenta else color.plum);
assignbackgroundColor(if (close > open) and (VolPct > lastUp[1]) then Color.CYAN else if close > open then CreateColor(0, 128, 128) else if close < open and VolPct > lastDn[1] then color.magenta else color.plum);

Another option for the addLabel is this:
addlabel(yes, roundup(vol,0), color.black);

Basically this will give you the whole number, rounded up. Check the screenshot.

SCREEN.jpg
 
Last edited:
Just adding a screenshot of how the original code from the original post #1 of this thread. Here is what Robert said incase the website gets deleted. this is just for archiving, since this appears to be a overlooked indicator due to some confusion on how it was intended to work.

1689916911219.png
 
Unless I'm reading this indicator wrong this doesn't seem to work correctly. The bars at the opening and close are always higher than the bars in the middle of the day. If it was truly comparing each bar to the previous n days exact time of day bar average then shouldn't only the bars that are higher than the average be up?
 
Does anyone know how to get this to work on /ES time frames lower than 15min? I changed line:

def nbars = RoundUp(390/ nMinutes, 0);

to

def nbars = RoundUp(1380 / nMinutes, 0);

and that works for time frames 15min and higher but lower time frames 10min and 2min did not work. I was messing around with the highest number that would still show a value on the 10min and it was (990 / nMinutes); so it seems that the fold function has a limit of 99 instances. Is there a workaround or is this a limiting factor? Thanks!
 
Last edited:
Does anyone know how to get this to work on /ES time frames lower than 15min? I changed line:

def nbars = RoundUp(390/ nMinutes, 0);

to

def nbars = RoundUp(1380 / nMinutes, 0);

and that works for time frames 15min and higher but lower time frames 10min and 2min did not work. I was messing around with the highest number that would still show a value on the 10min and it was (990 / nMinutes); so it seems that the fold function has a limit of 99 instances. Is there a workaround or is this a limiting factor? Thanks!
Have you found the answer to this? There has to be because I've seen people with ToS Relative Time of Day Volume displaying on 1 minute charts. So either we're close with this code or there's an entirely different way of finding the solution (other than counting back bars)
 
Volume is the second most important trading indicator, according to CustomizedTrading. Here is a quick snippet of their introductory to the indicator.



Robert from Researchtrade was able to convert the Time Based Volume indicator over to ThinkorSwim. Here is the full script.

Notes:
  • Cyan = Bullish
  • Darker blue = Bullish smaller
  • Magenta = Bearish
  • Darker purple = Bearish smaller

View attachment 4416

thinkScript Code

Rich (BB code):
# Time Based Volume
# Robert Payne
declare lower;
input LookBack = 20;
def nMinutes = GetAggregationPeriod() / 60000;
def nBars = RoundUp(390 / nMinutes, 0);

def pvSum = fold idx = 1 to LookBack + 1 with a=0 do a + GetValue(volume, idx * nBars, LookBack * nBars);

def pvAvg = pvSum / LookBack;
def VolPct = (volume / pvAvg) * 100;

plot avgLine = 100;
avgLine.SetDefaultColor(Color.GRAY);
avgLine.SetStyle(Curve.LONG_DASH);

def lastUp = if IsNaN(lastUp[1]) then 0 else if (close > open) then VolPct else lastUp[1];
def lastDn = if IsNaN(lastDn[1]) then 0 else if (close < open) then VolPct else lastDn[1];

plot Vol = VolPct;
Vol.SetPaintingStrategy(PaintingStrategy.HISTOGRAM);
Vol.DefineColor("Bullish", Color.CYAN);
Vol.DefineColor("Bullish Smaller", CreateColor(0, 128, 128));
Vol.DefineColor("Bearish", Color.MAGENTA);
Vol.DefineColor("Bearish Smaller", CreateColor(128, 0, 128));
Vol.AssignValueColor(if (close > open) and (VolPct > lastUp[1]) then Vol.Color("bullish" ) else if close > open then Vol.Color("bullish smaller" ) else if close < open and VolPct > lastDn[1] then Vol.Color("bearish" ) else Vol.Color("bearish smaller" ));
Vol.SetLineWeight(3);

Shareable Link

https://tos.mx/nxOBq1
Hello @BenTen , I just now saw your post...
All evening I was following up on a request for a time based relative volume for intraday as the Daily Relative Volume that is often used at a 60 period length would be useless to observe Volumes for Opening and Closing trends.

I used some Mobius Techniques to solve Relative Volume differently, My script used way more lines of code but on the bright side by finding Relative Volume by cutting Times into slots seems to allow some other functionalities.

Where would you like me to post this?
If you have time would you and @MerryDay please share any thoughts or criticisms before I share this with others.

Thank you so much for all the order you bring to the community.
Have a Happy NewYear if I don't see you for awhile.
 
http://tos.mx/WKzMuag

Relative Volume Calculation to compare the Volume of Order flow to other days at the exact same time of days. Corrected for all time frames including days including days with unequal trading hours.

The next task will probably be to automate some of the Volume Analysis to be more compact to the human eyes.
As always I'm grateful for all criticisms and suggestions.

Happy Holidays.

@MerryDay @BenTen @shakib3585 @lmk99
 

Attachments

  • RelativeVolume Advantages.png
    RelativeVolume Advantages.png
    311.8 KB · Views: 130

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