# Volume Zone Oscillator (VZO) For ThinkOrSwim

#### BenTen

Staff member
Staff
VIP
This is based on the Volume Zone Oscillator. Here is the modified code.

Code:
``````input length = 14;

def VP = expAverage(Sign(close - close[1]) * volume, length);
def TV = expAverage(volume, length);

def VZO = 100 * VP / TV;
plot VZO_DOTS = 100 * VP / TV;
plot "+60" = 60;
plot "+40" = 40;
#plot "+15" = 15;
#plot "-5" = -5;
plot "-40" = -40;
plot "-60" = -60;
plot ZeroLine = 0;

VZO.SetDefaultColor(GetColor(1));
"+60".SetDefaultColor(GetColor(6));
"+40".SetDefaultColor(GetColor(6));
#"+15".SetDefaultColor(GetColor(3));
#"-5".SetDefaultColor(GetColor(3));
"-40".SetDefaultColor(GetColor(5));
"-60".SetDefaultColor(GetColor(5));
ZeroLine.SetDefaultColor(GetColor(4));

def EMA60 = ExpAverage(close, 60);

def trendExistence = ADX > 18;
#1 - crosses above EMA60, 2 - above EMA60, 3 - crossing below EMA60, 4 - below EMA60
def direction = if close > EMA60 and close[1] <= EMA60 then 1 else if close > EMA60 and close[1] >= EMA60 then 2 else if close < EMA60 and close[1] >= EMA60 then 3 else 4;

def bullishCrossover = if VZO >= 40 and VZO[1] < 40 then 1 else 0;
def bearishCrossover = if VZO <= -40 and VZO[1] > -40 then 1 else 0;

VZO_DOTS.SetPaintingStrategy(PaintingStrategy.POINTS);
VZO_DOTS.AssignValueColor(if VZO > 15 then color.green else if VZO > -5 then color.yellow else color.red);
VZO_DOTS.SetLineWeight(3);``````

Last edited by a moderator:
I am interested in adding a sma to the Volume Zone Oscillator, any suggestions is greatly appreciated

plot vzoavg = simpleMovingAvg(vzo);

or

plot vzoavg = ExpAverage(vzo);

plot vzoavg = simpleMovingAvg(vzo);

or

plot vzoavg = ExpAverage(vzo);
Wow, much simpler than I thought. Thanks Horserider

Volume Zone Oscillator & Price Zone Oscillator
Here is a binary indicator that shows 5 MTF of the Price Zone Oscillator on top and a Volume Zone Oscillator on the bottom. Green bullish, Red Bearish, lower time frame on the bottom Higher time frame on top

Here is the code

Code:
``````##########################
Declare Lower;
# GLOBAL DEFINITIONS

DefineGlobalColor("TrendUp", CreateColor(0, 254, 30));
DefineGlobalColor("TrendDown", CreateColor(255, 3, 2));

input agg = AggregationPeriod.FIVE_MIN;
input agg2 = AggregationPeriod.THIRTY_MIN;
input agg3 = AggregationPeriod.HOUR;
input agg4 = AggregationPeriod.TWO_Hours;;
input agg5 = AggregationPeriod.FOUR_HOURs;
input DotSize = 5;
input n = 11;
def n1  = n + 1;
input length = 14;

#Aggregation 1
def V = Volume(Period = AGG);
def C = Close(Period =AGG);
def VP = ExpAverage(Sign(C - C[1]) * V, length);
def TV = ExpAverage(V, length);
def VZO = 100 * VP / TV;
plot VZO_Dot = if IsNaN(c) then Double.NaN else 1;
VZO_Dot.SetPaintingStrategy(PaintingStrategy.TRIANGLES);
VZO_Dot.SetLineWeight(DotSize);
VZO_Dot.AssignValueColor(if 0 > VZO then GlobalColor("TrendDown") else GlobalColor("TrendUp"));
AddChartBubble(!IsNaN(c [n1]) and IsNaN(C [n]), 1, (agg/1000/60) + " min", Color.Yellow, yes);

