Backtrader: Chaikin Money Flow Indicator

The Chaikin Money Flow (CMF) is a popular volume based indicator. It was developed by Marc Chaikin who has been an analyst, trader and entrepreneur in the industry since 1965. Further, he has been developing trading indicators since the 1980’s during which time he worked on some well-known indicators (with this being one of them). More recently he has founded the company Chaikin Analytics which provides analytics tools and software.

Source: https://en.wikipedia.org/wiki/Marc_Chaikin

Marc’s CMF Indicator is available on Tradingview as an open source indicator. This means we can take a look at that code and use it to make a port for Backtrader. However, before we get into the code, let’s take a quick look at the theory behind the indicator and some of the common ways to interpret it.

Chaikin Money Flow

Designed to measure the flow of money over a given period of time, the Chaikin Money Flow indicator will be positive when money is flowing into an asset and negative when money is flowing out of an asset. The way in which the indicator is calculated means that the value fluctuates between -1 and 1. As such, this indicator can be considered an oscillator.

The indicator has 3 main components:

  • Multiplier: This is the key component that allows the indicator to oscillate. A calculation is made which results in a negative or positive value that can then be used as multiplier. Essentially, the calculation will be positive if the close value is closer to the high of the day. Conversely, if the close value is closer to the low of the day, it will be negative.
  • Adjusted Volume:  Then we adjust the volume to a positive or negative value (volume * the multiplier)
  • CMF Value:  Finally we take a x period sum of the adjusted volume and divide it by the same period of total volume.

The actual formula and calculation will be seen in the code later but for those of you that prefer to put your math hat on, here is a link to the mathematical formula: https://en.wikipedia.org/wiki/Chaikin_Analytics#Chaikin_Money_Flow

Using Chaikin Money Flow

Given that this is an oscillating indicator, we have the usual suspects when it comes to interpretation. These being:

  • Zero Line: If the indicator is above zero, it suggests there is buying bias in the market. If it is below, we have a selling Bias.
  • Extremes: If the CMF value gets to an extreme level it could indicate a trend reversal. However, we must be careful in defining extreme. Due to the way the indicator is calculated, the longer the look-back period you use, the less likely it is to ever get to an extreme level. For example, with a look back period of 20, you would need 20 consecutive closes where the high is equal to the close value in order to reach 1.

The Code

Code Commentary

All of the action for this indicator is contained within the __init__()method. For anyone who has a basic knowledge of Backtrader and Python, the majority of the code within __init()__should be self-explanatory. However, if you are a complete beginner, fear not! We have some getting started tutorials here:

https://backtest-rookies.com/getting-started/

The two areas of which have not been covered before and are worth commenting on are the plotlinesdictionary and the self.data.adline.

Plotlines

The plotlines dictionary allows us to specify the look and feel of our plotted line. Each line has it’s own dictionary within it. This is how we can specify different parameters for different lines. Backtrader uses matplotlibfor plotting and as such we occasionally need to reference the matplotlibdocumentation to see what options/parameters are available to us. The official documentation makes a special mention to point this out.

Most of options specified inplotlines are meant to be directly passed over to matplotlib when plotting.

So for example, in the official Backtrader docs we have the code snippet:

However, if you see this and try to set a width parameter on a line chart rather than a bar chart (by changing the _method), you will encounter issues. So it is always a good idea to check the matplot lib docs.

Backtrader Docs: https://www.backtrader.com/docu/plotting/plotting.html#line-specific-plotting-options

Matplotlib Docs: https://matplotlib.org/api/pyplot_summary.html

Matplotlib Bar Options: https://matplotlib.org/api/_as_gen/matplotlib.pyplot.bar.html#matplotlib.pyplot.bar

bt.If(), bt.And() and bt.Or()

Next, we go to the long self.data.adline. Although it appears quite complex at first, we can break it down in plain English:

self.data.ad = bt.If(bt.Or(bt.And(c == h, c == l), h == l), 0, ((2*c-l-h)/(h-l))*v)

IF the Close == High AND the Close == Low OR High == Low THEN the value = 0 OTHERWISE, perform the multiplier calculation.

The reason it can look a little daunting is because we need to nest bt.And()/bt.Or()inside the bt.If() function. We do this as we cannot use pythons own if,andandoroperators when creating new data lines during __init__. This is a technical limitation and therefore, bt.If() and a series of other operators were created as a workaround.  For more information, see the documentation here:

https://www.backtrader.com/docu/concepts.html#some-non-overriden-operators-functions

On The Chart

Finally, let’s run the indicator on some data to see how it looks!

Chaikin Money Flow indicator shown on the chart