Author MEssage:
The Volumatic VIDYA (Variable Index Dynamic Average) indicator is a trend-following tool that calculates and visualizes both the current trend and the corresponding buy and sell pressure within each trend phase. Using the Variable Index Dynamic Average as the core smoothing technique, this indicator also plots volume levels of lows and highs based on market structure pivot points, providing traders with key insights into price and volume dynamics.
Additionally, it generates delta volume values to help traders evaluate buy-sell pressure balance during each trend, making it a powerful tool for understanding market sentiment shifts.
CODE:
CSS:
#// Indicator for TOS
#// © BigBeluga
#indicator("Volumatic Variable Index Dynamic Average [BigBeluga]", "Volumatic VIDYA [BigBeluga
# Converted by Sam4Cok@Samer800 - 10/2024
input showVolumeLabel = yes;
input showPivotLines = yes;
input source = close; # "Source") // Source for VIDYA calculation
input vidya_length = 10; # "VIDYA Length") // Length of the VIDYA calculation
input vidya_momentum = 20; # "VIDYA Momentum") // Momentum length for VIDYA
input band_distance = 2.0; # "Distance factor for upper/lower bands", step = 0.1)
input pivotLength = 3; # // Left side pivot bars
def na = Double.NaN;
def last = isNaN(close);
#// Define VIDYA (Variable Index Dynamic Average) function
Script vidya_calc {
input src = close;
input vidya_length = 20;
input vidya_momentum = 10;
def momentum = src - src[1];
def sum_pos_momentum = sum(if (momentum >= 0) then momentum else 0.0, vidya_momentum);
def sum_neg_momentum = sum(if (momentum >= 0) then 0.0 else -momentum, vidya_momentum);
def abs_cmo = AbsValue(100 * (sum_pos_momentum - sum_neg_momentum) / (sum_pos_momentum + sum_neg_momentum));
def alpha = 2 / (vidya_length + 1);
def vidya_value = alpha * abs_cmo / 100 * src + (1 - alpha * abs_cmo / 100) * vidya_value[1];
def smaVidya = Average(vidya_value, 15);
plot out = smaVidya;
}
Script Pivot {
input series = close;
input leftBars = 10;
input rightBars = 10;
input isHigh = yes;
def na = Double.NaN;
def HH = series == Highest(series, leftBars + 1);
def LL = series == Lowest(series, leftBars + 1);
def pivotRange = (leftBars + rightBars + 1);
def leftEdgeValue = if series[pivotRange] ==0 then na else series[pivotRange];
def pvtCond = leftBars > 0 and rightBars > 0 and !isNaN(leftEdgeValue);
def barIndexH = if pvtCond then
fold i = 1 to rightBars + 1 with p=1 while p do
series > GetValue(series, - i) else na;
def barIndexL = if pvtCond then
fold j = 1 to rightBars + 1 with q=1 while q do
series < GetValue(series, - j) else na;
def PivotPoint;
if isHigh {
PivotPoint = if HH and barIndexH then series else na;
} else {
PivotPoint = if LL and barIndexL then series else na;
}
plot pvt = PivotPoint;
}
#// CALCULATIONS
#// Calculate the Average True Range (ATR)
def atr_value = atr(Length = 200); # // ATR calculation with length of 200
#// Calculate the VIDYA (Variable Index Dynamic Average)
def vidya_value = vidya_calc(source, vidya_length, vidya_momentum);
#// Calculate upper and lower bands based on VIDYA and ATR
def upper_band = vidya_value + atr_value * band_distance;
def lower_band = vidya_value - atr_value * band_distance;
#// Detect trend direction using crossovers of source with bands
def crossUp = (source > upper_band) and (source[1] <= upper_band[1]);
def crossDn = (source < lower_band) and (source[1] >= lower_band[1]);
def is_trend_up = if crossUp then yes else if crossDn then no else is_trend_up[1];
def change = is_trend_up - is_trend_up[1];
#// Set trend-based smoothing variable
def smoothed_value = if change then na else
if !is_trend_up then upper_band else
if is_trend_up then lower_band else na;
#// Determine the color of the trend
def trend_col = if is_trend_up then 1 else
if !is_trend_up then -1 else 0;
#// Calculate pivot highs and lows for price action
def pivot_high = pivot(high[pivotLength], pivotLength, pivotLength, yes);
def pivot_low = pivot(close[pivotLength], pivotLength, pivotLength, no);
def pvtHi = !isNaN(pivot_high[-pivotLength]);
def pvtLo = !isNaN(pivot_low[-pivotLength]);
#// Create and store lines for pivot highs (resistance zones)
def price_level = if change then na else
if !is_trend_up then upper_band else
if is_trend_up then lower_band else price_level[1];
def cntUp; def cntUp1; def cntUp2; def cntUp3;
def volUp; def volUp1; def volUp2; def volUp3;
def pvtLineUp; def pvtLineUp1; def pvtLineUp2; def pvtLineUp3;
def isCrossUp = (price_level > pvtLineUp[1]);
def isCrossUp1 = (price_level > pvtLineUp1[1]) and (price_level[1] <= pvtLineUp1[1]);
def isCrossUp2 = (price_level > pvtLineUp2[1]) and (price_level[1] <= pvtLineUp2[1]);
def isCrossUp3 = (price_level > pvtLineUp3[1]) and (price_level[1] <= pvtLineUp3[1]);
if low > price_level and pvtLo {
cntUp3 = if cntUp3[1] > 50 then 0 else cntUp3[1];
cntUp2 = if cntUp2[1] > 50 then 0 else cntUp2[1];
cntUp1 = if cntUp1[1] > 50 then 0 else cntUp1[1];
cntUp = 0;
pvtLineUp3 = pvtLineUp2[1];
pvtLineUp2 = pvtLineUp1[1];
pvtLineUp1 = pvtLineUp[1];
pvtLineUp = low;
volUp3 = volUp2[1];
volUp2 = volUp1[1];
volUp1 = volUp[1];
volUp = Average(volume, pivotLength + pivotLength);
} else {
cntUp3 = if cntUp3[1] > 50 then 0 else cntUp3[1] + 1;
cntUp2 = if cntUp2[1] > 50 then 0 else cntUp2[1] + 1;
cntUp1 = if cntUp1[1] > 50 then 0 else cntUp1[1] + 1;
cntUp = cntUp[1] + 1;
pvtLineUp3 = if (isCrossUp3 or cntUp3 > 50) then na else pvtLineUp3[1];
pvtLineUp2 = if (isCrossUp2 or cntUp2 > 50) then na else pvtLineUp2[1];
pvtLineUp1 = if (isCrossUp1 or cntUp1 > 50) then na else pvtLineUp1[1];
pvtLineUp = if (isCrossUp or cntUp > 50) then na else pvtLineUp[1];
volUp3 = volUp3[1];
volUp2 = volUp2[1];
volUp1 = volUp1[1];
volUp = volUp[1];
}
def cntDn; def cntDn1; def cntDn2; def cntDn3;
def volDn; def volDn1; def volDn2; def volDn3;
def pvtLineDn; def pvtLineDn1; def pvtLineDn2; def pvtLineDn3;
def isCrossDn = (price_level < pvtLineDn[1]) and (price_level[1] >= pvtLineDn[1]);
def isCrossDn1 = (price_level < pvtLineDn1[1]) and (price_level[1] >= pvtLineDn1[1]);
def isCrossDn2 = (price_level < pvtLineDn2[1]) and (price_level[1] >= pvtLineDn2[1]);
def isCrossDn3 = (price_level < pvtLineDn3[1]) and (price_level[1] >= pvtLineDn3[1]);
if high < price_level and pvtHi {
cntDn3 = if cntDn3[1] > 50 then 0 else cntDn3[1];
cntDn2 = if cntDn2[1] > 50 then 0 else cntDn2[1];
cntDn1 = if cntDn1[1] > 50 then 0 else cntDn1[1];
cntDn = 0;
pvtLineDn3 = pvtLineDn2[1];
pvtLineDn2 = pvtLineDn1[1];
pvtLineDn1 = pvtLineDn[1];
pvtLineDn = high;
volDn3 = volDn2[1];
volDn2 = volDn1[1];
volDn1 = volDn[1];
volDn = Average(-volume, pivotLength + pivotLength);
} else {
cntDn3 = if cntDn3[1] > 50 then 0 else cntDn3[1] + 1;
cntDn2 = if cntDn2[1] > 50 then 0 else cntDn2[1] + 1;
cntDn1 = if cntDn1[1] > 50 then 0 else cntDn1[1] + 1;
cntDn = cntDn[1] + 1;
pvtLineDn3 = if (isCrossDn3 or cntDn3 > 50) then na else pvtLineDn3[1];
pvtLineDn2 = if (isCrossDn2 or cntDn2 > 50) then na else pvtLineDn2[1];
pvtLineDn1 = if (isCrossDn1 or cntDn1 > 50) then na else pvtLineDn1[1];
pvtLineDn = if (isCrossDn or cntDn > 50) then na else pvtLineDn[1];
volDn3 = volDn3[1];
volDn2 = volDn2[1];
volDn1 = volDn1[1];
volDn = volDn[1];
}
plot crossVolDn = if isCrossDn [-1] then pvtLineDn else na;
plot crossVolDn1 = if isCrossDn1[-1] then pvtLineDn1 else na;
plot crossVolDn2 = if isCrossDn2[-1] then pvtLineDn2 else na;
plot crossVolDn3 = if isCrossDn3[-1] then pvtLineDn3 else na;
plot crossVolUp = if isCrossUp [-1] then pvtLineUp else na;
plot crossVolUp1 = if isCrossUp1[-1] then pvtLineUp1 else na;
plot crossVolUp2 = if isCrossUp2[-1] then pvtLineUp2 else na;
plot crossVolUp3 = if isCrossUp3[-1] then pvtLineUp3 else na;
crossVolDn.SetLineWeight(2);
crossVolDn1.SetLineWeight(2);
crossVolDn2.SetLineWeight(2);
crossVolDn3.SetLineWeight(2);
crossVolDn.SetDefaultColor(Color.RED);
crossVolDn1.SetDefaultColor(Color.RED);
crossVolDn2.SetDefaultColor(Color.RED);
crossVolDn3.SetDefaultColor(Color.RED);
crossVolDn.SetPaintingStrategy(paintingStrategy.SQUARES);
crossVolDn1.SetPaintingStrategy(paintingStrategy.SQUARES);
crossVolDn2.SetPaintingStrategy(paintingStrategy.SQUARES);
crossVolDn3.SetPaintingStrategy(paintingStrategy.SQUARES);
crossVolUp.SetLineWeight(2);
crossVolUp1.SetLineWeight(2);
crossVolUp2.SetLineWeight(2);
crossVolUp3.SetLineWeight(2);
crossVolUp.SetDefaultColor(Color.GREEN);
crossVolUp1.SetDefaultColor(Color.GREEN);
crossVolUp2.SetDefaultColor(Color.GREEN);
crossVolUp3.SetDefaultColor(Color.GREEN);
crossVolUp.SetPaintingStrategy(paintingStrategy.SQUARES);
crossVolUp1.SetPaintingStrategy(paintingStrategy.SQUARES);
crossVolUp2.SetPaintingStrategy(paintingStrategy.SQUARES);
crossVolUp3.SetPaintingStrategy(paintingStrategy.SQUARES);
AddChartBubble(showVolumeLabel and !isCrossDn and isCrossDn [-1], pvtLineDn,Round(volDn /1000000,2)+"M",Color.RED);
AddChartBubble(showVolumeLabel and !isCrossDn1 and isCrossDn1[-1],pvtLineDn1,Round(volDn1/1000000,2)+"M",Color.RED);
AddChartBubble(showVolumeLabel and !isCrossDn2 and isCrossDn2[-1],pvtLineDn2,Round(volDn2/1000000,2)+"M",Color.RED);
AddChartBubble(showVolumeLabel and !isCrossDn3 and isCrossDn3[-1],pvtLineDn3,Round(volDn3/1000000,2)+"M",Color.RED);
AddChartBubble(showVolumeLabel and !isCrossUp and isCrossUp [-1], pvtLineUp,Round(volUp /1000000,2)+"M",Color.GREEN,no);
AddChartBubble(showVolumeLabel and !isCrossUp1 and isCrossUp1[-1],pvtLineUp1,Round(volUp1/1000000,2)+"M",Color.GREEN,no);
AddChartBubble(showVolumeLabel and !isCrossUp2 and isCrossUp2[-1],pvtLineUp2,Round(volUp2/1000000,2)+"M",Color.GREEN,no);
AddChartBubble(showVolumeLabel and !isCrossUp3 and isCrossUp3[-1],pvtLineUp3,Round(volUp3/1000000,2)+"M",Color.GREEN,no);
#// Detect changes in the trend direction
def trend_cross_up = !is_trend_up[1] and is_trend_up;
def trend_cross_dn = !is_trend_up and is_trend_up[1];
#// Reset volume counters when trend changes
def up_trend_volume; def down_trend_volume;
if (trend_cross_up - trend_cross_up[1]) or (trend_cross_dn - trend_cross_dn[1]) {
up_trend_volume = 0;
down_trend_volume = 0;
} else if !((trend_cross_up - trend_cross_up[1]) or (trend_cross_dn - trend_cross_dn[1])) {
up_trend_volume = up_trend_volume[1] + (if close > open then volume else 0);
down_trend_volume = down_trend_volume[1] + (if close < open then volume else 0);
} else {
up_trend_volume = up_trend_volume[1];
down_trend_volume = down_trend_volume[1];
}
#// Calculate average volume
def avg_volume_delta = if !last then (up_trend_volume + down_trend_volume) / 2 else avg_volume_delta[1];
def deltaVol = (up_trend_volume - down_trend_volume) / avg_volume_delta;
def delta_volume = if isNaN(deltaVol) then 0 else deltaVol;
#// Plot trend change markers (up and down arrows)
plot trendUp = if trend_cross_up[1] then smoothed_value[0] else na;
plot trendDn = if trend_cross_dn[1] then smoothed_value[0] else na;
plot smoothedValue = if smoothed_value then smoothed_value else na;
trendUp.SetLineWeight(3);
trendDn.SetLineWeight(3);
trendUp.SetDefaultColor(Color.CYAN);
trendDn.SetDefaultColor(Color.MAGENTA);
trendUp.SetPaintingStrategy(PaintingStrategy.POINTS);
trendDn.SetPaintingStrategy(PaintingStrategy.POINTS);
smoothedValue.SetLineWeight(2);
smoothedValue.AssignValueColor(if trend_col>0 then Color.CYAN else
if trend_col<0 then Color.MAGENTA else Color.GRAY);
plot LineUp = if showPivotLines and !last and pvtLineUp then pvtLineUp else na;
plot LineUp1 = if showPivotLines and !last and pvtLineUp1 then pvtLineUp1 else na;
plot LineUp2 = if showPivotLines and !last and pvtLineUp2 then pvtLineUp2 else na;
plot LineUp3 = if showPivotLines and !last and pvtLineUp3 then pvtLineUp3 else na;
plot LineDn = if showPivotLines and !last and pvtLineDn then pvtLineDn else na;
plot LineDn1 = if showPivotLines and !last and pvtLineDn1 then pvtLineDn1 else na;
plot LineDn2 = if showPivotLines and !last and pvtLineDn2 then pvtLineDn2 else na;
plot LineDn3 = if showPivotLines and !last and pvtLineDn3 then pvtLineDn3 else na;
LineUp.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
LineUp1.SetPaintingStrategy(PaintingStrategy.DASHES);
LineUp2.SetPaintingStrategy(PaintingStrategy.DASHES);
LineUp3.SetPaintingStrategy(PaintingStrategy.DASHES);
LineUp.SetDefaultColor(Color.GREEN);
LineUp1.SetDefaultColor(Color.GREEN);
LineUp2.SetDefaultColor(Color.GREEN);
LineUp3.SetDefaultColor(Color.GREEN);
LineDn.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
LineDn1.SetPaintingStrategy(PaintingStrategy.DASHES);
LineDn2.SetPaintingStrategy(PaintingStrategy.DASHES);
LineDn3.SetPaintingStrategy(PaintingStrategy.DASHES);
LineDn.SetDefaultColor(Color.RED);
LineDn1.SetDefaultColor(Color.RED);
LineDn2.SetDefaultColor(Color.RED);
LineDn3.SetDefaultColor(Color.RED);
AddLabel(1, AsPercent(delta_volume), if delta_volume>0 then Color.GREEN else
if delta_volume<0 then Color.RED else Color.GRAY);
AddLabel(1, "BUY("+Round(up_trend_volume/1000000, 2)+"M)", Color.CYAN);
AddLabel(1, "SELL("+Round(down_trend_volume/1000000, 2)+"M)", Color.MAGENTA);
AddCloud(ohlc4 - (ohlc4 - smoothedValue) / 2, smoothedValue, CreateColor(0, 100, 100), Color.PLUM);
#-- END of CODE