#Aggregation 2
def V2 = Volume(Period = AGG2);
def C2 = Close(Period =AGG2);
def VP2 = ExpAverage(Sign(C2 – C2[1]) * V2, length);
def TV2 = ExpAverage(V2, length);
def VZO2 = 100 * VP2 / TV2;
plot VZO2_Dot = if IsNaN(c2) then Double.NaN else 2;
VZO2_Dot.SetPaintingStrategy(PaintingStrategy.TRIANGLES);
VZO2_Dot.SetLineWeight(DotSize);
VZO2_Dot.AssignValueColor(if 0 > VZO2 then GlobalColor("TrendDown") else GlobalColor("TrendUp"));
AddChartBubble(!IsNaN(c2 [n1]) and IsNaN(C2 [n]), 2, (agg2/1000/60) + " min", Color.Yellow, yes);
#Aggregation 3
def V3 = Volume(Period = AGG3);
def C3 = Close(Period =AGG3);
def VP3 = ExpAverage(Sign(C3 – C3[1]) * V3, length);
def TV3 = ExpAverage(V3, length);
def VZO3 = 100 * VP3 / TV3;
plot VZO3_Dot = if IsNaN(c3) then Double.NaN else 3;
VZO3_Dot.SetPaintingStrategy(PaintingStrategy.TRIANGLES);
VZO3_Dot.SetLineWeight(DotSize);
VZO3_Dot.AssignValueColor(if 0 > VZO3 then GlobalColor("TrendDown") else GlobalColor("TrendUp"));
AddChartBubble(!IsNaN(c3 [n1]) and IsNaN(C3 [n]), 3, (agg3/1000/60) + " min", Color.Yellow, yes);
#Aggregation 4
def V4 = Volume(Period = AGG4);
def C4 = Close(Period =AGG4);
def VP4 = ExpAverage(Sign(C4 – C4[1]) * V4, length);
def TV4 = ExpAverage(V4, length);
def VZO4 = 100 * VP4 / TV4;
plot VZO4_Dot = if IsNaN(c4) then Double.NaN else 4;
VZO4_Dot.SetPaintingStrategy(PaintingStrategy.TRIANGLES);
VZO4_Dot.SetLineWeight(DotSize);
VZO4_Dot.AssignValueColor(if 0 > VZO4 then GlobalColor("TrendDown") else GlobalColor("TrendUp"));
AddChartBubble(!IsNaN(c4 [n1]) and IsNaN(C4 [n]), 4, (agg4/1000/60) + " min", Color.Yellow, yes);
#Aggregation 5
def V5 = Volume(Period = AGG5);
def C5 = Close(Period =AGG5);
def VP5 = ExpAverage(Sign(C5 – C5[1]) * V5, length);
def TV5 = ExpAverage(V5, length);
def VZO5 = 100 * VP5 / TV5;
plot VZO5_Dot = if IsNaN(c5) then Double.NaN else 5;
VZO5_Dot.SetPaintingStrategy(PaintingStrategy.TRIANGLES);
VZO5_Dot.SetLineWeight(DotSize);
VZO5_Dot.AssignValueColor(if 0 > VZO5 then GlobalColor("TrendDown") else GlobalColor("TrendUp"));
AddChartBubble(!IsNaN(c5 [n1]) and IsNaN(C5 [n]), 5, (agg5/1000/60) + " min", Color.Yellow, yes);

#Aggregation 1
def CP = ExpAverage(Sign(C - C[1]) * C, length);
def TC = ExpAverage(C, length);
def PZO = 100 * CP / TC;
plot PZO_Dot = if IsNaN(c) then Double.NaN else 7;
PZO_Dot.SetPaintingStrategy(PaintingStrategy.POINTS);
PZO_Dot.SetLineWeight(DotSize);
PZO_Dot.AssignValueColor(if 0 > PZO then GlobalColor("TrendDown") else GlobalColor("TrendUp"));
AddChartBubble(!IsNaN(c [n1]) and IsNaN(C [n]), 7, (agg/1000/60) + " min", Color.Yellow, yes);

