Pandas: Calculate the Moving Average Convergence Divergence (MACD) for a Stock

What is the Moving Average Convergence Divergence Indicator?

Moving Average Convergence Divergence (MACD) is a trend-following momentum indicator that shows the relationship between two moving averages of a security’s price. The MACD is calculated by subtracting the 26-period Exponential Moving Average (EMA) from the 12-period EMA.

https://www.investopedia.com/terms/m/macd.asp

That is easy to understand, right?

The good news is that it is easy to calculate using the Pandas DataFrames.

Well, the MACD is a technical indicator that helps to understand if it is a bullish or bearish market. That is, it can help the investor to understand if he should buy or sell the stock.

Step 1: Get the stock data

A great source to get stock data is by using the Pandas-datareader library to collect it.

import pandas_datareader as pdr
import datetime as dt

start = dt.datetime(2020, 1, 1)
end = dt.datetime.now()
ticker = pdr.get_data_yahoo("AAPL", start, end)['Adj Close']
print(ticker)

Here we collect it for Apple (ticker AAPL) from the beginning of the year 2020.

Date
2020-01-02    298.292145
2020-01-03    295.392120
2020-01-06    297.745880
2020-01-07    296.345581
2020-01-08    301.112640
                 ...    
2020-08-05    439.457642
2020-08-06    454.790009
2020-08-07    444.450012
2020-08-10    450.910004
2020-08-11    444.095001
Name: Adj Close, Length: 154, dtype: float64

Note that we only keep the Adjusted Close (Adj Close) column to make our calculations.

Step 2: Make the calculations

As the description says, we need the Exponential Moving Averages for a rolling 12-days and 26-days window.

Luckily, the Pandas DataFrame provides a function ewm(), which together with the mean-function can calculate the Exponential Moving Averages.

exp1 = ticker.ewm(span=12, adjust=False).mean()
exp2 = ticker.ewm(span=26, adjust=False).mean()
macd = exp1 - exp2

But more is needed. We need to make a signal line, which is also defined.

A nine-day EMA of the MACD called the “signal line,” is then plotted on top of the MACD line, which can function as a trigger for buy and sell signals.

https://www.investopedia.com/terms/m/macd.asp

Hence, we end up with the following.

exp1 = ticker.ewm(span=12, adjust=False).mean()
exp2 = ticker.ewm(span=26, adjust=False).mean()
macd = exp1 - exp2
exp3 = macd.ewm(span=9, adjust=False).mean()

Step 3: Plot the data

We need to plot two y-scales for the plot. One for the MACD and the 9 day EMA of MACD. And one for the actually stock price.

Luckily the Pandas plot function supports having two y-axis.

macd.plot(label='AAPL MACD', color='g')
ax = exp3.plot(label='Signal Line', color='r')
ticker.plot(ax=ax, secondary_y=True, label='AAPL')

As you see, the first two calls to plot use the same axis (the left side) and the final one on ticker, uses the secondary_y (the right side axis).

Then we need to setup labels, legends, and names on axis.

ax.set_ylabel('MACD')
ax.right_ax.set_ylabel('Price $')
ax.set_xlabel('Date')
lines = ax.get_lines() + ax.right_ax.get_lines()
ax.legend(lines, [l.get_label() for l in lines], loc='upper left')

The variable lines collects the lines plotted on both y-axis and then makes the legend. This is needed, otherwise only the last legend will be visible.

All together it becomes.

import pandas_datareader as pdr
import datetime as dt
import matplotlib.pyplot as plt

start = dt.datetime(2020, 1, 1)
end = dt.datetime.now()
ticker = pdr.get_data_yahoo("AAPL", start, end)['Adj Close']

exp1 = ticker.ewm(span=12, adjust=False).mean()
exp2 = ticker.ewm(span=26, adjust=False).mean()
macd = exp1 - exp2
exp3 = macd.ewm(span=9, adjust=False).mean()
macd.plot(label='AAPL MACD', color='g')
ax = exp3.plot(label='Signal Line', color='r')
ticker.plot(ax=ax, secondary_y=True, label='AAPL')

ax.set_ylabel('MACD')
ax.right_ax.set_ylabel('Price $')
ax.set_xlabel('Date')
lines = ax.get_lines() + ax.right_ax.get_lines()
ax.legend(lines, [l.get_label() for l in lines], loc='upper left')
plt.show()

Resulting in the graph.

Result

When the signal line (red one) crosses the MACD (green) line, it is time to sell if the green is below and buy if the green is above.

Notice that this is done on historical data and is no guarantee it will work in the future. While the results look pretty promising, it is not wise to make your investments solely on one indicator.

Leave a Reply