Author Message:
his is an experimental study inspired by the Quantitative Qualitative Estimation indicator designed to identify trend and wave activity.
In this study, rather than using RSI for the calculation, the Dual Volume Divergence Index oscillator is utilized.
First, the DVDI oscillator is calculated by taking the difference between PVI and its EMA , and NVI and its EMA , then taking the difference between the two results.
Optional parameters for DVDI calculation are included within this script:
- An option to use tick volume rather than real volume for the volume source
- An option to use cumulative data, which sums the movements of the oscillator from the beginning to the end of TradingView's maximum window to give a more broad picture of market sentiment
Next, two trailing levels are calculated using the average true range of the oscillator. The levels are then used to determine wave direction.
Lastly, rather than using 0 as the center line, it is instead calculated by taking a cumulative average of the oscillator.
Custom bar colors are included.
MTF option added -
CODE - 05/2024
CSS:
#//@version=4
#study("Dual Volume Divergence Index Quantitative Qualitative Estimation [DW]", shorttitle="DVDIQQE [DW]", overlay=false)
#//by Donovan Wall
# Converted by Sam4Cok@Samer800 - 12/2022
# updated by Sam4Cok@Samer800 - 05/2024 - Added MTF option, minor bug fix
declare lower;
#//Source
input timeframe = {Default "Chart", "Manual"};
input manualTimeframe = AggregationPeriod.FIFTEEN_MIN;
input BarColor = yes;
input centerLineType = {"Static", Default "Dynamic"}; # "Center Line Type"
input VolumeType = {default "Normal", "Tick"}; # "Volume Type"
input source = FundamentalType.CLOSE;
input SamplingPeriod = 13; # "Sampling Period"
input SmoothingPeriod = 6; # "Smoothing Period"
input FastTrailingLevelRangeMultiplier = 2.618; # "Fast Trailing Level Range Multiplier"
input SlowTrailingLevelRangeMultiplier = 4.236; # "Slow Trailing Level Range Multiplier"
#---- Calc
def na = Double.NaN;
def last = isNaN(close);
def Dynamic = centerLineType==centerLineType."Dynamic";
def src; def vol; def clo; def ope;
Switch (timeframe) {
Case "Manual" :
src = Fundamental(FundamentalType = source, Period = manualTimeframe);
vol = volume(Period = manualTimeframe);
clo = close(Period = manualTimeframe);
ope = open(Period = manualTimeframe);
Default :
src = Fundamental(FundamentalType = source);
vol = volume;
clo = close;
ope = open;
}
def rng = clo - ope;
#--- Color
DefineGlobalColor("exHi", CreateColor(5,255,166));
DefineGlobalColor("Hi" , CreateColor(0,148,95));
DefineGlobalColor("exLo", CreateColor(255,10,112));
DefineGlobalColor("Lo" , CreateColor(153,0,64));
DefineGlobalColor("norm" , CreateColor(204, 204, 204));
DefineGlobalColor("Blue5" , CreateColor(17,231,242));
##### Script
#EMA(x, t)=>
script EMA {
input x = close;
input t = 10;
def EMA = CompoundValue(1, (x - EMA[1]) * (2/(t + 1)) + EMA[1], x);
plot return = EMA;
}
#//Dual Volume Divergence Index Function
#DVDI(x, t1, t2, v_type)=>
script DVDI {
input x = close;
input t1 = 0;
input t2 = 0;
input v_type = "Normal";
input nzVol = volume;
input rng = 1;
def tick = TickSize();
def tickrng = if isNaN(tickrng[1]) or tickrng[1]==0 then tick else
If AbsValue(rng) < tick then tickrng[1] else rng;
def tivol = AbsValue(tickrng) / tick;
def tickvol = if isNaN(tivol) then 0 else tivol;
def vol = If(v_type == "Normal", (If(IsNaN(nzVol) or nzVol==0, tickvol, nzVol)), tickvol);
def PVI = CompoundValue(1, if vol > vol[1] then PVI[1] + (x - x[1]) else PVI[1], 0);
def psig = EMA(PVI, t1);
def pdiv = EMA(PVI - psig, t2);
def NVI = CompoundValue(1, if vol < vol[1] then NVI[1] - (x - x[1]) else NVI[1], 0);
def nsig = EMA(NVI, t1);
def ndiv = EMA(NVI - nsig, t2);
def DVDI = pdiv - ndiv;
plot Return = if isNaN(DVDI) then 0 else DVDI;
}
#//Trailing Level Function
script tl {
input x = close;
input t = 13;
input m = 2.618;
def wper = (t * 2) - 1;
def rng = AbsValue(x - x[1]);
def avrng = EMA(rng, wper);
def smrng = EMA(avrng, wper) * m;
def tl = CompoundValue(1, if x > tl[1] then (if (x - smrng) < tl[1] then tl[1] else (x - smrng)) else
(if (x + smrng) > tl[1] then tl[1] else (x + smrng)), x);
plot return = if isNaN(tl) then x else tl;
}
#//Cumulative Average Function
script cmean {
input x = close;
def xsum = CompoundValue(1, xsum[1] + x, x);
def tsum = CompoundValue(1, tsum[1] + 1, 1);
def cmean = xsum / tsum;
plot return = cmean;
}
#//DVDI Oscillator
def dvdi = DVDI(src, SamplingPeriod, SmoothingPeriod, VolumeType, vol, rng);
#//Trailing Levels
def ftl = tl(dvdi, SamplingPeriod, FastTrailingLevelRangeMultiplier);
def stl = tl(dvdi, SamplingPeriod, SlowTrailingLevelRangeMultiplier);
#//Center Line
def mean = cmean(dvdi);
def center = if Dynamic then mean else 0;
#//Colors
def dcolor = if (dvdi > ftl) and (dvdi > stl) and (dvdi > center) then 2 else
if (dvdi < ftl) and (dvdi < stl) and (dvdi > center) then 1 else
if (dvdi < ftl) and (dvdi < stl) and (dvdi < center) then -2 else
if (dvdi > ftl) and (dvdi > stl) and (dvdi < center) then -1 else 0;
#//Trailing Level Plots
plot stlplot = if last then na else stl; # "Slow Trailing Level"
plot ftlplot = if last then na else ftl; # "Fast Trailing Level"
stlplot.SetPaintingStrategy(PaintingStrategy.DASHES);
ftlplot.SetPaintingStrategy(PaintingStrategy.DASHES);
stlplot.SetDefaultColor(Color.WHITE); #MAGENTA);
ftlplot.SetDefaultColor(Color.GRAY); #CYAN);
#//Trailing Levels Fill
AddCloud(ftlplot, stlplot, Color.DARK_ORANGE, Color.DARK_ORANGE); # "Trailing Zone Fill"
#//Center Line Plot
plot centerplot = if last then na else center; # "Center Line"
centerplot.AssignValueColor(if center > center[1] then GlobalColor("exHi") else
if center < center[1] then GlobalColor("exLo") else Color.DARK_GRAY);
#//DVDI Oscillator Plot
plot dvdiLine = if last then na else dvdi;
#plot dvdiplot = if last then na else (dvdi - center); #"DVDI Oscillator"
dvdiLine.SetLineWeight(2);
dvdiLine.AssignValueColor(if dcolor== 2 then GlobalColor("exHi") else
if dcolor== 1 then GlobalColor("Hi") else
if dcolor==-2 then GlobalColor("exLo") else
if dcolor==-1 then GlobalColor("Lo") else Color.GRAY);
AddCloud(if (dcolor== 2 or dcolor[-1]== 2) then dvdiLine else na, centerplot, Color.GREEN);
AddCloud(if (dcolor== 1 or dcolor[-1]== 1) then dvdiLine else na, centerplot, Color.DARK_GREEN);
AddCloud(if (dcolor==-2 or dcolor[-1]==-2) then centerplot else na, dvdiLine, Color.RED);
AddCloud(if (dcolor==-1 or dcolor[-1]==-1) then centerplot else na, dvdiLine, Color.DARK_RED);
AddCloud(if (dcolor== 0 or dcolor[-1]== 0) then centerplot else na, dvdiLine, Color.GRAY, Color.GRAY);
#dvdiplot.SetHiding(!ShowHistogram);
#dvdiplot.SetPaintingStrategy(PaintingStrategy.SQUARED_HISTOGRAM);
#dvdiplot.AssignValueColor(if dcolor==2 then GlobalColor("exHi") else
# if dcolor==1 then GlobalColor("Hi") else
# if dcolor==-2 then GlobalColor("exLo") else
# if dcolor==-1 then GlobalColor("Lo") else Color.GRAY);
#dvdiplot.SetLineWeight(3);
#//----DVDI Fill
#AddCloud(centerplot,0, Color.GRAY, Color.GRAY);
#//Bar Color
AssignPriceColor(if !BarColor then Color.CURRENT else
if dcolor==2 then GlobalColor("exHi") else
if dcolor==1 then GlobalColor("Hi") else
if dcolor==-2 then GlobalColor("exLo") else
if dcolor==-1 then GlobalColor("Lo") else Color.GRAY);
#---END CODE
CODE - 12/2022:
CSS:
#//@version=4
#study("Dual Volume Divergence Index Quantitative Qualitative Estimation [DW]", shorttitle="DVDIQQE [DW]", overlay=false)
#//by Donovan Wall
# Converted by Sam4Cok@Samer800 - 12/2022
declare lower;
#//Source
input BarColor = yes;
input ShowHistogram = yes;
input src = close;
input per = 13; # "Sampling Period"
input smper = 6; # "Smoothing Period"
input fmult = 2.618; # "Fast Trailing Level Range Multiplier"
input smult = 4.236; # "Slow Trailing Level Range Multiplier"
input center_type = {Default Static, Dynamic}; # "Center Line Type"
input vol_type = {default Normal, Tick}; # "Volume Type"
#---- Calc
def na = Double.NaN;
#--- Color
DefineGlobalColor("exHi", CreateColor(5,255,166));
DefineGlobalColor("Hi" , CreateColor(0,148,95));
DefineGlobalColor("exLo", CreateColor(255,10,112));
DefineGlobalColor("Lo" , CreateColor(153,0,64));
DefineGlobalColor("Blue5" , CreateColor(17,231,242));
##### Script
script nz {
input data = 0;
input replacement = 0;
def ret_val = if IsNaN(data) then replacement else data;
plot return = ret_val;
}
#EMA(x, t)=>
script EMA {
input x = close;
input t = 10;
def EMA;
EMA = if(isNaN(EMA[1]) or EMA[1]==0, x , (x - EMA[1])*(2/(t + 1)) + EMA[1]);
plot return = EMA;
}
#//Dual Volume Divergence Index Function
#DVDI(x, t1, t2, v_type)=>
script DVDI {
input x = close;
input t1 = 0;
input t2 = 0;
input v_type = "Normal";
def tick = TickValue();
def rng = close - open;
def tickrng;
tickrng = if isNaN(tickrng[1]) or tickrng[1]==0 then tick else
If(AbsValue(rng) < tick, tickrng[1], rng);
def tickvol = AbsValue(tickrng) / tick;
def vol = If(v_type == "Normal", (If(IsNaN(volume) or volume==0, tickvol, volume)), tickvol);
def PVI;
PVI = If(vol > nz(vol[1],vol), PVI[1] + (x - nz(x[1],x)), PVI[1]);
def psig = EMA(PVI, t1);
def pdiv = EMA(PVI - psig, t2);
def NVI;
NVI = If(vol < nz(vol[1],vol), NVI[1] - (x - nz(x[1],x)), NVI[1]);
def nsig = EMA(NVI, t1);
def ndiv = EMA(NVI - nsig, t2);
def DVDI = pdiv - ndiv;
plot Return = DVDI;
}
#//Trailing Level Function
script tl {
input x = close;
input t = 13;
input m = 2.618;
def wper = (t*2) - 1;
def rng = AbsValue(x - x[1]);
def avrng = EMA(rng, wper);
def smrng = EMA(avrng, wper)*m;
def tl;
tl = if(x > nz(tl[1],x),(if((x - smrng) < nz(tl[1],x), nz(tl[1],x), (x - smrng))),
(if((x + smrng) > nz(tl[1],x), nz(tl[1],x), (x + smrng))));
plot return = tl;
}
#//Cumulative Average Function
script cmean {
input x = close;
def xsum;
xsum = nz(xsum[1]) + x;
def tsum;
tsum = nz(tsum[1]) + 1;
def cmean = xsum/tsum;
plot return = cmean;
}
#//DVDI Oscillator
def dvdi = DVDI(src, per, smper, vol_type);
#//Trailing Levels
def ftl = tl(dvdi, per, fmult);
def stl = tl(dvdi, per, smult);
#//Center Line
def center = if(center_type==center_type.Dynamic,cmean(dvdi),if(isNaN(close),na,0));
#//Colors
def dcolor = if (dvdi > ftl) and (dvdi > stl) and (dvdi > center) then 2 else
if (dvdi < ftl) and (dvdi < stl) and (dvdi > center) then 1 else
if (dvdi < ftl) and (dvdi < stl) and (dvdi < center) then -2 else
if (dvdi > ftl) and (dvdi > stl) and (dvdi < center) then -1 else 0;
def ccolor = if center > center[1] then 1 else
if center < center[1] then -1 else 0;
#//Trailing Level Plots
plot stlplot = stl; # "Slow Trailing Level"
stlplot.SetDefaultColor(Color.MAGENTA);
plot ftlplot = ftl; # "Fast Trailing Level"
ftlplot.SetDefaultColor(Color.CYAN);
#//Trailing Levels Fill
AddCloud(ftlplot, stlplot, Color.CYAN, Color.MAGENTA); # "Trailing Zone Fill"
#//Center Line Plot
plot centerplot = center; # "Center Line"
centerplot.AssignValueColor(if ccolor>0 then Color.GREEN else
if ccolor<0 then Color.RED else Color.DARK_GRAY);
#//DVDI Oscillator Plot
plot dvdiplot = dvdi; #"DVDI Oscillator"
dvdiplot.SetLineWeight(2);
dvdiplot.SetHiding(!ShowHistogram);
dvdiplot.SetPaintingStrategy(PaintingStrategy.HISTOGRAM);
dvdiplot.AssignValueColor(if dcolor==2 then GlobalColor("exHi") else
if dcolor==1 then GlobalColor("Hi") else
if dcolor==-2 then GlobalColor("exLo") else
if dcolor==-1 then GlobalColor("Lo") else Color.GRAY);
dvdiplot.SetLineWeight(3);
#//----DVDI Fill
AddCloud(centerplot,0, Color.GRAY, Color.GRAY);
#//Bar Color
AssignPriceColor(if !BarColor then Color.CURRENT else
if dcolor==2 then GlobalColor("exHi") else
if dcolor==1 then GlobalColor("Hi") else
if dcolor==-2 then GlobalColor("exLo") else
if dcolor==-1 then GlobalColor("Lo") else Color.GRAY);
#---END CODE
Last edited: