BuySell Volume, PreMarket OBV & CumuVol For ThinkOrSwim

walkr

New member
All-in-oneBuySell Volume w/ Labels, PreMarket OBV & Cumulative Premarket Vol, etc.

My first post. I hope it's useful to someone. Any critiques are helpful.

N9tUgt7.png
qJvXfBu.png


Includes:
  1. More InDepth Buy/Sell Volume Labels
  2. Cumulative Premarket Volume
  3. Premarket OnBalance Volume
  4. Volume Simple 9 Period Moving Average
  5. Midpoint to help gauge
  6. Dynamic Coloring

How Labels are read:
[ Vol: Current Volume (Previous Volume) Percent Change From Previous ]

Code:
# All-in-oneBuySell Volume w/ Labels, PreMarket OBV, Cumulative Premarket Vol
# @walkr 3/6/2022
#hint showVol9MovAvg: Simple 9 period moving average for volume
#hint showBarPercent: Shows current bar's buyers vs sellers as percent \n <li>Green = Current buyers</li><li>Red = Current sellers</li>
#hint showBarVisual: Represents current bar's buyer to seller percent with a horizontal positive/negative bar
#hint showPrevVol: Shows previous buy or sell volume in parenthesis
#hint showPreMktOBV: Shows pre-market on-balane volume
#hint PreMkt: Time pre-market starts
#hint MktOpen: Time regular trading starts
#hint AfterMkt: Time regular trading ends

input showTodaysVol = yes;
input showVolMovAvg = yes;
input showBuyAndSellVolLabels = yes;
input showBarPercent = yes;
input showBarVisual = no;
input showPrevVol = yes;
input showPercentChg = yes;
input showPreMktCmlVol = no;
input showPreMktOBV = yes;
input PreMkt = 0100;
input MktOpen = 930;
input AfterMkt = 1600;

def v = volume;
def h = high;
def o = open;
def c = close;
def l = low;

# Calculations

def tv = volume(period = AggregationPeriod.DAY);
def bv = RoundUp(v * (c - l) / (h - l));
def sv = RoundDown(v * (h - c) / (h - l));
def br = bv / v;
def sr = sv / v;
def bp = br * 100;
def sp = sr * 100;
def bvpc = ((bv - bv[1]) / bv[1]);
def svpc = ((sv - sv[1]) / sv[1]);
def bsr = Round((bv - (if v == 0 then 0.5 else (v / 2))) / ((if v == 0 then 1 else v) - 0) * 100, 1);

# Conditions & Parameters

def u = br > 1 / 2;
def d = sr > 1 / 2;
def ut = br > br[1];
def dt = sr > sr[1];

def isPm = SecondsFromTime(PreMkt) >= 0 and SecondsTillTime(MktOpen) > 0;
def pmStart = isPm and !isPm[1];
def isDay = SecondsFromTime(MktOpen) >= 0 and SecondsTillTime(AfterMkt) > 0;
def dayStart = isDay and !isDay[1];

# Self-referring Variables

def n = n[1] + if pmStart then 1 else 0;
def nDay =  if dayStart then 1 else nDay[1] + 1;
def cmVol = if dayStart then v else if isDay then if nDay > 9 then v + v[1] + v[2] + v[3] + v[4] + v[5] + v[6] + v[7] + v[8] else cmVol[1] + v else cmVol[1];
def cmlPmVol = if pmStart then v else if isPm then cmlPmVol[1] + v else cmlPmVol[1];
def pmOBV = if pmStart then if c > o then v else if c < o then - v else 0 else if isPm then if c > o then pmOBV[1] + v else if c < o then pmOBV[1] - v else pmOBV[1] else pmOBV[1];

# AvgPreMktVol

def ONV1;
def ONV2;
def ONV3;
def ONV4;
def ONV5;
if (pmStart and n > 1) {
    ONV1 = cmlPmVol[1];
    ONV2 = ONV1[1];
    ONV3 = ONV2[1];
    ONV4 = ONV3[1];
    ONV5 = ONV4[1];
} else {
    ONV1 = ONV1[1];
    ONV2 = ONV2[1];
    ONV3 = ONV3[1];
    ONV4 = ONV4[1];
    ONV5 = ONV5[1];
}

def avgPMV = if n > 5 then (ONV1 + ONV2 + ONV3 + ONV4 + ONV5) / 5 else Double.NaN;

# Plots

