7 min read

How to Add the MACD Indicator to Your MetaTrader 5 Python Trading Bot

Learn how to add the MACD Technical Indicator to Your Trading Bot.
How to Add the MACD Indicator to Your MetaTrader 5 Python Trading Bot

The Moving Average Convergence/Divergence technical indicator (MACD) is one of the most popular momentum indicators in trading. Traders from all different markets, including FOREX, Cryptocurrencies, Stocks, and Futures, use it due to its simplicity, flexibility, and applicability.

In this article, I’m going to show you how easy it is to add this powerful indicator to your trading bot.


By The End of This Article

By the end of this article, you’ll be able to generate a graph that looks like this:

Example of BTCUSD with the MACD indicator added
BTCUSD with MACD Indicator

Prior Knowledge

There are a few pieces of information you need in order to add this indicator to your trading bot:

  1. TA-Lib. I use the open-source TA-Lib library to generate the signal. There is simply nothing faster. If you’re looking for insight on how to install it on Windows, check out this article.
  2. Retrieval of Candlestick (OHLC) data in a Pandas Dataframe. You need to be able to retrieve a minimum of 200 candlesticks and preferably at least 1000. If you’re looking for information on how to get this from MetaTrader, check out this series or YouTube video.
  3. Timeframe in a column called human_time . Every exchange has a slightly different way of representing time. MetaTrader 5 uses an integer Unix Time, so make sure you convert it to a Python Datetime object using this code: dataframe['human_time'] = pandas.to_datetime(dataframe['time'], unit='s')
  4. The following libraries installed in your Python environment: Pandas, Plotly

About the MACD

In a previous post, I did a deep dive into the MACD, including how it’s used, how it’s calculated, and some of its weaknesses. I recommend you have a read if you’d like to learn more about the theoretical background of MACD.

For this article, we’ll be focusing on the quantitative data that the MACD technical indicator uses and generates, these being:

  1. The input Exponential Moving Averages (EMA’s)
  2. The output MACD Line
  3. The output MACD Signal Line
  4. The output MACD Histogram

MACD Technical Indicator Code

Let’s convert our Candlestick data into the required MACD items.

Calculate MACD Line, MACD Signal Line, and MACD Histogram

To do this, create a new file called indicator_lib.py in your project (or add it to your existing one if you’ve been following my series).

In this file, add the following:

import talib 
 
def calc_macd(raw_candlestick_dataframe): 
    """ 
    Function to calculate a MACD indicator 
    :param dataframe: dataframe of the raw candlestick data 
    :return: dataframe with MACD values included 
    """ 
    # Simplify the variable 
    dataframe = raw_candlestick_dataframe.copy() 
    # Calculate the MACD values in the dataframe 
    dataframe['macd'], dataframe['macd_signal'], dataframe['macd_histogram'] = talib.MACD( 
        dataframe['close'], 
        fastperiod=12, 
        slowperiod=26, 
        signalperiod=9 
    ) 
    print(dataframe)

If you added this function to your __main__ and passed it a dataframe, you’d get something back that looks like this:

Three MACD technical information. MACD, MACD Signal, MACD Histogram

Your values will probably be different depending on what time you run it. You can see here that the initial values are NaN (Not a Number) as the EMA hasn’t been calculated at this stage.

Prepare Code to Pass to Plotly

Data exploration is a critical component of forex trading strategy development, so now we’ll prepare our indicator for displaying.

To do this, update your function as follows:

# Function to calculate a MACD Indicator 
def calc_macd(dataframe, display=False, symbol=None): 
    """ 
    Function to calculate a MACD indicator 
    :param dataframe: dataframe of the raw candlestick data 
    :param display: boolean to determine whether the MACD indicator should be displayed 
    :param symbol: string of the symbol to be displayed on the graph 
    :return: dataframe with MACD values included 
    """ 
    # Calculate the MACD values in the dataframe 
    dataframe['macd'], dataframe['macd_signal'], dataframe['macd_histogram'] = talib.MACD( 
        dataframe['close'], 
        fastperiod=12, 
        slowperiod=26, 
        signalperiod=9 
    ) 
    if display: 
        title = symbol + " MACD Indicator" 
        fig = display_lib.display_macd_indicator( 
            dataframe=dataframe, 
            title=title 
        ) 
        # Return the dataframe 
        return fig 
    else: 
        # If not displaying, return the dataframe 
        return dataframe

In this update we:

  1. Add in parameters to manage whether the symbol should be displayed or not
  2. Add branching logic to determine whether to return the dataframe with calculated values, or a figure with the values added

Now all we need to do is add in a library to display the indicator

Display MACD Indicator with Plotly

Data exploration is a critical part of trading strategy development, regardless of what market you’re trading.

One of the best ways I’ve found to explore the data is through Plotly, which has a great open-source library of charts available. We’ll leverage Plotly, and their associated Dash display library, to display our data.

If you’d like to learn more about Forex and Crypto trading, why not sign up to my YouTube Channel and Medium? The helpful content is generated for builders and explorers just like you!

The MACD has three different pieces of information which need to be displayed:

  1. The MACD Line
  2. The MACD Signal Line
  3. The MACD Histogram

Create Initial MACD Indicator Figure

We do this by layering each piece of information onto the graph, then creating two different Y-axis.

To do this, create a file called display_lib.py in your project (or add this code to it if you’ve already got it).

Then, construct the figure using the following code:

import plotly.graph_objects as go 
from plotly.subplots import make_subplots 
 
 
# Function to display a MACD indicator 
def display_macd_indicator(dataframe, title): 
    """ 
    Function to display a MACD indicator 
    :param dataframe: dataframe with all values 
    :param title: Title of the data 
    :return: figure with all data 
    """ 
    # Set up the figure 
    fig = make_subplots(specs=[[{"secondary_y": True}]]) 
    # Add in the candlesticks for the original data 
    fig = fig.add_trace( 
        go.Candlestick( 
            x=dataframe['human_time'], 
            open=dataframe['open'], 
            high=dataframe['high'], 
            close=dataframe['close'], 
            low=dataframe['low'], 
            name=title 
        ), 
        secondary_y=False 
    ) 
    # Add in the MACD line 
    fig = fig.add_trace( 
        go.Scatter( 
            x=dataframe['human_time'], 
            y=dataframe['macd'], 
            name="MACD" 
        ), 
        secondary_y=True 
    ) 
    # Add in the MACD signal line 
    fig = fig.add_trace( 
        go.Scatter( 
            x=dataframe['human_time'], 
            y=dataframe['macd_signal'], 
            name="MACD Signal" 
        ), 
        secondary_y=True 
    ) 
    # Add in the MACD histogram 
    fig = fig.add_trace( 
        go.Bar( 
            x=dataframe['human_time'], 
            y=dataframe['macd_histogram'], 
            name="MACD Histogram" 
        ), 
        secondary_y=True 
    ) 
    return fig

This code constructs the graph with four elements:

  1. The raw OHLC Candlestick data to provide the actual prices
  2. The MACD Line, MACD Signal Line, and MACD Histogram

It assigns all the MACD components to a secondary Y axis.

Create A Display Function

Now we can display our awesome MACD Technical Indicator.

Add a new function and import statement to your display_lib :

from dash import Dash, html, dcc 
 
# Function to display a plotly graph in dash 
def display_graph(plotly_fig, graph_title, dash=False): 
    """ 
    Function to display a plotly graph using Dash 
    :param plotly_fig: plotly figure 
    :param graph_title: string 
    :param dash: boolean to determine whether to run the dash server 
    :return: None 
    """ 
    # Add in layout features for each plotly figure 
    plotly_fig.update_layout( 
        xaxis_rangeslider_visible=False, 
        autosize=True, 
        height=800 
    ) 
    plotly_fig.update_yaxes(automargin=True) 
 
    if dash: 
        # Create the Dash object 
        app = Dash(__name__) 
        # Construct view 
        app.layout = html.Div(children=[ 
            html.H1(children=graph_title), 
            html.Div("Created by James Hinton from AlgoQuant.Trade"), 
            dcc.Graph( 
                id=graph_title, 
                figure=plotly_fig 
            ) 
        ]) 
        # Run the image 
        app.run_server(debug=True) 
    else: 
        plotly_fig.show()

This function takes the figure created earlier and passes it into a series of display layouts. This includes:

  1. Some formatting to remove a range slider
  2. Setting the height to be 800px
  3. Allowing Plotly to figure out the margins

Update Main

All that’s left is to update our main function so that it will display the graph. I’ll post what mine looks like below, just remember that I’ve included how I get my OHCL data (which may be different from you):

# Main function 
if __name__ == '__main__': 
    print("Let's build an awesome trading bot!!!") 
    # Import settings.json 
    project_settings = get_project_settings(import_filepath=settings_filepath) 
    # Start MT5 
    mt5_start = mt5_startup(project_settings=project_settings) 
    pandas.set_option('display.max_columns', None) 
    comment = "ema_cross_strategy" 
    # If MT5 starts correctly, lets query for some candles 
    if mt5_start: 
        symbol = "BTCUSD.a" 
        # Get data from MT5 
        data = mt5_lib.query_historic_data( 
            symbol=symbol, 
            timeframe="M30", 
            number_of_candles=1000 
        ) 
        # Get the MACD data 
        macd_fig = indicator_lib.calc_macd(data, display=True, symbol=symbol) 
        display_lib.display_graph(plotly_fig=macd_fig, graph_title="MACD_Example", dash=True)

If you’d like to learn how to build your own MetaTrader 5 Python Trading Bot, then check out my series on YouTube.

Advanced Updates

As you can probably tell, by coding the functions like this, you have the ability to modify almost every aspect of the MACD Indicator. Some popular options include:

  1. Modifying the input EMAs (just make sure your dataframe is big enough)
  2. Integrating a histogram strength calculation

Let me know in the comments how you’ve modified it.

Quick Call to Action

As a creator, I love what I do. The process of designing content, developing solutions, and sharing it in meaningful ways is something I deeply enjoy. My ability to monetize this process is critical to my ability to keep doing this. You can help me continue to do this by:

  1. Subscribing to my Medium and Medium Email list
  2. Subscribing to my YouTube channel
  3. Signing up to Medium via my referral link, where Medium will contribute 50% of the fees to me while costing you nothing extra
  4. Signing Up to my website AlgoQuant.Trade

I also love hearing from my readers, so reach out to me on LinkedIn, Instagram, or my contact page.

Say Hi!

I love hearing from my readers, so feel free to reach out. It means a ton to me when you clap for my articles or drop a friendly comment — it helps me know that my content is helping.

Resources

  1. TA-Lib
  2. TA-Lib Windows Install
  3. How to Build a MetaTrader 5 Python Trading Bot
  4. How to Retrieve 50,000 candlesticks from MetaTrader
  5. Pandas Python Library
  6. Plotly Python Library