#Aggregation 2
def CP2 = ExpAverage(Sign(C2 – C2[1]) * C2, length);
def TC2 = ExpAverage(C2, length);
def PZO2 = 100 * CP2 / TC2;
plot PZO2_Dot = if IsNaN(c2) then Double.NaN else 8;
PZO2_Dot.SetPaintingStrategy(PaintingStrategy.POINTS);
PZO2_Dot.SetLineWeight(DotSize);
PZO2_Dot.AssignValueColor(if 0 > PZO2 then GlobalColor("TrendDown") else GlobalColor("TrendUp"));
AddChartBubble(!IsNaN(c2 [n1]) and IsNaN(C2 [n]), 8, (agg2/1000/60) + " min", Color.Yellow, yes);
#Aggregation 3
def CP3 = ExpAverage(Sign(C3 – C3[1]) * C3, length);
def TC3 = ExpAverage(C3, length);
def PZO3 = 100 * CP3 / TC3;
plot PZO3_Dot = if IsNaN(c3) then Double.NaN else 9;
PZO3_Dot.SetPaintingStrategy(PaintingStrategy.POINTS);
PZO3_Dot.SetLineWeight(DotSize);
PZO3_Dot.AssignValueColor(if 0 > PZO3 then GlobalColor("TrendDown") else GlobalColor("TrendUp"));
AddChartBubble(!IsNaN(c3 [n1]) and IsNaN(C3 [n]), 9, (agg3/1000/60) + " min", Color.Yellow, yes);
#Aggregation 4
def CP4 = ExpAverage(Sign(C4 – C4[1]) * C4, length);
def TC4 = ExpAverage(C4, length);
def PZO4 = 100 * CP4 / TC4;
plot PZO4_Dot = if IsNaN(c4) then Double.NaN else 10;
PZO4_Dot.SetPaintingStrategy(PaintingStrategy.POINTS);
PZO4_Dot.SetLineWeight(DotSize);
PZO4_Dot.AssignValueColor(if 0 > PZO4 then GlobalColor("TrendDown") else GlobalColor("TrendUp"));
AddChartBubble(!IsNaN(c4 [n1]) and IsNaN(C4 [n]), 10, (agg4/1000/60) + " min", Color.Yellow, yes);
#Aggregation 5
def CP5 = ExpAverage(Sign(C5 – C5[1]) * C5, length);
def TC5 = ExpAverage(C5, length);
def PZO5 = 100 * CP5 / TC5;
plot PZO5_Dot = if IsNaN(c5) then Double.NaN else 11;
PZO5_Dot.SetPaintingStrategy(PaintingStrategy.POINTS);
PZO5_Dot.SetLineWeight(DotSize);
PZO5_Dot.AssignValueColor(if 0 > PZO5 then GlobalColor("TrendDown") else GlobalColor("TrendUp"));
AddChartBubble(!IsNaN(c5 [n1]) and IsNaN(C5 [n]), 11, (agg5/1000/60) + " min", Color.Yellow, yes);``````

Last edited by a moderator:
Hello ,

I'm trying to create a normalized (no negative values) version of the volume zone oscillator's exponential moving average. I mushed together some normalizing code with the indicator, and I get no errors but the values are still negative. Since I have tried several times I think I will just ask your input. If you know of any similar indicators that would be great. So far this one seems to have a good personality when it interacts with fractal energy and the laguerre RSI, but the indicator is too erratic by itself.

I'd like to build a scan that can be run as a lower study, but the values don't fit for a "crossover" if they're not normalized - am I right? I am also not sure they will scale properly if you zoom in and have them laid on top of each other.
If there's any way to easily add it (and its movavgexp) to the "Laguerre time", I wonder what that would look like.

