How to Build a Profitable Money Flow Index Strategy Using Python (Rules, Backtest)

How to Build a Profitable Money Flow Index Strategy Using Python (Rules, Backtest)

Introduction

This tutorial will explain the construction of a Money Flow Index trading strategy to you in Python. Along the way, it will implement class inheritance approach to build the code. The aim of the article is to show the code how it’s done, not to make a superb trading strategy.

The main Python packages for trading use the inheritance principle to build trading strategies; therefore, understanding this topic will enhance your skill in using those Python packages.

The financial instrument to use is the Invesco QQQ Trust (QQQ) etf, and the start and end periods for this trading strategy are 2000-01-01 and 2023-10-23, respectively.

Profitable Money Flow Index Strategy in Python

Money Flow Index (MFI)

The Money Flow Index Indicator measures when a financial instrument is overbought or oversold. The calculation uses the price and volume to estimate it.

There are four steps to calculate the indicator:

Typical Price:

\begin{align}
   \text{{Typical Price}} = \frac{{\text{{High}} + \text{{Low}} + \text{{Close}}}}{3}
\end{align}

Raw Money Flow:

\begin{align}
   \text{{Raw Money Flow}} = \text{{Typical Price}} \times \text{{Volume}}
\end{align}

Money Flow Ratio:

\begin{align}
   \text{{Money Flow Ratio}} = \frac{{\text{{14-period Positive Money Flow}}}}{{\text{{14-period Negative Money Flow}}}}
\end{align}

Money Flow Index:

\begin{align}
   \text{{Money Flow Index}} = 100 - \frac{{100}}{{1 + \text{{Money Flow Ratio}}}}
\end{align}

This indicator is (in reality) a volume-weighted RSI because it multiplies the typical price by the volume.

Python Implementation

Importing Libraries and Downloading Data

As in the previous tutorial about a profitable VWAP trading strategy, the first part is to import the Python libraries and download the historical financial data as follows:

The output is:

Downloading Data (Parent Class)

This section will build a class to download the same data from the previous section; the difference is the Object Oriented Approach implemented in this section. In a previous article about how to build a profitable Parabolic SAR trading strategy, we showed the implements Object Oriented Approach.

The following image shows the class Parent, which has three initial parameters security_name, start, and end. The build-in __init__ function instantiates the values from the Parent class. Meanwhile, the download_data1 function from the Parent class downloads the data; this function follows the same procedure as the download_data function; the difference is that one function is inside of Parent, and the other no.

The following image shows the implementation of the class Parent, myclass1 = Parent(security_name, ‘2000-01-01’, “2023-10-23”); it is instantiated with security_name, ‘2000-01-01’, “2023-10-23”. Subsequently, it calls its internal function download_data1 to download data from Yahoo Finance.

Calculation of Money Flow Index (Child Class)

This section will estimate the Money Flow Index using the Object Oriented approach (OOA). The name of the class to calculate the MFI is Child. Although this name does not relate to the name of the indicator, it will illustrate how the inheritance properties work from one class to the other.

Firstly, this paragraph will explain a graphical example to illustrate more clearly how class inheritance works in Python; in the following image below, on the left, you can see the classes ExampleParent and ExampleChild, respectively. The ExampleChild class inherits all the methods and properties of ExampleParent using ExampleChild(ExampleParent), then implements super().__init__(a, b), which makes it possible to add the methods and properties of ExampleParent to ExampleChild; otherwise, all the methods need to be added manually from ParentClass to ParentChild, as shown in the ParentChild class located on the right side of the image.

The following images show the Child class, the __init__ function has three parameters security_name, start, and end. Inside of the __init__ function, the super().__init__(self, security_name, start, end) will make the Child class inherit all methods and properties from the class Parent.

The following functions handle the procedure to calculate the Money Flow Index indicator. The first step is to use the typical price get_typical_price, which is the average price between high, low, and close.

The second step is to implement the get_raw_money_flow function, which gets the results from the typical price and multiplies it by the volume. Third, the get_money_flow_ratio function implements the procedure to calculate the Money Flow Ratio.

Finally, the get_money_flow_index function calculates the Money Flow Index Indicator.

The following image shows the implementation of the class Parent to obtain MFI:

Plotting Money Flow Index and Analysis

This section will plot the Money Flow Index indicator and the daily closing price; for this, we will use a version with minor modifications of the article we wrote about how to make a profitable stochastic trading strategy. For an explanation of it, we recommend going to that article.

The previous code, plot_data(result_myclass2, mfi, security_name), implements the MFI indicator with 20% and 80% thresholds. As observed in the image below, in the green time series, the lower threshold (20%), only generates one buy signal.

Meanwhile, there are at least ten signals with a long position (threshold 80%). Under this situation, it is necessary to change the thresholds to have more signals for long and short positions.

When we observe the following graph with 30% and 70% thresholds, there are more sell signals (above 70%) than buy signals (below 30%). If we look at the closing price chart, it is clear that the price is following an upward trend; therefore, placing too many short positions will result in losses.

For the reason expressed in the previous paragraph, we increase the lower threshold to 35%; in the following chart, it is evident that the number of times the MFI exceeds 70% is higher than the number of times the indicator is below 35%.

Finally, we increase both thresholds to 40% and 75%; in this case, the number of times a long position is started (MFI below threshold 40%) exceeds the number of times a short position is started (MFI is higher than 75%).

Trading Strategy and Backtesting

The strategy to implement is:

1) Take a long position when the MFI indicator is below 40%, and hold that position until the indicator crosses above 75%.

2) Take a short position when the MFI indicator is above 75%, and hold that position until the indicator falls below 40%.

The decision to use the 40% and 75% thresholds is based on the analysis conducted in the previous section.

The following image illustrates the calculate_signals function, which determines the periods for holding long and short positions. The objective is to iterate over the values of the Money Flow Index indicator; whenever the indicator is below threshold1, position=1; if the MFI is above threshold2, position=-1; if neither condition is met, the indicator remains the same as the previous value, meaning that the position is held.

The equity_curve function, which has been discussed in many previous tutorials, is shown in the following image:

Implementing this function yields:

The above image portrays a strategy with favorable results, surpassing its benchmark (which doesn’t include reinvested dividends). This strategy is the outcome of comprehending the data and understanding how the thresholds of the MFI indicator could be adapted to the upward pattern in the historical series of closing prices.

Same Trading Strategy using SPY

The following chart is the previous strategy applied to the SPY:

The strategy has positive results but does not work well because each financial security behaves differently; therefore, implementing the same strategy with the same parameter will not generate a similar performance.

Similar Posts