Volumatic Variable Index Dynamic Average [BigBeluga] for ThinkOrSwim

samer800

Moderator - Expert
VIP
Lifetime
fnRbTYp.png


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
 

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