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

Use MFI to know when to buy and sell stock

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.

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.

# 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 librariesimport warningsimport numpy as npimport pandas as pdimport matplotlib.pyplot as pltplt.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 datafrom google.colab import files # Use to load data on Google Colabfiles.upload() # Use to load data on Google Colab`

Get the stock, store, and show the data.

`#Get the stock quotedf = pd.read_csv('AAPL.csv')#Set the date as the indexdf = df.set_index(pd.DatetimeIndex(df['Date'].values))#Show the datadf.head(5)`

Graph and visually show the data.

`#Visually Show The Stock Price#Create and plot the graphplt.figure(figsize=(12.2,4.5)) #width = 12.2in, height = 4.5plt.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()`

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

`#Calculate the typical pricetypical_price = (df['Close'] + df['High'] + df['Low']) / 3typical_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 flowmoney_flow = typical_price * df['Volume']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 summingpositive_flow =[] #Create a empty list called positive flownegative_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 periodpositive_mf =[]negative_mf = [] #Get all of the positive money flows within the time periodfor 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`

Graph and visually show the MFI.

`# Visually Show The Money Flow Indexdf2 = pd.DataFrame()df2['MFI'] = mfi#Create and plot the graphplt.figure(figsize=(12.2,4.5)) #width = 12.2in, height = 4.5plt.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()`

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 framenew_df = pd.DataFrame()new_df = df[period:]new_df['MFI'] = mfi#Show the new data framenew_df`

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 Buydef get_signal(data, high, low):  buy_signal = [] #The stock was over sold  sell_signal = [] #The stock was over boughtfor 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 dataframenew_df`

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 historyplt.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 levelsplt.figure(figsize=(12.4,3.5))plt.title('MFI Plot')plt.plot(new_df.index, new_df['MFI'])plt.axhline(10, linestyle='--',color = 'orange') #Buyplt.axhline(20, linestyle='--', color = 'blue') #Sellplt.axhline(80, linestyle='--', color = 'blue') #Sellplt.axhline(90, linestyle='--', color = 'orange') #Sellplt.xlabel('Date',fontsize=18)plt.xticks(rotation = 45)plt.ylabel('MFI Values (0 - 100)',fontsize=18)plt.show()`

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.

Written by