In the end I hope to have Laguerre RSI, Fractal Energy, Volume Zone Oscillator, and the Volume Zone Oscillator MovAvgExp on the same lower study, which I can run / write a crossover scan for it. I'm not sure if they all need to be on the same study to work properly for these different uses.

Code:
``````declare lower;

input length = 14;

script normalizePlot {
input data = close;
input newRngMin =  -1;
input newRngMax = 1;
def hhData = HighestAll( data );
def llData = LowestAll( data );
plot nr = ((( newRngMax - newRngMin ) * ( data - llData )) / ( hhData - llData )) + newRngMin;
}

script VZOScr {
input Length = 13;
def VP = ExpAverage(Sign(close - close[1]) * volume, length);
def TV = ExpAverage(volume, length);
plot VZO = 100 * VP / TV;
}

plot VZOX = normalizePlot(VZOScr("Length" = Length), -100, 100);``````

Last edited:
At one point in the future, you'll realize that some indicators can not be merged. An example of that would be something like the RSI and a moving average. It's like mixing oil with water. I hope that helps.

plot VZOX = normalizePlot(VZOScr("Length" = Length), 0, 100);

I think that did what I was thinking of.. but I appreciate the feedback. This might not lead anywhere, but it is interesting.

I was able to normalize all the studies together. These can also be turned into individual studies to use as scans.
I'm still mixed on the usefulness of it but I am seeing that a high (descending) wave of Fractal Energy moving average seems to carry any VZO breakouts.

Code:
``````declare lower;

#VolumeZoneOscillatorMovAvgExp#
#
# TD Ameritrade IP Company, Inc. (c) 2011-2020
#

input VAvlength = 9;

script normalizePlot {
input data = close;
input newRngMin =  -1;
input newRngMax = 1;
def hhData = HighestAll( data );
def llData = LowestAll( data );
plot nr = ((( newRngMax - newRngMin ) * ( data - llData )) / ( hhData - llData )) + newRngMin;
}

script VZOScr {
input Length = 13;
input displace = 0;
def VP = ExpAverage(Sign(close - close[1]) * volume, Length);
def TV = ExpAverage(volume, Length);
def VZO = 100 * VP / TV;
def price = VZO;
plot VZOavg = ExpAverage(price[-displace], Length);
}

plot VZOavgX = normalizePlot(VZOScr("Length" = VavLength), 0, 100);

VZOavgX.SetDefaultColor(Color.MAGENTA);
VZOavgX.SetLineWeight(3);

#VolumeZoneOscillator#
#
# TD Ameritrade IP Company, Inc. (c) 2011-2020
#

input Vlength = 9;

script normalizePlot {
input data = close;
input newRngMin =  -1;
input newRngMax = 1;
def hhData = HighestAll( data );
def llData = LowestAll( data );
plot nr = ((( newRngMax - newRngMin ) * ( data - llData )) / ( hhData - llData )) + newRngMin;
}

script VZOScr {
input Length = 13;
def VP = ExpAverage(Sign(close - close[1]) * volume, Length);
def TV = ExpAverage(volume, Length);
plot VZO = 100 * VP / TV;
}

plot VZOX = normalizePlot(VZOScr("Length" = VLength), 0, 100);
VZOX.SetDefaultColor(Color.PINK);

# RSI-Laguerre Self Adjusting With Fractal Energy Gaussian Price Filter
# Mobius
# V01.12.2016
# Both Fractal Energy and RSI are plotted. RSI in cyan and FE in yellow. Look for trend exhaustion in the FE and a reversal of RSI or Price compression in FE and an RSI reversal.

#Inputs:
# RSI-Laguerre Self Adjusting With Fractal Energy Gaussian Price Filter
# Mobius
# V01.12.2016
# Both Fractal Energy and RSI are plotted. RSI in cyan and FE in yellow. Look for trend exhaustion in the FE and a reversal of RSI or Price compression in FE and an RSI reversal.

#Inputs:
input nFE = 8;#hint nFE: length for Fractal Energy calculation.
input Glength  = 13;
input data = close;

