Further modify relative volume indicator to segment the volume bars with horizontal lines that show the size of the trades in T&S

Glefdar

Active member
I already modified the built-in relative volume indicator to be color-coded in a way that reflects buy vs sell relative volume intuitively:

Code:
# TD Ameritrade IP Company, Inc. (c) 2014-2021
#

declare lower;
declare zerobase;

input length = 60;
input numDev = 2.0;
input allowNegativeValues = yes;

def rawRelVol = (volume - Average(volume, length)) / StDev(volume, length);
plot RelVol = if allowNegativeValues then rawRelVol else Max(0, rawRelVol);
plot StDevLevel = numDev;

RelVol.SetPaintingStrategy(PaintingStrategy.HISTOGRAM);
RelVol.SetLineWeight(3);
RelVol.DefineColor("UpCandleAbove", Color.Light_Green);
RelVol.DefineColor("DownCandleAbove", Color.Red);
RelVol.DefineColor("UpCandleBelow", Color.CYAN);
RelVol.DefineColor("DownCandleBelow", Color.DARK_ORANGE);
RelVol.DefineColor("DownCandleNegBelow", CreateColor(60,25,25));
RelVol.DefineColor("UpCandleNegBelow", CreateColor(25,60,25));
RelVol.AssignValueColor(if RelVol >= numDev and RelVol>0 and open<close then RelVol.Color("UpCandleAbove") else if RelVol < numDev and RelVol<0 and open>close then RelVol.Color("DownCandleNegBelow") else if RelVol < numDev and RelVol<0 and open<close then RelVol.Color("UpCandleNegBelow")  else if RElVol>0 and open<close then RelVol.Color("UpCandleBelow") else if RelVol >= numDev and RelVol>0 and open>close then RelVol.Color("DownCandleAbove") else if RElVol>0 and open>close then  RelVol.Color("DownCandleBelow") else  Color.Gray);
StDevLevel.SetDefaultColor(GetColor(7));
StDevLevel.SetStyle(Curve.SHORT_DASH);

The result looks like this on a 1min chart (example here is KOSS):

Fk8EQ3K.png


What I'm interested in, however, is to further modify the relative volume indicator to reflect what is happening with the transaction sizes in the tape.

For example, I was thinking of something like horizontal lines segmenting the volume bars, or maybe a region of the volume bar highlighted with a brighter or darker shade with the proportionally highlighted area reflecting the size of the trade(s). Some way in other words to reflect if the volume bar consists of a bunch of small sells or a massive block sale, and likewise for buys. Because currently, the only way I can be aware of huge buys or sells happening in one transaction is to keep my eyes on the tape. But of course it's very helpful for being able to interpret whether the stock is in accumulation or distribution, to be able to see if any individual sells or buys have sizes that are some standard deviation above normal.

Does anyone have ideas or suggestions for how this could be accomplished (i.e. reflecting large individual tape transactions in a lower study), and furthermore, how it could be combined with the relative volume indicator?

EDIT: Another thing that would be useful is if within the 1min volume bar, it was possible to represent both buy and sell transactions, because that would help to avoid being fooled by when the bar gets painted a misleading color. For example, there can be a 1 share buy at $1, a 10,000 share buy at $2, and then a 1 share sell at $0.99 before the candle closes, and then it makes it look like a massive dump happened in that 1min bar. I've noticed this happens sometimes before a stock gets pumped hard and it's often difficult to see through the deception unless also watching the tape at the same time.
 
Last edited:
@lmk99 Thinkscript only allows a means of Buy and Sell volumes but NOT individual trade volumes as we can see in Time and Sales... There are several volume indicators here in these forums that display the Buy/Sell volume comparison...
 

Join useThinkScript to post your question to a community of 21,000+ developers and traders.

@lmk99 Thinkscript only allows a means of Buy and Sell volumes but NOT individual trade volumes as we can see in Time and Sales... There are several volume indicators here in these forums that display the Buy/Sell volume comparison...
From your reply I understand that it's possible to break down the ratio of buy to sell volume within a candle (to help see through misleading paint jobs on the volume bar) but it's not possible to access within a study the individual trade volumes to designate large chunked trades.