plot PrevCmlVol = if !showPreMktCmlVol then Double.NaN else if isPm then cmlPmVol - v else Double.NaN;
plot NegVolume = if showPreMktCmlVol then if isPm then Double.NaN else sv else sv;
plot PosVolume = if showPreMktCmlVol then if isPm then cmlPmVol else bv + sv else bv + sv;
plot Mid = if !(bp > 60 or bp < 40 or bv == sv) then v / 2 else Double.NaN;
plot AvgVol = if showVolMovAvg then if isDay then if nDay < 9 then cmVol / nDay else cmVol / 9 else Double.NaN else Double.NaN;
plot PreMktOBV = if showPreMktOBV then if isPm then pmOBV else Double.NaN else Double.NaN;

# Today Volume Label

AddLabel(!IsNaN(tv) and showTodaysVol,  " Today's Vol: " + (if tv >= 1000000 then Round(tv / 1000000, 1)  else if tv >= 1000 then Round(tv / 1000, 1) else Round(tv / 100) * 100) + (if tv >= 1000000 then "M " else if tv >= 1000 then "K " else "") + " ", Color.GRAY);

# Buy Label

AddLabel(showBuyAndSellVolLabels,
    " Buy Vol: " + (if IsNaN(bv) then 0 else (if bv >= 1000000 then Round(bv / 1000000, 1)  else if bv >= 1000 then Round(bv / 1000, 1) else Round(bv / 100) * 100)) + (if bv >= 1000000 then "M " else if bv >= 1000 then "K " else " ") +
    (if showPrevVol then "(" +  (if IsNaN(bv[1]) then 0 else if AbsValue(bv[1]) >= 1000000 then Round(bv[1] / 1000000, 1)  else if AbsValue(bv[1]) >= 1000 then Round(bv[1] / 1000, 1) else bv[1]) + (if AbsValue(bv[1]) >= 1000000 then "M) " else if AbsValue(bv[1]) >= 1000 then "K) " else ") ") else " ") +
    if !showPercentChg then "  " else ((if bvpc > 0 then "+" else "") + (if IsNaN(bvpc) then "----" else if bvpc > 999999 then "" + 999999 else Round(bvpc * 100, 1) + "") + "%  "),
    if IsNaN(bvpc) or IsNaN(svpc) then Color.DARK_GRAY else if (AbsValue(bvpc) > AbsValue(svpc)) then if (bvpc > 0) then CreateColor(0, 50 + (205 * br), 0) else if (bvpc < 0) then CreateColor(200, 120, 120) else Color.GRAY else if (svpc > bvpc) then Color.GRAY else Color.GRAY);

# Sell Label

AddLabel(showBuyAndSellVolLabels,
    " Sell Vol: " + (if IsNaN(sv) then 0 else (if sv >= 1000000 then Round(sv / 1000000, 1)  else if sv >= 1000 then Round(sv / 1000, 1) else Round(sv / 100) * 100)) + (if sv >= 1000000 then "M " else if sv >= 1000 then "K " else " ") +
    ( if showPrevVol then "(" + (if IsNaN(sv[1]) then 0 else if AbsValue(sv[1]) >= 1000000 then Round(sv[1] / 1000000, 1)  else if AbsValue(sv[1]) >= 1000 then Round(sv[1] / 1000, 1) else sv[1]) + (if AbsValue(sv[1]) >= 1000000 then "M) " else if AbsValue(sv[1]) >= 1000 then "K) " else ") ") else " ") +
    if !showPercentChg then "  " else ((if svpc > 0 then "+" else "") + (if IsNaN(svpc) then "----" else if svpc > 999999 then "" + 999999 else Round(svpc * 100, 1) + "") + "%  "),
     if IsNaN(svpc) or IsNaN(bvpc) then Color.DARK_GRAY else if (AbsValue(bvpc) < AbsValue(svpc)) then if (svpc < 0) then CreateColor(120, 200, 120) else if (svpc > 0) then CreateColor(50 + (205 * sr), 0, 0) else Color.GRAY else if (svpc < bvpc) then Color.GRAY else Color.GRAY);

# Current Bar Percent Label