script normalizePlot {
input data = close;
input newRngMin =  -1;
input newRngMax = 1;
def hhData = HighestAll( data );
def llData = LowestAll( data );
plot nr = ((( newRngMax - newRngMin ) * ( data - llData )) / ( hhData - llData )) + newRngMin;
}

script RSIScr {

#Inputs:
input nFE = 8;#hint nFE: length for Fractal Energy calculation.
input Glength  = 13;
input data = close;

def w = (2 * Double.Pi / Glength);
def beta = (1 - Cos(w)) / (Power(1.414, 2.0 / betaDev) - 1 );
def alpha = (-beta + Sqrt(beta * beta + 2 * beta));
def Go = Power(alpha, 4) * open +
4 * (1 – alpha) * Go[1] – 6 * Power( 1 - alpha, 2 ) * Go[2] +
4 * Power( 1 - alpha, 3 ) * Go[3] - Power( 1 - alpha, 4 ) * Go[4];
def Gh = Power(alpha, 4) * high +
4 * (1 – alpha) * Gh[1] – 6 * Power( 1 - alpha, 2 ) * Gh[2] +
4 * Power( 1 - alpha, 3 ) * Gh[3] - Power( 1 - alpha, 4 ) * Gh[4];
def Gl = Power(alpha, 4) * low +
4 * (1 – alpha) * Gl[1] – 6 * Power( 1 - alpha, 2 ) * Gl[2] +
4 * Power( 1 - alpha, 3 ) * Gl[3] - Power( 1 - alpha, 4 ) * Gl[4];
def Gc = Power(alpha, 4) * data +
4 * (1 – alpha) * Gc[1] – 6 * Power( 1 - alpha, 2 ) * Gc[2] +
4 * Power( 1 - alpha, 3 ) * Gc[3] - Power( 1 - alpha, 4 ) * Gc[4];
# Variables:
def o;
def h;
def l;
def c;
def CU1;
def CU2;
def CU;
def CD1;
def CD2;
def CD;
def L0;
def L1;
def L2;
def L3;
plot RSI;
plot OS;
plot OB;
plot M;

# Calculations
o = (Go + Gc[1]) / 2;
h = Max(Gh, Gc[1]);
l = Min(Gl, Gc[1]);
c = (o + h + l + Gc) / 4;
plot gamma = Log(Sum((Max(Gh, Gc[1]) - Min(Gl, Gc[1])), nFE) /
(Highest(gh, nFE) - Lowest(Gl, nFE)))
/ Log(nFE);
gamma.SetDefaultColor(Color.Yellow);
L0 = (1 – gamma) * Gc + gamma * L0[1];
L1 = -gamma * L0 + L0[1] + gamma * L1[1];
L2 = -gamma * L1 + L1[1] + gamma * L2[1];
L3 = -gamma * L2 + L2[1] + gamma * L3[1];
if L0 >= L1
then {
CU1 = L0 - L1;
CD1 = 0;
} else {
CD1 = L1 - L0;
CU1 = 0;
}
if L1 >= L2
then {
CU2 = CU1 + L1 - L2;
CD2 = CD1;
} else {
CD2 = CD1 + L2 - L1;
CU2 = CU1;
}
if L2 >= L3
then {
CU = CU2 + L2 - L3;
CD = CD2;
} else {
CU = CU2;
CD = CD2 + L3 - L2;
}

RSI = if CU + CD <> 0 then CU / (CU + CD) else 0;
RSI.SetDefaultColor(Color.Cyan);
RSI.SetLineWeight(3);
OS = if IsNaN(c) then Double.NaN else 0.2;
OS.SetDefaultColor(Color.RED);
OS.HideBubble();
OS.HideTitle();
OB = if IsNaN(c) then Double.NaN else 0.8;
OB.SetDefaultColor(Color.GREEN);
OB.HideBubble();
OB.HideTitle();
M = if IsNaN(c) then Double.NaN else 0.5;
M.SetStyle(Curve.long_dash);
M.SetDefaultColor(Color.Gray);
M.HideBubble();
M.HideTitle();
def FEh = if isNaN(c) then double.nan else .618;

def FEl = if isNaN(c) then double.nan else .382;
plot RSINorm = RSI;
}