Maybe the closest way to represent that as a lower study would be to have a separate cell which is a tick-based volume study (like Welkin's tick volume study).

But it seems to me like actually the Ticks Per Volume study posted here might work with a 1min chart: https://usethinkscript.com/threads/tick-buy-and-sell-volume-indicator-for-thinkorswim.534/

The description given is: "Shows volume divided by ticks or in other words the volume traded divided by the number of trades. Higher means larger lots being traded and lower bar means smaller lots."

The code is as follows:

Code:
declare lower;
declare zerobase;

def TradeCount = tick_count;
def MoneyCount = volume;

plot avgTradeCount = ((MoneyCount[1] + MoneyCount) / 2) / ((TradeCount + TradeCount[1]) / 2);

AvgTradeCount.SetPaintingStrategy(PaintingStrategy.HISTOGRAM);
AvgTradeCount.AssignValueColor(if TradeCount >= AvgTradeCount then Color.UPTICK else Color.DOWNTICK);

I'm going to see if there's a way to usefully integrate this into the relative volume study.
 
Hi all, this is what I came up with for trying to represent that the share amounts of the individual trade(s) in a candle exceed one or two standard deviations: a horizontal line that is color coded which appears on top of the volume cande. This is the code:

Code:
#
# TD Ameritrade IP Company, Inc. (c) 2014-2021
#

declare lower;
declare zerobase;

input length = 60;
input numDev = 2.0;
input allowNegativeValues = yes;

def rawRelVol = (volume - Average(volume, length)) / StDev(volume, length);
plot RelVol = if allowNegativeValues then rawRelVol else Max(0, rawRelVol);
plot StDevLevel = numDev;

RelVol.SetPaintingStrategy(PaintingStrategy.HISTOGRAM);
RelVol.SetLineWeight(3);
RelVol.DefineColor("UpCandleAbove", Color.Light_Green);
RelVol.DefineColor("DownCandleAbove", Color.Red);
RelVol.DefineColor("UpCandleBelow", Color.CYAN);
RelVol.DefineColor("DownCandleBelow", Color.DARK_ORANGE);
RelVol.DefineColor("DownCandleNegBelow", CreateColor(60,25,25));
RelVol.DefineColor("UpCandleNegBelow", CreateColor(25,60,25));
RelVol.AssignValueColor(if RelVol >= numDev and RelVol>0 and open<close then RelVol.Color("UpCandleAbove") else if RelVol < numDev and RelVol<0 and open>close then RelVol.Color("DownCandleNegBelow") else if RelVol < numDev and RelVol<0 and open<close then RelVol.Color("UpCandleNegBelow")  else if RElVol>0 and open<close then RelVol.Color("UpCandleBelow") else if RelVol >= numDev and RelVol>0 and open>close then RelVol.Color("DownCandleAbove") else if RElVol>0 and open>close then  RelVol.Color("DownCandleBelow") else  Color.Gray);
StDevLevel.SetDefaultColor(GetColor(7));
StDevLevel.SetStyle(Curve.SHORT_DASH);

def TradeCount = tick_count;
def MoneyCount = volume;

def avgTradeCount = ((MoneyCount[1] + MoneyCount) / 2) / ((TradeCount + TradeCount[1]) / 2);

def ticksizestddev = (avgTradeCount - Average(avgTradeCount, length)) / StDev(avgTradeCount, length);

plot relticksize = RelVol;

relticksize.SetPaintingStrategy(PaintingStrategy.HoriZONTAL);
relticksize.SetLineWeight(3);
relticksize.AssignValueColor(if ticksizestddev >= numDev and ticksizestddev>0 and open<close then RelVol.Color("UpCandleAbove") else if ticksizestddev < numDev and ticksizestddev<0 and open>close then RelVol.Color("DownCandleNegBelow") else if ticksizestddev < numDev and ticksizestddev<0 and open<close then RelVol.Color("UpCandleNegBelow")  else if ticksizestddev>0 and open<close then RelVol.Color("UpCandleBelow") else if ticksizestddev >= numDev and ticksizestddev>0 and open>close then RelVol.Color("DownCandleAbove") else if ticksizestddev>0 and open>close then  RelVol.Color("DownCandleBelow") else Color.Gray);

It seems to work pretty OK most of the time, but it doesn't always convey the information that I want it to convey. Recall that the purpose of this indicator is to convey the information that is shown in Time and Sales, to see if the buy or sell volume of that bar consists of a bunch of average sized trades or if it contains any large sized trades. The problem is that a large sized buy of the ask can still happen in Time and Sales but then the information is coded as sell volume if the candle closes down, as in this type of case:

9uOT1It.png


Not sure if you can see well but there was a huge 84,000 share buy of the ask but it was concealed in one of the candles (it may not have been the exact bar I circled, but the point is that the bars made it hard to tell that this had happened because it closed as an indecision candle or a down candle to conceal it; indeed a few minutes after this large buy, the bid moved up significantly).

So I think the solution is that the code for the horizontal line's color needs to somehow factor in if the large trade(s) (or if that's not possible, if the trades overall) were buys or sells, instead of basing the color on how the price candle closed.

