Advanced Volume Zone Oscillator

Transform the basic VZO indicator in ThinkOrSwim, and extract meaningful patterns to turn it into a useful trend trading tool

25 mins
Beginner-Friendly
youtube-video-thumbnail
Table of Contents
    Add a header to begin generating the table of contents
    Table of Contents
      Add a header to begin generating the table of contents

      Introduction

      Welcome to the 14th episode of “How to thinkScript”.

      In this video, we’re going to take the basic Volume Zone Oscillator that’s built into ThinkOrSwim , and turn it into something like this:

      Advanced Volume Zone Oscillator (VZO) for ThinkOrSwim

      Most of this is going to be just some formatting tricks, using the basic indicator. But, we’ll use some ThinkOrSwim documentation, along with some research, to make the VZO more advanced, and complete.

      Volatility Box Invite

      We are TOS Indicators.com, home of the Volatility Box.

      The Volatility Box is our secret tool, to help us consistently profit from the market place. We’re a small team, and we spend hours every day, after the market close, doing nothing but studying thousands of data points to keep improving and perfecting the Volatility Box price ranges.

      We have two different Volatility Boxes - a Futures Volatility Box and a Stock Volatility Box.

      Futures Volatility Box - Trade Major Markets With an Edge

      Designed For: Futures, Micro-Futures and Index Market Traders
      Supported Models: Hourly Volatility Box models
      Supported Markets: 10 Major Futures Markets

      The Futures Volatility Box comes with:

      • 5 Volatility Models for each market
      • Support for 10 Futures Markets (/ES, /NQ, /YM, /RTY, /CL, /GC, /SI, /ZB, /HG, /NG)
      • Video Setup Guide
      • Trade Plan
      • Access to all members-only resources, including Squeeze Course

      Learn More About the Futures Volatility Box

      Trade futures and micro futures with a consistent volatility edge

      Stock Volatility Box - Powerful Web Based Volatility Platform

      Designed For: Stock and Options Traders
      Supported Models: Hourly and Daily Volatility Box models
      Supported Markets: 10,000+ Stocks and ETFs (new markets added frequently)

      A Stock Volatility Box membership includes access to: 

      • Live Scanner - A powerful scanner we've built from scratch, to scan 10,000 symbols every 2 seconds for new volatility breaches
      • Dashboard - A quick and easy way to view daily volatility model levels online
      • Short Interest Scanner - Short interest, Squeeze, and EMA data to find short squeezes
      • Squeeze Course - All of our proprietary squeeze tools, including robust backtesters
      • All Members Only Indicators - We don't nickel and dime you. Everything really is included.
      • And much more!

      Learn More About the Stock Volatility Box

      Trade stocks and options with a consistent volatility edge

      Concepts

      In this tutorial, we’re going to cover a handful of concepts.

      We’ll talk about reading ThinkOrSwim documentation, and translating their insights into actual code.

      Once we have that, we will spend some time going over formatting tips and tricks for ThinkOrSwim studies, to show relevant information only.

      And finally, we’ll use the lower VZO Indicator that we build, to quickly build out an upper VZO indicator as well, with colored candles and arrows.

      Let’s get started.

      What is the Volume Zone Oscillator?

      Before we write any code to build the VZO Indicator, let’s first understand what it even is.

      VZO stands for “Volume Zone Oscillator”

      Let’s take a look to see how the ThinkOrSwim documentation defines VZO:

      The Volume Zone Oscillator (VZO) is a technical indicator analyzing volume changes in relation to certain levels (zones). Unlike VolumeOsc, the VZO uses price data along with volume.

      Two averages are calculated for the VZO: the first one is price related EMA of volume, the second is general EMA of volume. The first EMA takes into account volume with sign like OnBalanceVolume: the volume is considered negative when the Close price of the corresponding bar is lower than that of the previous bar, and positive otherwise. Once these averages are calculated, their percentage ratio is the resulting plot.

      Several levels are introduced to analyze the VZO plot: “+60”, “+40”, “+15”, “-5”, “-40”, and “-60”. These numbers represent corresponding percentage values. For additional confirmation, it is suggested that the VZO plot be accompanied with 60 period EMA and 14 period ADX. These two studies are used for checking trend existence and direction. ADX values higher than 18 suggest that the market is trending, otherwise the non-trending mode is spotted. When the market is trending, the trend direction can be defined using the EMA: the price crossing above the EMA suggests the uptrend, otherwise the downtrend is detected. When the trend mode and direction are defined, use the crossovers of the VZO with corresponding levels as Buy and Sell signals for long and short positions (see plots’ descriptions for details).

      Source: https://tlc.thinkorswim.com/center/reference/Tech-Indicators/studies-library/V-Z/VolumeZoneOscillator

      Let’s summarize the takeaways.

       

      VZO Takeaways

      So the key points to highlight here that there are two moving averages that go into the calculation:

      1. Price related EMA of Volume
      2. General EMA of Volume

      The VZO line that plots in the indicator is the percentage ratio of both the price related volume EMA, and the general volume EMA. And we can see that there are different levels based on this percentage, which is what all of the different sections in the indicator are… green, yellow, red, etc.

      Let’s keep reading.

      Ah – ThinkOrSwim even gives us some hints.

      For additional confirmation of the VZO indicator, they suggest using the 60 period EMA and 14 period ADX. So we might be able to use this for arrows on the chart.

      And we see that both of these indicators help validate that the trend actually exists, and what direction it’s headed in.

      • 14-period ADX condition: ADX value above 18 suggests that the market is trending. So trend existence.
      • 60-period EMA condition:Price crossing above the EMA suggests an uptrend. Otherwise we are in a down trend.

      And our final hint is when the trend exists, and we know the direction, then use the VZO crossovers with the levels as buy and sell signals.

      Let’s start writing some code.

      Advanced VZO Code for ThinkOrSwim

      So the built-in study is going to be our base. It seems to match even the settings from the screenshot of a 14-period oscillator.

      And for the rest of it, we’re going to use the hints given to us by ThinkOrSwim.

      So let’s create a new study. We’ll call it “TI_AdvancedVZO_Lower”

      In it, let’s start by bringing over all the existing plots from the built-in indicator inside of ThinkOrSwim.

      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 "+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));=

      Ok – that’s a good baseline. Now let’s start by going through our ThinkOrSwim hints.

      Let’s go ahead and create two new variables, that brings in our 14 period ADX and our 60 period EMA indicators.

      def ADX = ADX (14);
      def EMA60 = ExpAverage(close, 60);

      Next, let’s define the trigger criteria condition for each of these:

      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; 

      Now, we need  to bring everything together.

      Let’s now start to define what an VZO crossover looks like:

      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);

      Fantastic. That works like we expected it to. There aren’t a ton of signals that are populating on the charts, which is the point of all of our confirmation signals.

      To confirm.

      Formatting

      Let’s complete the funnel now with a list of top holdings.

      The first thing is lines. There’s too many of them. Let’s clean that up.

      We’ll comment out the –5 and 15.

      We can also turn the top and bottom levels into a cloud, similar to our Volatility Box.

      Let’s change their line plots to the following:

      AddCloud(40, 60, color.green, color.green);
      Addcloud (-40,-60, color.red, color.red);

      It would also be cool if the VZO Indicator line changed colors based on which zone we are in. Let’s do that. We’ll use the AssignValueColor function for that.

      Another thing, to achieve this effect of having dots and lines, we’ll duplicate the plot of the VZO, so we can have one draw using dots. The other using a line.

      However, we will use the same logic for coloring on both, to make our jobs easy.

      Plot VZO_Dots = 100 * VP / TV;
      VZO.setLineWeight(3);
      VZO_Dots.setPaintingStrategy(PaintingStrategy.POINTS);
      VZO_Dots.setLineWeight(3);

      Now, let’s set the logic for the VZO Indicator’s colors.

      VZO.AssignValueColor(if VZO > 15 then color.green else if VZO > -5 then color.yellow else color.red);

      And we’ll copy paste this one more time, for our dots.

      VZO_Dots.AssignValueColor(if VZO > 15 then color.green else if VZO > -5 then color.yellow else color.red);

      Click save, and voila!

      That’s it folks. You have a fancy new VZO Indicator to trade momentum and trends.

      Creating an Upper VZO Indicator Study

      Once we copy paste all of the code, we’ll change the top to declare upper, instead of the lower.

      Declare upper;

      And we already have the arrows declared in our code, from our initial work.

      The only step left is to define the colors of the candles. Let’s do that. We’ll change the AssignValueColors on VZO to be for the candles instead. So we’ll replace that with AssignPriceColors.

      And let’s make our arrows stand out a bit more. Here is the final code for the TI_AdvancedVZO_Upper study:

      declare upper;
      
      input length = 14;
      
      def VP = ExpAverage(Sign(close - close[1]) * volume, length);
      def TV = ExpAverage(volume, length);
      
      def VZO = 100 * VP / TV;
      
      
      def ADX = ADX(14);
      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;
      
      plot bullSignal = if trendExistence == 1 and direction == 1 and bullishCrossover then 1 else 0;
      bullSignal.setPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
      bullSignal.SetLineWeight(5);
      
      plot bearSignal = if trendExistence == 1 and direction == 3 and bearishCrossover then 1 else 0;
      bearSignal.setPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);
      bearSignal.SetLineWeight(5);
      
      AssignPriceColor(if VZO > 15 then color.green else if VZO > -5 then color.yellow else color.red);
      

      Download

      Click the button below to download the code for the Advanced Volume Zone Oscillator (VZO) Indicator.

      downloads

      Download the Advanced VZO Indicator for ThinkorSwim.

      The download contains a STUDY.ts file, which you can directly import into your ThinkOrSwim platform.

      Download Indicator

      Download the Advanced VZO Indicator for ThinkorSwim.

      The download contains a STUDY.ts file, which you can directly import into your ThinkOrSwim platform.

      Have your own idea?

      Let us help you turn your trading strategy into a powerful indicator, scan and backtester.