AddLabel(!IsNaN(v) and showBarPercent,
     (if showBarVisual then "{" + (if bsr < 0 then (if AbsValue(bsr) >= 50 then "\" else if AbsValue(bsr) >= 47.5 then "`" else "_") + (if AbsValue(bsr) >= 45 then "\" else if AbsValue(bsr) >= 42.5 then "`" else "_") + (if AbsValue(bsr) >= 40 then "\" else if AbsValue(bsr) >= 37.5 then "`" else "_") + (if AbsValue(bsr) >= 35 then "\" else if AbsValue(bsr) >= 32.5 then "`" else "_") + (if AbsValue(bsr) >= 30 then "\" else if AbsValue(bsr) >= 27.5 then "`" else "_") + (if AbsValue(bsr) >= 25 then "\" else if AbsValue(bsr) >= 22.5 then "`" else "_") + (if AbsValue(bsr) >= 20 then "\" else if AbsValue(bsr) >= 17.5 then "`" else "_") + (if AbsValue(bsr) >= 15 then "\" else if AbsValue(bsr) >= 12.5 then "`" else "_") + (if AbsValue(bsr) >= 10 then "\" else if AbsValue(bsr) >= 7.5 then "`" else "_") + (if AbsValue(bsr) >= 5 then "\|" else if AbsValue(bsr) >= 2.5 then "`|" else "_|") else "__________|") + (if bsr >= 5 then "\" else if bsr >= 2.5 then "`" else "_") + (if bsr >= 10 then "\" else if bsr >= 7.5 then "`" else "_") + (if bsr >= 15 then "\" else if bsr >= 12.5 then "`" else "_") + (if bsr >= 20 then "\" else if bsr >= 17.5 then "`" else "_") + (if bsr >= 25 then "\" else if bsr >= 22.5 then "`" else "_") + (if bsr >= 30 then "\" else if bsr >= 27.5 then "`" else "_") + (if bsr >= 35 then "\" else if bsr >= 32.5 then "`" else "_") + (if bsr >= 40 then "\" else if bsr >= 37.5 then "`" else "_") + (if bsr >= 45 then "\" else if bsr >= 42.5 then "`" else "_") + (if bsr >= 50 then "\" else if bsr >= 47.5 then "`" else "_") + "} " else "") + " " +
    (if IsNaN(bsr) then "----" else bsr * 2 + "") + "% ", if IsNaN(br) or IsNaN(sr) then Color.DARK_GRAY else if br == 0 then Color.RED else if sr == 0 then Color.GREEN else if u && ut then CreateColor((255 * sr), 255, (255 * sr)) else if d && dt then CreateColor(255, (255 * br), (255 * br)) else Color.ORANGE);

# Cumulative PreMkt Volume Label

AddLabel(yes, "PreMkt Vol: " + (if cmlPmVol >= 1000000 then Round(cmlPmVol / 1000000, 1)  else if cmlPmVol >= 1000 then Round(cmlPmVol / 1000, 1) else Round(cmlPmVol / 100) * 100) + (if cmlPmVol >= 1000000 then "M " else if cmlPmVol >= 1000 then "K " else ""), if isPm then if cmlPmVol > avgPMV then Color.GREEN else Color.ORANGE else Color.DARK_GRAY);

# Appearance

DefineGlobalColor("PosVolume", Color.GREEN);
DefineGlobalColor("NegVolume", Color.RED);
DefineGlobalColor("NeutVolume", Color.GRAY);
DefineGlobalColor("CmlVol", Color.BLACK);

AvgVol.SetDefaultColor(Color.YELLOW);
Mid.SetDefaultColor(Color.BLACK);
PreMktOBV.SetDefaultColor(Color.ORANGE);

PosVolume.AssignValueColor(if showPreMktCmlVol && isPm then if u then GlobalColor("PosVolume") else if d then GlobalColor("NegVolume") else GlobalColor("NeutVolume") else (if u then GlobalColor("PosVolume") else if d then GlobalColor("NeutVolume") else GlobalColor("NeutVolume")));
NegVolume.AssignValueColor(if d then GlobalColor("NegVolume") else if u then GlobalColor("NeutVolume") else GlobalColor("NeutVolume"));
PrevCmlVol.AssignValueColor(GlobalColor("CmlVol"));

PosVolume.SetPaintingStrategy(PaintingStrategy.HISTOGRAM);
NegVolume.SetPaintingStrategy(PaintingStrategy.HISTOGRAM);
PrevCmlVol.SetPaintingStrategy(PaintingStrategy.HISTOGRAM);
Mid.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
 

Attachments

  • N9tUgt7.png
    N9tUgt7.png
    266.1 KB · Views: 394
Last edited by a moderator:

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