Any ideas for how to do this? I think this would be a really useful modification to the relative volume indicator if this could be done. This is for reference an example of when the indicator does what I want, because the candle closes in congruence with the large buy occurring:

ZAZt2oT.png


But how can the horizontal line on the volume bar be made to display that same color even if the candle had closed flat or down?
 
Last edited:
ToS_lowerStudy_volBuySell_Indicator

Code:
# Show total volume in gray.  Buying volume in green.  Sell Volume in red.
# Volume average is gray line.
# Specified percent over average volume is cyan triangles.
# Horserider 12/30/2019 derived from some already existing studies.


declare lower;

#Inputs

input Show30DayAvg = yes;
input ShowTodayVolume =  yes;
input ShowPercentOf30DayAvg = yes;
input UnusualVolumePercent = 200;
input Show30BarAvg = yes;
input ShowCurrentBar = yes;
input ShowPercentOf30BarAvg = yes;
input ShowSellVolumePercent = yes;

def O = open;
def H = high;
def C = close;
def L = low;
def V = volume;
def buying = V*(C-L)/(H-L);
def selling = V*(H-C)/(H-L);

# Selling Volume

Plot SellVol = selling;
SellVol.setPaintingStrategy(PaintingStrategy.Histogram);
SellVol.SetDefaultColor(Color.Red);
SellVol.HideTitle();
SellVol.HideBubble();
SellVol.SetLineWeight(1);

# Total Volume

# Note that Selling + Buying Volume = Volume.
plot TV =  volume;

TV.SetPaintingStrategy(PaintingStrategy.HISTOGRAM);
TV.SetDefaultColor(Color.GRAY);
#TV.HideTitle();
#TV.HideBubble();
TV.SetLineWeight(1);

Plot BuyVol = buying;
BuyVol.setPaintingStrategy(PaintingStrategy.Histogram);
BuyVol.SetDefaultColor(Color.Green);
BuyVol.HideTitle();
BuyVol.HideBubble();
BuyVol.SetLineWeight(5);

#Volume Data

def volLast30DayAvg = (volume(period = "DAY")[1] + volume(period = "DAY")[2] + volume(period = "DAY")[3] + volume(period = "DAY")[4] + volume(period = "DAY")[5] + volume(period = "DAY")[6] + volume(period = "DAY")[7] + volume(period = "DAY")[8] + volume(period = "DAY")[9] + volume(period = "DAY")[10] + volume(period = "DAY")[11] + volume(period = "DAY")[12] + volume(period = "DAY")[13] + volume(period = "DAY")[14] + volume(period = "DAY")[15] + volume(period = "DAY")[16] + volume(period = "DAY")[17] + volume(period = "DAY")[18] + volume(period = "DAY")[19] + volume(period = "DAY")[20] + volume(period = "DAY")[21] + volume(period = "DAY")[22] + volume(period = "DAY")[23] + volume(period = "DAY")[24] + volume(period = "DAY")[25] + volume(period = "DAY")[26] + volume(period = "DAY")[27] + volume(period = "DAY")[28] + volume(period = "DAY")[29] + volume(period = "DAY")[30]) / 30;
def today = volume(period = "DAY");
def percentOf30Day = Round((today / volLast30DayAvg) * 100, 0);
def avg30Bars = (volume[1] + volume[2] + volume[3] + volume[4] + volume[5] + volume[6] + volume[7] + volume[8] + volume[9] + volume[10] + volume[11] + volume[12] + volume[13] + volume[14] + volume[15] + volume[16] + volume[17] + volume[18] + volume[19] + volume[20] + volume[21] + volume[22] + volume[23] + volume[24] + volume[25] + volume[26] + volume[27] + volume[28] + volume[29] + volume[30]) / 30;
def curVolume = volume;
def percentOf30Bar = Round((curVolume / avg30Bars) * 100, 0);
def SellVolPercent = Round((Selling / Volume) * 100, 0);

# Labels

AddLabel(Show30DayAvg, "Avg 30 Days: " + Round(volLast30DayAvg, 0), Color.LIGHT_GRAY);

AddLabel(ShowTodayVolume, "Today: " + today, (if percentOf30Day >= UnusualVolumePercent then Color.GREEN else if percentOf30Day >= 100 then Color.ORANGE else Color.LIGHT_GRAY));

