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!
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);