VO w/RelSpikes + Buyers and Sellers Perc

rewardiaz

Active member
VIP
Hi Guys,

I'm working on creating a Volume Oscilator that currently help display Rel Vol Spikes and the percentage of Buyers and Sellers. Can someone help me identify divergence?

The logic used below is not really doing it.

Many Thanks!

Python:
# ########################################
# VO ((V)olume (O)scillator) + Relative VolSpikes + Buy/Sell%
# Credit to @MerryDay
# Credit to @UpTwoBucks "RelVolSpikes/Buyers and Seller" - https://usethinkscript.com/threads/relative-volume-spike-buy-sell-chart-setup-for-thinkorswim.15555/

# ########################################
# Charting & Formatting
declare lower;
declare real_size;

# ########################################
# Global
def na = Double.NaN;
input C = close;
input bullish_spike_percentage_threshold = 100.0;     # Set the percentage threshold for the bullish spike
input bearish_spike_percentage_threshold = 100.0;     # Set the percentage threshold for the bearish spike
input showVolSpikesSignals = yes;
input fastLength = 9;
input slowLength = 27;
input diffType = {default points, percent};
input lookback = 9;                                   # Lookback period for peaks and troughs

# ########################################
# Chart Coloring
DefineGlobalColor("maxxed", CreateColor(50, 200, 255));
DefineGlobalColor("rising",  CreateColor(0, 165, 0));
DefineGlobalColor("bear",  CreateColor(225, 0, 0));
DefineGlobalColor("pretrend", CreateColor(200, 125, 255));
DefineGlobalColor("neutral", Color.DARK_ORANGE);
DefineGlobalColor("bull_divergence", Color.CYAN);
DefineGlobalColor("bear_divergence", Color.MAGENTA);
# ########################################################

plot VO;
switch (diffType) {
case points:
    VO = Average(volume, fastLength) - Average(volume, slowLength);
case percent:
    VO = (Average(volume, fastLength) - Average(volume, slowLength)) / Average(volume, slowLength);
}
plot ZL = 0;
ZL.SetDefaultColor(GlobalColor("neutral"));
ZL.SetLineWeight(2);

VO.AssignValueColor(
    if VO >= ZL then
        if VO >= VO[1] then GlobalColor("rising") else GlobalColor("bear")
    else
        if VO >= VO[1] then GlobalColor("rising") else GlobalColor("bear")
);
VO.HideBubble();
VO.HideTitle();
VO.SetLineWeight(2);

# ########################################
# Volumen Buyers vs Selling
def O = open;
def H = high;
def L = low;
def V = volume;
def Buying = V * (C - L) / (H - L);
def Selling = V * (H - C) / (H - L);
def totVol = Round(Buying, 0) + Round(Selling, 0) ;
def buyPercent = if totVol != 0 then (Round(Buying, 0) / totVol) * 100 else 0;
def sellPercent = if totVol != 0 then (Round(Selling, 0) / totVol) * 100 else 0;

# ########################################
# Volume Spikes Signals
# Calculate the relative volume for the current bar
# Calculate the percentage change in volume relative to the average volume
# Determine if the current bar has a bullish volume spike
# Determine if the current bar has a bearish volume spike
# Define the label value as the percentage change in volume if it is a spike, otherwise NaN
def rel_vol = V / Average(V, 50);
def vol_change_pct = (rel_vol - 1.0) * 100.0;
def is_bullish_spike = vol_change_pct >= bullish_spike_percentage_threshold and C > O;
def is_bearish_spike = vol_change_pct >= bearish_spike_percentage_threshold and C < O;
def label_value = if is_bullish_spike or is_bearish_spike then vol_change_pct else na;

# Plot dots for bullish spikes
plot BullishDot = if is_bullish_spike then VO else na;
BullishDot.SetPaintingStrategy(PaintingStrategy.POINTS);
BullishDot.SetDefaultColor(GlobalColor("rising"));
BullishDot.SetLineWeight(4);
BullishDot.HideBubble();
BullishDot.HideTitle();

# Plot dots for bearish spikes
plot BearishDot = if is_bearish_spike then VO else na;
BearishDot.SetPaintingStrategy(PaintingStrategy.POINTS);
BearishDot.SetDefaultColor(GlobalColor("bear"));
BearishDot.SetLineWeight(4);
BearishDot.HideBubble();
BearishDot.HideTitle();

# ########################################################
# Divergence Detection
# Identify peaks and troughs in price and VO
def priceHigh = if high > Highest(high[1], lookback) and high > Highest(high[-lookback], lookback) then high else na;
def priceLow = if low < Lowest(low[1], lookback) and low < Lowest(low[-lookback], lookback) then low else na;
def voHigh = if VO > Highest(VO[1], lookback) and VO > Highest(VO[-lookback], lookback) then VO else na;
def voLow = if VO < Lowest(VO[1], lookback) and VO < Lowest(VO[-lookback], lookback) then VO else na;