RSIX.setDefaultColor(color.CYAN);
RSIX.setlineWeight(1);

# End Code RSI_Laguerre Self Adjusting with Fractal Energy
#######################################

###############################################
#
# TD Ameritrade IP Company, Inc. (c) 2017-2020
#Fractal Energy Movavgexponential

def displace = 0;
input FELength = 10;

###normalize###
script normalizePlot {
input data = close;
input newRngMin =  -1;
input newRngMax = 1;
def hhData = HighestAll( data );
def llData = LowestAll( data );
plot nr = ((( newRngMax - newRngMin ) * ( data - llData )) / ( hhData - llData )) + newRngMin;
}

script FEAvgScr {
input Length = 10;
def displace = 0;
def sumTR = Sum (TrueRange(high, close, low), Length);
def HMax =  Highest (high, Length);
def LMax =  Lowest (low, Length);
def FE = 100 * Log (sumTR / (HMax - LMax)) / Log(Length);
def price = FE;
plot FEnormExp = ExpAverage(price[-displace], Length);
}

plot FEavg = normalizePlot(FEAvgScr("Length" = FELength), 0, 100);
FEavg.setDefaultColor(color.LIGHT_GRAY);
FEavg.setLineWeight(3);``````

so found this script on another site i have adjusted it for daytrading scalping and would like to know if I could get some help adding a way to signal on the top chart (when the tzo touches or crosses the levels of 75 and -75 and 100 and -100). any help much appreciated. The main purpose is to serve as a confirmation signal for a trade... for instance if tzo is below -75 or at -100 you can look to go long paired with another level or the opposite if it is above at 75 or 100 look to sell or go short!!

Code:
``````declare lower;
input length = 14;

def VP = ExpAverage(Sign(close - close[1]) * volume, length);
def TV = ExpAverage(volume, length);

plot VZO = 100 * VP / TV;
plot "+100" = 100;
plot "+75" = 75;
plot "+28" = 28;
plot "+90" = 90;
plot "-28" = -28;
plot "-75" = -75;
plot "-90" = -90;
plot "-100" = -100;
plot ZeroLine = 0;

VZO.SetDefaultColor(GetColor(1));
"+100".SetDefaultColor(GetColor(6));
"+90".SetDefaultColor(GetColor(5));
"+75".SetDefaultColor(GetColor(6));
"-90".SetDefaultColor(GetColor(5));
"+28".SetDefaultColor(GetColor(3));
"-28".SetDefaultColor(GetColor(3));
"-75".SetDefaultColor(GetColor(5));
"-100".SetDefaultColor(GetColor(5));
ZeroLine.SetDefaultColor(GetColor(4));
def EMA60 = ExpAverage(close, 60);
def trendExistence = ADX > 18;

# 1 = cross above, 2 = stays above, 3 = crosses below, 4 = stays below

def direction = if close > EMA60 and close[1] <= EMA60 then 1 else if close > EMA60 and close[1] >= EMA60 then 2 else if close < EMA60 and close[1] >= EMA60 then 3 else 4;
def bullishCrossover = if VZO >= +40 and VZO[1] < +40 then 1 else 0;
def bearishCrossover = if VZO <= -40 and VZO[1] > -40 then 1 else 0;

plot bullSignal = if trendExistence == 1 and direction == 1 and bullishCrossover then 1 else 0;
bullSignal.setPaintingStrategy(PaintingStrategy.ARROW_UP);

