Algorithmic Trading Strategy Using Money Flow Index (MFI) & Python

Use MFI to know when to buy and sell stock

Image for post
Image for post

Disclaimer: The material in this article is purely educational and should not be taken as professional investment advice. Invest at your own discretion.

In this article, I will attempt to create a trading strategy called Money Flow Index (MFI). The MFI is also known as volume-weighted RSI and it is an oscillator that uses price and volume data for identifying overbought or oversold signals in an asset.

A Money Flow Index (MFI) level above 80 is considered overbought which is an indication to (sell) and a level below 20 is considered oversold which is an indication to (buy). Also note that levels of 90 and 10 are also used as thresholds.

Calculating the Money Flow Index:

When calculating the Money Flow Index, you want to first calculate the typical price. The typical price indicates an average of each days price. The calculation takes the current high price plus the current low price plus the current close price and divides it by three.

Next, calculate the money flow which is negative when the typical price declines from one period to another and is positive when the typical price rises from one period to another. This calculation is done by multiplying the typical price with the volume.

Get the positive money flow and the negative money flow within a given time period. We can get the positive money flow by adding the money flow of all the days where the typical price is higher than the previous day’s typical price, and we can get the negative money flow by adding the money flow of all the days where the typical price is lower than the previous day’s typical price. If the typical price didn’t change then that day is removed, but adding 0 is effectively the same thing.

Next we need to calculate the money flow ratio. The money flow ratio is calculated by taking the positive money flow for a specific time period and dividing it by the negative money flow for a specific time period. Note if we use the second formula of money flow index, then we do not need to make this calculation.

Last, but most certainly not least, we need to calculate the money flow index. All that we truly need are the positive and negative money flows. This can be calculated by subtracting 100 divided by 1 plus the money ratio from 100, this is Equation1 below. But there are other ways to do the calculation as well, I will show two different formulas to calculate the MFI below.

Summarized Steps:

  1. Calculate the typical price.

2. Calculate the money flow

3. Split the money flow into positive and negative money flows.

4. Optionally calculate the money ratio.

5. Calculate the Money Flow Index.

Image for post
Image for post
Image: MFI Formula Source: investopedia.com

If you prefer not to read this article and would like a video representation of it, you can check out the YouTube Video below. It goes through everything in this article with a little more detail, and will help make it easy for you to start programming . Or you can use both as supplementary materials for learning !

If you are interested in reading more on machine learning and/or algorithmic trading then you might want to read Hands-On Machine Learning for Algorithmic Trading: Design and implement investment strategies based on smart algorithms that learn from data using Python. The book will show you how to implement machine learning algorithms to build, train, and validate algorithmic models. It will also show you how to create your own algorithmic design process to apply probabilistic machine learning approaches to trading decisions, and the book will show you how to develop neural networks for algorithmic trading to perform time series forecasting and smart analytics.

Image for post
Image for post
Hands-On Machine Learning for Algorithmic Trading: Design and implement investment strategies based on smart algorithms that learn from data using Python

Programming

The first thing that I like to do before writing any code is to put a description of the program in comments.

#Description: This program uses the Money Flow Index to determine when to buy and sell stock

Next, import the libraries/dependencies that will be used throughout the program.

#Import the libraries
import warnings
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
plt.style.use('fivethirtyeight')
warnings.filterwarnings('ignore')

Now let’s load the data. Since I am using the website https://colab.research.google.com/ , I need to use that sites library to upload the data. The data contains stock data for Apple from 10/01/2010 to 09/09/2011.

#Load the data
from google.colab import files # Use to load data on Google Colab
files.upload() # Use to load data on Google Colab

Get the stock, store, and show the data.

#Get the stock quote
df = pd.read_csv('AAPL.csv')
#Set the date as the index
df = df.set_index(pd.DatetimeIndex(df['Date'].values))
#Show the data
df.head(5)
Image for post
Image for post
Sample of the data

Graph and visually show the data.

#Visually Show The Stock Price
#Create and plot the graph