# Detect bullish divergence (price making lower low, VO making higher low)
def bullDiv = if !IsNaN(priceLow) and !IsNaN(voLow) and priceLow < priceLow[lookback] and voLow > voLow[lookback] then priceLow else na;
plot BullDivLine = if bullDiv then VO else na;
BullDivLine.enableApproximation();
BullDivLine.SetPaintingStrategy(PaintingStrategy.POINTS);
BullDivLine.SetDefaultColor(GlobalColor("bull_divergence"));
BullDivLine.SetLineWeight(3);

# Detect bearish divergence (price making higher high, VO making lower high)
def bearDiv = if !IsNaN(priceHigh) and !IsNaN(voHigh) and priceHigh > priceHigh[lookback] and voHigh < voHigh[lookback] then priceHigh else na;
plot BearDivLine = if bearDiv then VO else na;
BearDivLine.enableApproximation();
BearDivLine.SetPaintingStrategy(PaintingStrategy.POINTS);
BearDivLine.SetDefaultColor(GlobalColor("bear_divergence"));
BearDivLine.SetLineWeight(3);

# ########################################################
# The same logic that was used in coloring the plot can be used in labels
AddLabel(yes,
    if VO >= ZL then
        if VO >= VO[1] then "VO: is Above[0] and Rising" else "VO: is Above[0] but Falling"
    else
        if VO >= VO[1] then "VO: is Below[0] but Rising" else "VO: is Below[0] and Falling",
    if VO >= ZL then
        if VO >= VO[1] then GlobalColor("rising") else GlobalColor("bear")
    else
        if VO >= VO[1] then GlobalColor("rising") else GlobalColor("bear")
);

AddLabel(yes,
    "Curr. Bar: " + Round(buyPercent, 0) + "% BUYERS",
    if Buying > Selling then GlobalColor("rising") else
    Color.BLACK);
AddLabel(yes,
    "Curr. Bar: " + Round(sellPercent, 0) +  "% SELLERS",
    if Selling > Buying then GlobalColor("bear") else
    Color.BLACK);
 
Solution
Okay, found a way to code it into the code code. Hope helps others.

Code:
# ########################################
# VO ((V)olume (O)scillator) + Relative VolSpikes + Buy/Sell% + Divergence
# Credit to @MerryDay
# Credit to @UpTwoBucks "RelVolSpikes/Buyers and Seller" - https://usethinkscript.com/threads/relative-volume-spike-buy-sell-chart-setup-for-thinkorswim.15555/
# Credit to @samer800 "Divergence" - RSI-Heiken Ashi For ThinkOrSwim

# ########################################
# Charting & Formatting
declare lower;
declare real_size;

# ########################################
# Global
def na = Double.NaN;
input C = close;
input bullish_spike_percentage_threshold = 100.0;     # Set the percentage threshold for the bullish spike
input...
Okay, found a way to code it into the code code. Hope helps others.

Code:
# ########################################
# VO ((V)olume (O)scillator) + Relative VolSpikes + Buy/Sell% + Divergence
# Credit to @MerryDay
# Credit to @UpTwoBucks "RelVolSpikes/Buyers and Seller" - https://usethinkscript.com/threads/relative-volume-spike-buy-sell-chart-setup-for-thinkorswim.15555/
# Credit to @samer800 "Divergence" - RSI-Heiken Ashi For ThinkOrSwim

# ########################################
# Charting & Formatting
declare lower;
declare real_size;

# ########################################
# Global
def na = Double.NaN;
input C = close;
input bullish_spike_percentage_threshold = 100.0;     # Set the percentage threshold for the bullish spike
input bearish_spike_percentage_threshold = 100.0;     # Set the percentage threshold for the bearish spike
input showVolSpikesSignals = yes;
input fastLength = 9;
input slowLength = 27;
input diffType = {default points, percent};
input showDivergence = yes;

# ########################################
# Chart Coloring
DefineGlobalColor("maxxed", CreateColor(50, 200, 255));
DefineGlobalColor("rising",  CreateColor(0, 165, 0));
DefineGlobalColor("bear",  CreateColor(225, 0, 0));
DefineGlobalColor("pretrend", CreateColor(200, 125, 255));
DefineGlobalColor("neutral", Color.DARK_ORANGE);
# ########################################################

plot VO;
switch (diffType) {
case points:
    VO = Average(volume, fastLength) - Average(volume, slowLength);
case percent:
    VO = (Average(volume, fastLength) - Average(volume, slowLength)) / Average(volume, slowLength);
}
plot ZL = 0;
ZL.SetDefaultColor(GlobalColor("neutral"));
ZL.SetLineWeight(2);

VO.AssignValueColor(
    if VO >= ZL then
        if VO >= VO[1] then GlobalColor("rising") else GlobalColor("bear")
    else
        if VO >= VO[1] then GlobalColor("rising") else GlobalColor("bear")
);
VO.HideBubble();
VO.HideTitle();
VO.SetLineWeight(2);

# ########################################
# Volumen Buyers vs Sellers
def O = open;
def H = high;
def L = low;
def V = volume;
def Buying = V * (C - L) / (H - L);
def Selling = V * (H - C) / (H - L);
def totVol = Round(Buying, 0) + Round(Selling, 0) ;
def buyPercent = if totVol != 0 then (Round(Buying, 0) / totVol) * 100 else 0;
def sellPercent = if totVol != 0 then (Round(Selling, 0) / totVol) * 100 else 0;