AddLabel(ShowPercentOf30DayAvg, percentOf30Day + "%", (if percentOf30Day >= UnusualVolumePercent then Color.GREEN else if percentOf30Day >= 100 then Color.ORANGE else Color.WHITE) );

AddLabel(Show30BarAvg, "Avg 30 Bars: " + Round(avg30Bars, 0), Color.LIGHT_GRAY);

AddLabel(ShowCurrentBar, "Cur Bar: " + curVolume, (if percentOf30Bar >= UnusualVolumePercent then Color.GREEN else if PercentOf30Bar >= 100 then Color.ORANGE else Color.LIGHT_GRAY));

AddLabel(ShowPercentOf30BarAvg, PercentOf30Bar + "%", (if PercentOf30Bar >= UnusualVolumePercent then Color.GREEN else if PercentOf30Bar >= 100 then Color.ORANGE else Color.WHITE) );

AddLabel(ShowSellVolumePercent, "Cur Bar Sell %: " + SellVolPercent, (if SellVolPercent > 51 then Color.RED else if SellVolPercent < 49 then Color.GREEN else Color.ORANGE));

input length = 20;
plot VolAvg = Average(volume, length);

VolAvg.SetDefaultColor(GetColor(7));


# hiVolume indicator
# source: http://tinboot.blogspot.com
# author: allen everhart


input type = { default SMP, EXP } ;
input length1 = 20 ;
input hotPct = 100.0 ;

def ma =
if type == type.SMP then
SimpleMovingAvg(volume, length)
else
MovAvgExponential(volume, length);

plot hv =
if 100 * ((volume / ma) - 1) >= hotPct then
ma
else
Double.NaN;

hv.SetDefaultColor( Color.CYAN);
hv.SetLineWeight(1) ;
hv.SetPaintingStrategy( PaintingStrategy.TRIANGLES);;

Alert(today/volLast30DayAvg > 3, "Volume above 300% threshold", Alert.BAR, Sound.Ring);
 
ToS_lowerStudy_volBuySell_Indicator

Code:
# Show total volume in gray.  Buying volume in green.  Sell Volume in red.
# Volume average is gray line.
# Specified percent over average volume is cyan triangles.
# Horserider 12/30/2019 derived from some already existing studies.


declare lower;

#Inputs

input Show30DayAvg = yes;
input ShowTodayVolume =  yes;
input ShowPercentOf30DayAvg = yes;
input UnusualVolumePercent = 200;
input Show30BarAvg = yes;
input ShowCurrentBar = yes;
input ShowPercentOf30BarAvg = yes;
input ShowSellVolumePercent = yes;

def O = open;
def H = high;
def C = close;
def L = low;
def V = volume;
def buying = V*(C-L)/(H-L);
def selling = V*(H-C)/(H-L);

# Selling Volume

Plot SellVol = selling;
SellVol.setPaintingStrategy(PaintingStrategy.Histogram);
SellVol.SetDefaultColor(Color.Red);
SellVol.HideTitle();
SellVol.HideBubble();
SellVol.SetLineWeight(1);

# Total Volume

# Note that Selling + Buying Volume = Volume.
plot TV =  volume;

TV.SetPaintingStrategy(PaintingStrategy.HISTOGRAM);
TV.SetDefaultColor(Color.GRAY);
#TV.HideTitle();
#TV.HideBubble();
TV.SetLineWeight(1);

Plot BuyVol = buying;
BuyVol.setPaintingStrategy(PaintingStrategy.Histogram);
BuyVol.SetDefaultColor(Color.Green);
BuyVol.HideTitle();
BuyVol.HideBubble();
BuyVol.SetLineWeight(5);

#Volume Data