plt.figure(figsize=(12.2,4.5)) #width = 12.2in, height = 4.5
plt.plot( df['Close'], label='Close Price')#plt.plot( X-Axis , Y-Axis, line_width, alpha_for_blending, label)
plt.title('Close Price History')
plt.xlabel('Date',fontsize=18)
plt.ylabel('Close Price USD ($)',fontsize=18)
plt.legend(df.columns.values, loc='upper left')
plt.show()
Image for post
Image for post
Plot of Apple Inc. Closing Price

Time to start preparing to do the calculations for MFI ! First, calculate and show the typical price.

#Calculate the typical price
typical_price = (df['Close'] + df['High'] + df['Low']) / 3
typical_price
Image for post
Image for post
The Typical Price

Get the time period.

period =  14 #The typical period used for MFI is 14 days

Calculate and show the Money Flow.

#Calculate the money flow
money_flow = typical_price * df['Volume']
money_flow
Image for post
Image for post
The Money Flow

Get all of the positive and negative money flows.

#Get all of the positive and negative money flows 
#where the current typical price is higher than the previous day's typical price, we will append that days money flow to a positive list
#and where the current typical price is lower than the previous day's typical price, we will append that days money flow to a negative list
#and set any other value to 0 to be used when summing

positive_flow =[] #Create a empty list called positive flow
negative_flow = [] #Create a empty list called negative flow
#Loop through the typical price
for i in range(1, len(typical_price)):
if typical_price[i] > typical_price[i-1]: #if the present typical price is greater than yesterdays typical price
positive_flow.append(money_flow[i-1])# Then append money flow at position i-1 to the positive flow list
negative_flow.append(0) #Append 0 to the negative flow list
elif typical_price[i] < typical_price[i-1]:#if the present typical price is less than yesterdays typical price
negative_flow.append(money_flow[i-1])# Then append money flow at position i-1 to negative flow list
positive_flow.append(0)#Append 0 to the positive flow list
else: #Append 0 if the present typical price is equal to yesterdays typical price
positive_flow.append(0)
negative_flow.append(0)

Get all of the positive and negative money flows within the time period.

#Get all of the positive and negative money flows within the time period
positive_mf =[]
negative_mf = []
#Get all of the positive money flows within the time period
for i in range(period-1, len(positive_flow)):
positive_mf.append(sum(positive_flow[i+1-period : i+1]))
#Get all of the negative money flows within the time period
for i in range(period-1, len(negative_flow)):
negative_mf.append(sum(negative_flow[i+1-period : i+1]))

Calculate and show the Money Flow Index (MFI).

mfi = 100 * (np.array(positive_mf) / (np.array(positive_mf)  + np.array(negative_mf) ))mfi
Image for post
Image for post
Sample of MFI

Graph and visually show the MFI.

# Visually Show The Money Flow Index
df2 = pd.DataFrame()
df2['MFI'] = mfi
#Create and plot the graph
plt.figure(figsize=(12.2,4.5)) #width = 12.2in, height = 4.5
plt.plot( df2['MFI'], label='MFI')#plt.plot( X-Axis , Y-Axis, line_width, alpha_for_blending, label)
plt.axhline(10, linestyle='--', color = 'orange') #Over Sold line (Buy)
plt.axhline(20, linestyle='--',color = 'blue') #Over Sold Line (Buy)
plt.axhline(80, linestyle='--', color = 'blue') #Over Bought line (Sell)
plt.axhline(90, linestyle='--', color = 'orange') #Over Bought line (Sell)
plt.title('MFI')
plt.ylabel('MFI Values',fontsize=18)
plt.legend(df2.columns.values, loc='upper left')
plt.show()
Image for post
Image for post
MFI Plot

Create and show a new data frame from the start of the time period to the rest of the data in the original data set. Add a new column to store the MFI. This will be used to show the buy and sell signals.

#Create a new data frame
new_df = pd.DataFrame()
new_df = df[period:]
new_df['MFI'] = mfi
#Show the new data frame
new_df
Image for post
Image for post

