Volume Zone Oscillator

The Volume Zone Oscillator (VZO) was authored by Walid Khalil and David Steckler in the Stocks and Commodities Magazine, May 2011. The VZO uses price, previous price and moving averages to compute its oscillating value. It is a leading indicator that calculates buy and sell signals based on oversold / overbought conditions. The VZO system also uses a 60 period Exponential Moving Average and a 14 period Average Directional Movement Index (ADX). The user may change the input (close), method (EMA) and period lengths. This indicator’s definition is further expressed in the condensed code given in the calculation below.

VZO01

How To Trade Using The Volume Zone Oscillator

Four trading signals (enter long, exit long, enter short, exit short) are calculated for this indicator. For details refer to the S and C article and the code given below.

How To Access in MotiveWave

Go to the top menu, choose Add Study, start typing in this study name until you see it appear in the list, click on the study name, click OK.

Important Disclaimer: The information provided on this page is strictly for informational purposes and is not to be construed as advice or solicitation to buy or sell any security. Please see our Risk Disclosure and Performance Disclaimer Statement.

Calculation

//input = price, user defined, default is closing price
//method = moving average, user defined, default is EMA
//period = user defined, default is 14
//maPeriod = user defined, default is 60
//reduceWhipsaws = default is true
//index = current bar number

prevPrice = price[index-1];
vol = getVolume(index);
r = Utility.sign(price, prevPrice) * vol;
ma = ma(method, index, maPeriod, key);
vp = ma(method, index, period, R);
tv = ma(method, index, period, VOLUME);
if (tv != 0) vzo = 100 * vp / tv;
prevVzo = vzo[index-1];
//ADX
// Calculate the +DM, -DM and TR
pdm = getPositiveDM(index);
ndm = getNegativeDM(index);
tr = getTrueRange(index);
// Calculate the Average +DM, -DM and TR
pdma = smma(index, period, PDM);
ndma = smma(index, period, NDM);
tra = smma(index, period, TR);
// Determine the +DI, -DI and DX
pdi = pdma / tra * 100;
ndi = ndma / tra * 100;
dx = abs((pdma - ndma)) / (pdma + ndma) * 100;
// Calculate the Average DX
Plot:adx = smma(index, period, DX);
// Signals
//Note:Shorthand example: bottGuide40=bottom guide with default value of 40
boolean enterLong = false, exitLong = false, enterShort = false, exitShort = false;
//uptrend
if (price moreThan ma AND adx moreThan adxMidG)
      if (reduceWS) enterLong = (prevVzo lessThan bottG40 AND vzo moreThan bottG40) OR (prevVzo lessThan topG15 AND  vzo moreThan topG15);
      if (!reduceWS) enterLong= (prevVzo lessThan bottG40 AND vzo moreThan bottG40) OR (prevVzo lessThan midG AND vzo moreThan midG);
  exitLong = ((prevVzo moreThan topG60 AND vzo lessThan prevVzo) OR (prevVzo moreThan topG40 AND vzo lessThan   topG40) OR (price lessThan ma AND vzo lessThan midG)); 
endIf
//down trend
if (price lessThan ma AND adx moreThan adxMidG)
      if (reduceWS) enterShort = (prevVzo moreThan topG40 AND vzo lessThan topG40) OR (prevVzo moreThan bottG5 AND vzo lessThan bottG5);  
      if (!reduceWS) enterShort = (prevVzo moreThan topG40 AND vzo lessThan topG40) OR (prevVzo moreThan midG AND vzo lessThan midG);  
      exitShort = (vzo lessThan bottG60 AND vzo moreThan prevVzo) OR (prevVzo lessThan bottG40 AND vzo moreThan bottG40) OR (price moreThan ma AND prevVzo lessThan midG AND vzo moreThan midG);
         
endIf  
//non trending
if (adx lessThan adxMidG)
      enterLong = (prevVzo lessThan bottG40 AND vzo moreThan bottG40) OR (prevVzo lessThan topG15 AND vzo moreThan topG15);
      exitLong = ((prevVzo lessThan topG40 AND vzo moreThan topG40) AND exitLong) OR (prevVzo moreThan bottG5 AND vzo lessThan bottG5);
      enterShort = (prevVzo moreThan topG40 AND vzo lessThan topG40) OR (prevVzo moreThan bottG5 AND vzo lessThan bottG5);
if ((prevVzo moreThan bottG40 AND vzo lessThan bottG40))
        if (reduceWS) exitShort = (prevVzo lessThan bottG40 AND vzo moreThan bottG40) OR (prevVzo lessThan topG15 AND vzo moreThan topG15);
        if (!reduceWS) exitShort= (prevVzo lessThan bottG40 AND vzo moreThan bottG40) OR (prevVzo lessThan midG AND vzo moreThan midG);
 
endIf
      if (vzo moreThan bottG40) exitShort =  (prevVzo lessThan topG15 AND vzo moreThan topG15);