def volLast30DayAvg = (volume(period = "DAY")[1] + volume(period = "DAY")[2] + volume(period = "DAY")[3] + volume(period = "DAY")[4] + volume(period = "DAY")[5] + volume(period = "DAY")[6] + volume(period = "DAY")[7] + volume(period = "DAY")[8] + volume(period = "DAY")[9] + volume(period = "DAY")[10] + volume(period = "DAY")[11] + volume(period = "DAY")[12] + volume(period = "DAY")[13] + volume(period = "DAY")[14] + volume(period = "DAY")[15] + volume(period = "DAY")[16] + volume(period = "DAY")[17] + volume(period = "DAY")[18] + volume(period = "DAY")[19] + volume(period = "DAY")[20] + volume(period = "DAY")[21] + volume(period = "DAY")[22] + volume(period = "DAY")[23] + volume(period = "DAY")[24] + volume(period = "DAY")[25] + volume(period = "DAY")[26] + volume(period = "DAY")[27] + volume(period = "DAY")[28] + volume(period = "DAY")[29] + volume(period = "DAY")[30]) / 30;
def today = volume(period = "DAY");
def percentOf30Day = Round((today / volLast30DayAvg) * 100, 0);
def avg30Bars = (volume[1] + volume[2] + volume[3] + volume[4] + volume[5] + volume[6] + volume[7] + volume[8] + volume[9] + volume[10] + volume[11] + volume[12] + volume[13] + volume[14] + volume[15] + volume[16] + volume[17] + volume[18] + volume[19] + volume[20] + volume[21] + volume[22] + volume[23] + volume[24] + volume[25] + volume[26] + volume[27] + volume[28] + volume[29] + volume[30]) / 30;
def curVolume = volume;
def percentOf30Bar = Round((curVolume / avg30Bars) * 100, 0);
def SellVolPercent = Round((Selling / Volume) * 100, 0);

# Labels

AddLabel(Show30DayAvg, "Avg 30 Days: " + Round(volLast30DayAvg, 0), Color.LIGHT_GRAY);

AddLabel(ShowTodayVolume, "Today: " + today, (if percentOf30Day >= UnusualVolumePercent then Color.GREEN else if percentOf30Day >= 100 then Color.ORANGE else Color.LIGHT_GRAY));

AddLabel(ShowPercentOf30DayAvg, percentOf30Day + "%", (if percentOf30Day >= UnusualVolumePercent then Color.GREEN else if percentOf30Day >= 100 then Color.ORANGE else Color.WHITE) );

AddLabel(Show30BarAvg, "Avg 30 Bars: " + Round(avg30Bars, 0), Color.LIGHT_GRAY);

AddLabel(ShowCurrentBar, "Cur Bar: " + curVolume, (if percentOf30Bar >= UnusualVolumePercent then Color.GREEN else if PercentOf30Bar >= 100 then Color.ORANGE else Color.LIGHT_GRAY));

AddLabel(ShowPercentOf30BarAvg, PercentOf30Bar + "%", (if PercentOf30Bar >= UnusualVolumePercent then Color.GREEN else if PercentOf30Bar >= 100 then Color.ORANGE else Color.WHITE) );

AddLabel(ShowSellVolumePercent, "Cur Bar Sell %: " + SellVolPercent, (if SellVolPercent > 51 then Color.RED else if SellVolPercent < 49 then Color.GREEN else Color.ORANGE));

input length = 20;
plot VolAvg = Average(volume, length);

VolAvg.SetDefaultColor(GetColor(7));


# hiVolume indicator
# source: http://tinboot.blogspot.com
# author: allen everhart


input type = { default SMP, EXP } ;
input length1 = 20 ;
input hotPct = 100.0 ;

def ma =
if type == type.SMP then
SimpleMovingAvg(volume, length)
else
MovAvgExponential(volume, length);

plot hv =
if 100 * ((volume / ma) - 1) >= hotPct then
ma
else
Double.NaN;

hv.SetDefaultColor( Color.CYAN);
hv.SetLineWeight(1) ;
hv.SetPaintingStrategy( PaintingStrategy.TRIANGLES);;

Alert(today/volLast30DayAvg > 3, "Volume above 300% threshold", Alert.BAR, Sound.Ring);

Thanks for the suggestion. This study has the same limitation: where I circled, a huge buy of the ask had occurred in the Time and Sales but the volume studies don't show that at all, they just show red and gray on those bars:

 
Thanks for the suggestion. This study has the same limitation: where I circled, a huge buy of the ask had occurred in the Time and Sales but the volume studies don't show that at all, they just show red and gray on those bars:

You're welcome. By chance does that large Buy at the Ask, that will not show up, have extra decimal point numbers? As in the trading price is $. but then all of a sudden you see a series of $.00* or $.00** (*being the extra decimal numbers, equallying a fraction of Bid or Ask price.)
 
I wish think script allowed access to the time and sell date. but it doesn't seem like it does. I guess only think you can really do is use tick charts and use tick_count/volume on it to ~the sell/buy size.
 
I wish think script allowed access to the time and sell date. but it doesn't seem like it does. I guess only think you can really do is use tick charts and use tick_count/volume on it to ~the sell/buy size.

@ktp You are correct... We do not have access to the Time and Sales data... I believe someone posted a tick-based solution within the past few weeks for someone with the same question...
 

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
445 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