Create a function to get the buy and sell signals.

# Create a function to get the buy and sell signals
#MFI above 80 is considered overbought condition and MFI below 20 is considered oversold.
#MFI > 80 then Sell
#MFI < 20 then Buy

def get_signal(data, high, low):
buy_signal = [] #The stock was over sold
sell_signal = [] #The stock was over bought
for i in range(len(data['MFI'])):
if data['MFI'][i] > high: #Then the stock is over bought, you should sell
buy_signal.append(np.nan)
sell_signal.append(data['Close'][i])
elif data['MFI'][i] < low: #Then the stock is over sold, you should buy
buy_signal.append(data['Close'][i])
sell_signal.append(np.nan)
else:
buy_signal.append(np.nan)
sell_signal.append(np.nan)
return (buy_signal, sell_signal)

Add new columns to store the buy and sell signals in the new data frame.

#Add new columns (Buy & Sell)
new_df['Buy'] = get_signal(new_df, 80, 20)[0]
new_df['Sell'] = get_signal(new_df, 80, 20)[1]
#Show the new dataframe
new_df
Image for post
Image for post

Finally we get to put it all together and look at all of the data to see how well the MFI strategy performed on the data set. This will be achieved by plotting all of the data together.

# plot the close price history
plt.figure(figsize=(12.2,4.5))
plt.plot(new_df.index, new_df['Close'],alpha = 0.5, label='Close Price')
plt.scatter(new_df.index, new_df['Buy'], color = 'green', label='Oversold/ Buy Signal', marker = '^', alpha = 1)
plt.scatter(new_df.index, new_df['Sell'], color = 'red', label='Overbought/ Sell Signal', marker = 'v', alpha = 1)
plt.title('Close Price')
plt.xlabel('Date',fontsize=18)
plt.xticks(rotation = 45)
plt.ylabel('Close Price USD ($)',fontsize=18)
plt.legend( loc='upper left')
plt.show()
# plot the corresponding MFI values and significant levels
plt.figure(figsize=(12.4,3.5))
plt.title('MFI Plot')
plt.plot(new_df.index, new_df['MFI'])
plt.axhline(10, linestyle='--',color = 'orange') #Buy
plt.axhline(20, linestyle='--', color = 'blue') #Sell
plt.axhline(80, linestyle='--', color = 'blue') #Sell
plt.axhline(90, linestyle='--', color = 'orange') #Sell
plt.xlabel('Date',fontsize=18)
plt.xticks(rotation = 45)
plt.ylabel('MFI Values (0 - 100)',fontsize=18)
plt.show()
Image for post
Image for post

Now, by looking at this chart, I can see the sell signals in red pointing down and the buy signals in green pointing up. It looks like if I had bought, according to the indicators, Apple Inc. stock between April 2011 and May 2011 at an average price of about $12 per share (it’s actually less than $12 per share, but for now to keep it simple I will round up) and between June 2011 and July 2011 at an average price of about $11.75 per share (again I’m rounding up the price, the price is actually lower) then sold at the lowest point where the indicator tells me to sell, between the dates July 2011 and August 2011 at about $12.5 per share (this of course is rounding down, the actual price would be higher), then I would have made profited.

Again, I was taking a look at the worst case scenario and still would’ve profited. The MFI strategy was profitable in this case, but of course a lot more testing needs to be done with this strategy with a lot more data.

That’s it, we are done creating this program ! If you want to start an investment portfolio of your own, then sign up with WeBull using this link, deposit $100 and get 2 FREE stocks worth up to $1600 USD! It’s free stocks that you can either sell, or play with.

Thanks for reading this article I hope its helpful to you all! If you enjoyed this article and found it helpful please leave some claps to show your appreciation. Keep up the learning, and if you like machine learning, mathematics, computer science, programming or algorithm analysis, please visit and subscribe to my YouTube channels (randerson112358 & compsci112358 ).

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store