plot bearSignal = if trendExistence == 1 and direction == 3 and bearishCrossover then 1 else 0; bearSignal.setPaintingStrategy(PaintingStrategy.Boolean_ARROW_DOWN);
Plot VZO_Dots = 100 * VP / TV;
VZO.setLineWeight(3);
VZO_Dots.setPaintingStrategy(PaintingStrategy.POINTS);
VZO_Dots.setLineWeight(3);
VZO.AssignValueColor(if VZO > 15 then color.green else if VZO > -5 then color.yellow else color.red);
VZO_Dots.AssignValueColor(if VZO > 15 then color.green else if VZO > -5 then color.yellow else color.red);``````

Last edited by a moderator:
I added alerts for when VZO enters and exits the buy and sell zones. Also updated color scheme. No other changes to it.

http://tos.mx/zCEpFos

Code:
``````# VZO
# Modified by Chewie
# and updated the color scheme 12/20/20
# TD Ameritrade IP Company, Inc. (c) 2011-2020
#
declare lower;

input length = 14;
def VP = ExpAverage(Sign(close - close[1]) * volume, length);
def TV = ExpAverage(volume, length);
plot VZO = 100 * VP / TV;
plot "+60" = 60;
plot "+40" = 40;
plot "-40" = -40;
plot "-60" = -60;
plot ZeroLine = 0;

VZO.DefineColor("Normal", color.white);
VZO.DefineColor("OverBought", color.red);
VZO.DefineColor("OverSold", color.green);
VZO.AssignValueColor(if VZO > "+60" then VZO.Color("OverBought") else if VZO < "-60" then VZO.Color("OverSold") else VZO.Color("Normal"));
"+60".SetDefaultColor(color.red);
"+40".SetDefaultColor(color.red);
"-40".SetDefaultColor(color.green);
"-60".SetDefaultColor(color.green);
ZeroLine.SetDefaultColor(color.yellow);

def condition1 = VZO crosses above "+40";
def condition2 = VZO crosses below "+40";
def condition3 = VZO crosses below "-40";
def condition4 = VZO crosses above "-40";

input length = 14;

def VP = expAverage(Sign(close - close[1]) * volume, length);
def TV = expAverage(volume, length);

def VZO = 100 * VP / TV;
plot VZO_DOTS = 100 * VP / TV;
plot "+60" = 60;
plot "+40" = 40;
#plot "+15" = 15;
#plot "-5" = -5;
plot "-40" = -40;
plot "-60" = -60;
plot ZeroLine = 0;

VZO.SetDefaultColor(GetColor(1));
"+60".SetDefaultColor(GetColor(6));
"+40".SetDefaultColor(GetColor(6));
#"+15".SetDefaultColor(GetColor(3));
#"-5".SetDefaultColor(GetColor(3));
"-40".SetDefaultColor(GetColor(5));
"-60".SetDefaultColor(GetColor(5));
ZeroLine.SetDefaultColor(GetColor(4));

def EMA60 = ExpAverage(close, 60);

def trendExistence = ADX > 18;
#1 - crosses above EMA60, 2 - above EMA60, 3 - crossing below EMA60, 4 - below EMA60
def direction = if close > EMA60 and close[1] <= EMA60 then 1 else if close > EMA60 and close[1] >= EMA60 then 2 else if close < EMA60 and close[1] >= EMA60 then 3 else 4;

def bullishCrossover = if VZO >= 40 and VZO[1] < 40 then 1 else 0;
def bearishCrossover = if VZO <= -40 and VZO[1] > -40 then 1 else 0;

VZO_DOTS.SetPaintingStrategy(PaintingStrategy.POINTS);
VZO_DOTS.AssignValueColor(if VZO > 15 then color.green else if VZO > -5 then color.yellow else color.red);
VZO_DOTS.SetLineWeight(3);

Last edited by a moderator:
See if this is what you are looking for

Code:
``````declare lower;
input length = 14;
input agg = AggregationPeriod.DAY;

def VP = expAverage(Sign(close(period = agg) - close(period = agg)[1]) * volume(period = agg), length);
def TV = expAverage(volume(period = agg), length);

