Data Analysis: Volume at Price

The post today focuses on neither Backtrader or Tradingview (could pigs be flying?). Instead, we are going to create a tool that can be used to analyze which price levels attract the most volume for a particular stock. This is known generally as “Volume at Price”.

Yes, I know Tradingview has such an indicator for Pro subscribers. However, not all of the Backtest-Rookies audience are Tradingview subscribers.

It is also worth noting that this post is not aimed at the beginner.  The code sample can certainly be used by anyone but understanding each part of the code might be a stretch if you are new.

Volume At Price

Volume at price indicators simply shows which price levels see the most volume. Some will break it down into buying and selling volume if that data is available. When using volume at price analysis, traders can confirm key support or resistance levels as market participants rush to buy stock when it is considered cheap or conversely sell it when taking profits.

Setup

As mentioned in the introduction. The code in this post does not use Backtrader. Instead, we start working with the following packages/libraries:

  • Quandl
  • Pandas
  • Numpy
  • Matplotlib

Quandl will be used for downloading example data. Once you are comfortable with the code, it can easily be replaced with a CSV file or other source. Panda’s and Numpy are used for working with the data we download from Quandl. Finally, Matplotlib is used to plot the final chart. It is worth noting that Pandas, Numpy and Matplotlib go hand in hand and are used extensively by those in the data science and technology communities.

All of these packages are available via pip. To install them simply:

pip install <insert package name>

Remember to replace pipwith pip3 if you already have python2installed.

References:

Pandas: https://pandas.pydata.org/

Numpy: http://www.numpy.org/

Matplotlib: https://matplotlib.org/

Disclaimer:

Matplotlib, Pandas, and Numpy are packages that I tend to use only when I have a specific task in mind. I don’t live in these libraries. They are all large, powerful and worthy of many blogs of their own. As such, do not assume the code examples in this post follow the best practices for those libraries.

The Code

Without further ado, here is the code. We will discuss more in the commentary below:

Commentary

Quandl is used as a convenient, predictable data source for sharing the code online. Using Quandl ensures everyone can use the example code. It was not selected for any other reason. In fact, some people may wish to replace Quandl with their own data source or even CSV files. Note that if you do decide to use Quandl at a source you should add your API key or remove the following two lines. However, if you do remove them, you shall be limited to a certain number of API calls per day.

Once we have our data we need to trim it for the parts that are useful. For volume at price charts, we only need the volume and close data. Note that some people may wish to change this the HL2 (high + low / 2) to give a more central point for the volume traded in that day/bar. Others may prefer something completely different. After all, the traded volume was unlikely to all happen at the close price.

After we have extracted a copy of the data we want to work with, here comes the tricky part. We now have the volume for close of every bar but it is just a chronological list of values. Everything is still indexed by date. We want to be able to ignore the date something happened and instead focus on the price levels.

So to tackle this, the first thing we do is round every close price to a reasonable level for the data we are working with. What does that mean? Well, we probably don’t want to see the volume $1 price levels for a stock measured over 15 years and now trades for $700 a share. We would end up with data overload on the chart with very little visibility of key levels. Instead of $10, $20 or $50 dollar steps might be more appropriate.

Using thecustom_round() function, we are able to specify which key levels we want to focus on. The function is applied to the Close column of the Pandas dataframe and rounds each Closeto an appropriate nearby level. Full credit where it is due for this part of the code. It came from Andy on StackOverflow with a great example of how to “round to the nearest N” in Pandas.

So now we have centered each piece of volume around a key level. However, we are now left with lots of entries at the same price level. Therefore, we must now group and sum the rows. To do this we group by the Close price and sum the volume levels.

Finally, once we have our data ready, all that is left to do is to plot it! Again, the horizontal bar chart is not entirely my own. It was taken mostly from the standard example on the MatplotLib website. See here: https://matplotlib.org/gallery/lines_bars_and_markers/barh.html

Testing

In order to build confidence in the rounding and summing, we need to perform some controlled tests on a small selection of data. To do this, we will go through a full example, checking the raw data and verifying it is correct at each stage described above.

Note: This section assumes you have saved the code as vol_at_price.py.

Let’s take a look at Amazon over a short period of time to make verification a little simpler.

python3 vol_at_price.py WIKI/AMZN 2018-03-01 2018-03-20 5

Now let’s add some print statements to the round_and_group()function.

Then run the script.

The key level to watch for here is 1545 it has been summed from the 07th March and the 19th of March into a single row. 1590has also been summed from the 13th and 14th of March. As such, when we create the chart we can see that these two levels saw the most volume over the test period. Here is the final chart:

Image showing the final volume at price chart from the verification example