# ########################################
# Volume Spikes Signals
# Calculate the relative volume for the current bar
# Calculate the percentage change in volume relative to the average volume
# Determine if the current bar has a bullish volume spike
# Determine if the current bar has a bearish volume spike
# Define the label value as the percentage change in volume if it is a spike, otherwise NaN
def rel_vol = V / Average(V, 50);
def vol_change_pct = (rel_vol - 1.0) * 100.0;
def is_bullish_spike = vol_change_pct >= bullish_spike_percentage_threshold and C > O;
def is_bearish_spike = vol_change_pct >= bearish_spike_percentage_threshold and C < O;
def label_value = if is_bullish_spike or is_bearish_spike then vol_change_pct else na;

# Plot dots for bullish spikes
plot BullishDot = if is_bullish_spike then VO else na;
BullishDot.SetPaintingStrategy(PaintingStrategy.POINTS);
BullishDot.SetDefaultColor(GlobalColor("rising"));
BullishDot.SetLineWeight(4);
BullishDot.HideBubble();
BullishDot.HideTitle();

# Plot dots for bearish spikes
plot BearishDot = if is_bearish_spike then VO else na;
BearishDot.SetPaintingStrategy(PaintingStrategy.POINTS);
BearishDot.SetDefaultColor(GlobalColor("bear"));
BearishDot.SetLineWeight(4);
BearishDot.HideBubble();
BearishDot.HideTitle();

# ########################################################
# Divergence Detection
# Identify peaks and troughs in price and VO
def lenVO = floor(slowLength / 2);
def bn = BarNumber();

def VO_H = fold Hi = 1 to lenVO with Hp = 1 while Hp do VO > GetValue(VO, -Hi);
def VO_L = fold Li = 1 to lenVO with Lp = 1 while Lp do VO < GetValue(VO, -Li);
def pvtH = if VO == Highest(VO, lenVO) and VO_H then VO else na;
def pvtL = if VO == Lowest(VO, lenVO) and VO_L then VO else na;
def VO_PHBar = if !IsNaN(pvtH) then bn else VO_PHBar[1];
def VO_PLBar = if !IsNaN(pvtL) then bn else VO_PLBar[1];
def VO_PHPoint = if !IsNaN(pvtH) then pvtH else VO_PHPoint[1];
def VO_PLPoint = if !IsNaN(pvtL) then pvtL else VO_PLPoint[1];
def VO_LastPHBar = if VO_PHBar != VO_PHBar[1] then VO_PHBar[1] else VO_LastPHBar[1];
def VO_LastPLBar = if VO_PLBar != VO_PLBar[1] then VO_PLBar[1] else VO_LastPLBar[1];
def VO_HighPivots = BarNumber() >= HighestAll(VO_LastPHBar);
def VO_LowPivots = BarNumber() >= HighestAll(VO_LastPLBar);
def VO_pivotHigh = if VO_HighPivots then pvtH else na;
def VO_pivotLow = if VO_LowPivots then pvtL else na;

plot VO_plotHline = if showDivergence then VO_pivotHigh else na;
VO_plotHline.EnableApproximation();
VO_plotHline.SetDefaultColor(GlobalColor("neutral"));
VO_plotHline.SetStyle(Curve.SHORT_DASH);

plot VO_plotLline = if showDivergence and VO_LowPivots then pvtL else na;
VO_plotLline.EnableApproximation();
VO_plotLline.SetDefaultColor(GlobalColor("neutral"));
VO_plotLline.SetStyle(Curve.SHORT_DASH);

plot VO_pivotDot = if !IsNaN(VO_pivotHigh) then VO_pivotHigh else if !IsNaN(VO_pivotLow) then VO_pivotLow else na;
VO_pivotDot.SetDefaultColor(GlobalColor("neutral"));
VO_pivotDot.SetPaintingStrategy(PaintingStrategy.POINTS);
VO_pivotDot.SetLineWeight(3);

# ########################################################
# The same logic that was used in coloring the plot can be used in labels
AddLabel(yes,
    if VO >= ZL then
        if VO >= VO[1] then "VO: is Above[0] and Rising" else "VO: is Above[0] but Falling"
    else
        if VO >= VO[1] then "VO: is Below[0] but Rising" else "VO: is Below[0] and Falling",
    if VO >= ZL then
        if VO >= VO[1] then GlobalColor("rising") else GlobalColor("bear")
    else
        if VO >= VO[1] then GlobalColor("rising") else GlobalColor("bear")
);

AddLabel(yes,
    "Curr. Bar: " + Round(buyPercent, 0) + "% BUYERS",
    if Buying > Selling then GlobalColor("rising") else
    Color.BLACK);
AddLabel(yes,
    "Curr. Bar: " + Round(sellPercent, 0) +  "% SELLERS",
    if Selling > Buying then GlobalColor("bear") else
    Color.BLACK);
 
Solution

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