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.

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.