// This work is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 4.
0
International
// [Link]
// © BigBeluga
//@version=6
indicator('High Volume Points [BigBeluga]', overlay = true, max_polylines_count = 100,
max_lines_count = 17, max_labels_count = 500, max_bars_back = 1000)
//
==================================================================================
===================================}
// INPUTS
//
==================================================================================
==================================={
//@variable Diameter of the circles
step = [Link](1, 'Diameter Of Circles', step = 0.1, group = 'Settings')
//@variable Volume threshold to filter points
filter_vol = [Link](2, 'Filter Points by Volume', step = 0.1, group = 'Settings', minval = 0, maxval =
6)
//@variable Number of bars to the left of the pivot
int leftBars = input(15, "Left Bars", group = "Points")
int rightBars = input(15, "Right Bars", group = "Points")
//@variable Option to show levels
show_lvl = [Link](true, 'Show Levels', group = 'Visual')
// Define scaling factors
float xScale = 2.0
float yScale = 0.5 * [Link](500)
// Define colors
color upper_col = [Link](#fda05e, "", inline = "1")
color lower_col = [Link](#2fd68e, "", inline = "1")
// Dynamic width levels
int width1 = 0
int width2 = 0
// Initialize arrays for storing points and levels
var points = [Link]<[Link]>()
var levels = [Link]<line>()
//
==================================================================================
===================================}
// CALCULATIONS
//
==================================================================================
==================================={
// Calculate pivot high and pivot low
ph = [Link](leftBars, rightBars)
pl = [Link](leftBars, rightBars)
volume_ = [Link](volume, leftBars * 2)
// Calculate normalized volume delta
float vol = volume_
// Get min and max volume within the lookback period
min_vol = [Link](volume_, 300)
max_vol = [Link](volume_, 300)
// // Normalize the volume between 0 and 6
// norm_vol = ((volume_ - min_vol) / (max_vol - min_vol)) * 6
reference_vol = ta.percentile_nearest_rank(volume_, 1000, 95)
norm_vol = volume_ / reference_vol * 5
check_cross(arrayOfLines) =>
int qtyOfLines = [Link](arrayOfLines)
for lineNo = 0 to qtyOfLines > 0 ? qtyOfLines - 1 : na by 1
if lineNo < [Link](arrayOfLines)
line currentLine = [Link](arrayOfLines, lineNo)
float lineLevel = line.get_price(currentLine, bar_index)
bool lineWasCrossed = [Link](close[1] - lineLevel) != [Link](close - lineLevel)
if lineWasCrossed
line.set_style(currentLine, line.style_dotted)
[Link](arrayOfLines, lineNo)
int(na)
else
line.set_x2(currentLine, bar_index)
int(na)
method draw_circle(bool src, int mult_x, int mult_y) =>
[Link]()
float angle = 0
var float source = 0.
var color color = na
switch
src =>
source := high[rightBars]
color := upper_col
color
=>
source := low[rightBars]
color := lower_col
color
for i = 1 to 11 by 1
int xValue = int([Link](xScale * mult_x * [Link](angle))) + bar_index - rightBars
float yValue = yScale * mult_y * [Link](angle) + source
angle := angle + [Link] / 5
[Link]([Link].from_index(xValue, yValue))
[Link](points, curved = false, line_color = color, fill_color = [Link](color, 90), line_width
= 1)
//@function draw level.
method draw_level(float src, int n, width, color) =>
[Link](x1 = n, y1 = src, x2 = n, y2 = src, style = line.style_solid, width = [Link](width / 3),
color = color)
//
==================================================================================
===================================}
// PLOT
//
==================================================================================
==================================={
if last_bar_index - bar_index < 300
// ————— Plotting logic for high pivots
for i = 0 to 10 by 1
condition = not na(ph) and norm_vol > i and norm_vol > filter_vol
if condition and [Link]
true.draw_circle([Link](i * step), [Link](i * step))
width1 := width1 + 1
width1
if not na(ph) and norm_vol > filter_vol and [Link]
int n = bar_index - rightBars
float src = high[rightBars]
[Link] cp = [Link].from_index(n, src)
[Link](src.draw_level(n, width1, upper_col))
[Link](cp, textcolor = chart.fg_color, color = [Link](upper_col, 30), style =
label.style_circle, size = [Link])
[Link](cp, text = [Link](vol, [Link]), textcolor = chart.fg_color, color =
color(na), style = label.style_label_down)
// ————— Plotting logic for low pivots
for i = 10 to 0 by 1
condition = not na(pl) and norm_vol > i and norm_vol > filter_vol
if condition and norm_vol > filter_vol and [Link]
false.draw_circle([Link](i * step), [Link](i * step))
width2 := width2 + 1
width2
if not na(pl) and norm_vol > filter_vol and [Link]
int n = bar_index - rightBars
float src = low[rightBars]
[Link] cp = [Link].from_index(n, src)
[Link](src.draw_level(n, width2, lower_col))
[Link](cp, textcolor = chart.fg_color, color = [Link](lower_col, 30), style =
label.style_circle, size = [Link])
[Link](cp, text = [Link](vol, [Link]), textcolor = chart.fg_color, color =
color(na), style = label.style_label_up)
// Check and update crosses
check_cross(levels)
// Clean up lines if levels are not shown
a_allLines = [Link]
if [Link](a_allLines) > 0 and not show_lvl
for i = 0 to [Link](a_allLines) - 1 by 1
[Link]([Link](a_allLines, i))
//
==================================================================================
===================================}
// 🔔 ALERT CONDITION — High volume surge
alertcondition(norm_vol > filter_vol, title = "High Volume Alert", message = "📈 High volume detected
at {{ticker}} on {{interval}}!")
// 🔔 ALERT CONDITION — Low volume dip
alertcondition(norm_vol < filter_vol, title = "Low Volume Alert", message = "📉 Low volume detected
at {{ticker}} on {{interval}}!")