```
declare lower;
input overBought = -20;
input overSold = -80;
input MAlength = 21;
input price = close;
input ChartBubblesOn = no;
plot WAD = AccumDistBuyPr();
WAD.SetDefaultColor(GetColor(1));
plot VMA = Average(WAD, MAlength);
VMA.SetDefaultColor(GetColor(0));
def WADDownCross = Crosses(( WAD < 0) != 0, 0.5, yes );
plot SignalDn = if WADDownCross then VMA else Double.NaN;
SignalDn.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);
SignalDn.SetDefaultColor(Color.DOWNTICK);
SignalDn.SetLineWeight(5);
def WADUpCross = Crosses(( WAD > 0) != 0, 0.5, yes );
plot SignalUp = if WADUpCross then VMA else Double.NaN;
SignalUp.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
SignalUp.SetDefaultColor(Color.UPTICK);
SignalUp.SetLineWeight(5);
AddCloud(WAD, VMA, Color.UPTICK);
def VMAUpCross = Crosses((VMA > WAD) != 0, 0.5, no );# && VMAUpCross
#rec flip = if VMAUpCross == VMAUpCross[1] then 0 else 1;
plot ArrowUp = if VMAUpCross then VMA else Double.NaN;
ArrowUp.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
ArrowUp.SetDefaultColor(Color.CYAN);
def VMADnCross = Crosses((VMA < WAD) != 0, 0.5, no );# && VMAUpCross
#rec flop = if VMADnCross or flop then 1 else 0;
plot ArrowDn = if VMADnCross then VMA else Double.NaN;
ArrowDn.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);
ArrowDn.SetDefaultColor(Color.YELLOW);
def relativeVMA = Round((VMA - LowestAll(VMA)) / (HighestAll(VMA) - LowestAll(VMA)), 2) * 100;
AddLabel(yes, Concat( Round(relativeVMA, 2), Concat("", "%")), if relativeVMA > 80 then Color.RED else if relativeVMA < 20 then Color.GREEN else Color.GRAY );
def tmp1 = if price > price[1] then price - price[1] else 0;
def tmp2 = if price[1] > price then price[1] - price else 0;
def d2 = Sum(tmp1, MAlength);
def d4 = Sum(tmp2, MAlength);
def cond = d2 + d4 == 0;
def ad3 = if cond then 0 else (d2 - d4) / (d2 + d4) * 100;
def coeff = 2 / (MAlength + 1) * AbsValue(ad3) / 100;
def asd = CompoundValue("visible data" = coeff * price + (if IsNaN(asd[1]) then 0 else asd[1]) * (1 - coeff), "historical data" = price);
VMA.SetDefaultColor(GetColor(0));
def vwma8 = Sum(volume * close, 8) / Sum(volume, 8);
def vwma21 = Sum(volume * close, 21) / Sum(volume, 21);
def vwma34 = Sum(volume * close, 34) / Sum(volume, 34);
def bullish = if vwma8 > vwma21 and vwma21 > vwma34 then 1 else 0;
def bearish = if vwma8 < vwma21 and vwma21 < vwma34 then 1 else 0;
def distribution = if !bullish and !bearish then 1 else 0;
AddLabel (yes, if bullish then "Stage: Acceleration" else if bearish then "Stage: Deceleration" else if close >= VMA then "Stage: Accumulation" else "stage: Distribution", if bullish then Color.GREEN else if bearish then Color.RED else if close >= VMA then Color.YELLOW else Color.ORANGE);
VMA.AssignValueColor(if bearish then Color.RED else if bullish and close >= VMA then Color.GREEN else Color.GRAY);
def accumulationToAcceleration = if (bullish and close >= VMA) then 1 else 0;
AddChartBubble(ChartBubblesOn and accumulationToAcceleration and !accumulationToAcceleration[1], close, "Entering Acceleration", Color.GREEN);
def distributionToDeceleration = if (bearish and close <= VMA) then 1 else 0;
AddChartBubble(ChartBubblesOn and distributionToDeceleration and !distributionToDeceleration[1], close, "Entering Deceleration", Color.RED);
```