plot VZO = 100 * VP / TV;
plot VZO_DOTS = 100 * VP / TV;
plot "+60" = 60;
plot "+40" = 40;
#plot "+15" = 15;
#plot "-5" = -5;
plot "-40" = -40;
plot "-60" = -60;
plot ZeroLine = 0;

VZO.SetDefaultColor(GetColor(1));
"+60".SetDefaultColor(GetColor(6));
"+40".SetDefaultColor(GetColor(6));
#"+15".SetDefaultColor(GetColor(3));
#"-5".SetDefaultColor(GetColor(3));
"-40".SetDefaultColor(GetColor(5));
"-60".SetDefaultColor(GetColor(5));
ZeroLine.SetDefaultColor(GetColor(4));

def EMA60 = ExpAverage(close(period = agg), 60);

def trendExistence = ADX > 18;
#1 - crosses above EMA60, 2 - above EMA60, 3 - crossing below EMA60, 4 - below EMA60
def direction = if close(period = agg) > EMA60 and close(period = agg)[1] <= EMA60 then 1 else if close(period = agg) > EMA60 and close(period = agg)[1] >= EMA60 then 2 else if close(period = agg) < EMA60 and close(period = agg)[1] >= EMA60 then 3 else 4;

def bullishCrossover = if VZO >= 40 and VZO[1] < 40 then 1 else 0;
def bearishCrossover = if VZO <= -40 and VZO[1] > -40 then 1 else 0;

VZO.AssignValueColor(if VZO > 15 then color.green else if VZO > -5 then color.yellow else color.red);
VZO_DOTS.SetPaintingStrategy(PaintingStrategy.POINTS);
VZO_DOTS.AssignValueColor(if VZO > 15 then color.green else if VZO > -5 then color.yellow else color.red);
VZO_DOTS.SetLineWeight(3);``````

This is based on the Volume Zone Oscillator. Here is the modified code.

Code:
``````input length = 14;

def VP = expAverage(Sign(close - close[1]) * volume, length);
def TV = expAverage(volume, length);

def VZO = 100 * VP / TV;
plot VZO_DOTS = 100 * VP / TV;
plot "+60" = 60;
plot "+40" = 40;
#plot "+15" = 15;
#plot "-5" = -5;
plot "-40" = -40;
plot "-60" = -60;
plot ZeroLine = 0;

VZO.SetDefaultColor(GetColor(1));
"+60".SetDefaultColor(GetColor(6));
"+40".SetDefaultColor(GetColor(6));
#"+15".SetDefaultColor(GetColor(3));
#"-5".SetDefaultColor(GetColor(3));
"-40".SetDefaultColor(GetColor(5));
"-60".SetDefaultColor(GetColor(5));
ZeroLine.SetDefaultColor(GetColor(4));

def EMA60 = ExpAverage(close, 60);

def trendExistence = ADX > 18;
#1 - crosses above EMA60, 2 - above EMA60, 3 - crossing below EMA60, 4 - below EMA60
def direction = if close > EMA60 and close[1] <= EMA60 then 1 else if close > EMA60 and close[1] >= EMA60 then 2 else if close < EMA60 and close[1] >= EMA60 then 3 else 4;

def bullishCrossover = if VZO >= 40 and VZO[1] < 40 then 1 else 0;
def bearishCrossover = if VZO <= -40 and VZO[1] > -40 then 1 else 0;

VZO_DOTS.SetPaintingStrategy(PaintingStrategy.POINTS);
VZO_DOTS.AssignValueColor(if VZO > 15 then color.green else if VZO > -5 then color.yellow else color.red);
VZO_DOTS.SetLineWeight(3);``````

anyone know the code that will give sound alerts whenever the VZO DOTS go above the +40 and below the -40 zones?

87k+ Posts
330 Online

## The Market Trading Game Changer

Join 2,500+ subscribers inside the useThinkScript VIP Membership Club
• Exclusive indicators
• Proven strategies & setups
• Private Discord community
• Exclusive members-only content
• 1 full year of unlimited support

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?