## What is the Moving Average Convergence Divergence (MACD) 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 historic time series stock price data

A great source to get historic stock price 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.

The **Adjusted Close **is adjusted for stock splits, dividend payout and other cooperate operations that affect the price (read more on Investopedia.org).

## Step 2: Make the MACD calculations

The formula for MACD = 12-Period EMA − 26-Period EMA (source)

As the description says, we need the **Exponential Moving Averages** (EMA) for a 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** method 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.

## Next step

Want to learn more about Python for Finance?

Check out my Online Courses in the menu. I have a highest rated course on Udemy.

Also, check out my FREE online video course with Python for Finance.

how do you export it to excel?

Hi Ramses,

you can see how to do it in the video. Also, download the Jupyter Notebook with the code.

But in general you can export a DataFrame by calling to_excel(“filename.xlsx”) on it.

For more details, please see the video.

Rune

Hi,

Can you make this update during the day as the stock price changes? How would you go about doing this?

Hi Ronan,

Great question.

The data source we use here is limited to be daily. We are using the Closing price (or Adj Close). Therefore, with this data source, you would only make trades once per day.

If you want to make day-trading you need a data source that provides prices on smaller interval. If you have that, you can use MACD. I would advice not to rely only on MACD.

Cheers, Rune