Everything You Need to Connect Your Python Trading Bot to MetaTrader 5
Build Your Own Algorithmic Trading Bot with Python
When it comes to day trading, MetaTrader is one of the giants in the room. It’s one of the world’s most popular day-trading platforms, with a rich set of features traders can access through the Meta Query Language (MQL). MetaTrader 5 (MT5) built on this history by exposing most of the functionality of MQL in a Python Library called MetaTrader5.
If you’re looking to get into algorithmic trading or to expand your trading bots functionality, MetaTrader is a great place to start.
In this article, I'll show you how to do this.
Why MetaTrader?
The MetaTrader5 platform offers many benefits for building an algorithmic trading bot.
It is fast. MT5 is very, very fast. This is important when you’re looking to get into high-frequency trading, and even more important when you’re looking to automate as much of your trading as possible.
It is widely used. In contrast to many of the platforms out there, MT5 is used around the world by various brokers. This means that anything you build on MT5 can be used and reused extensively.
It offers a desktop client-side app. While this can be a mixed blessing, for trading bot purposes, this means there are no API limits and much faster information access.
There Are Some Downsides
There are some definite downsides to using MT5, and it’s important to be aware of them.
The Python Library only works with the desktop app on Windows. This is probably the biggest gotcha with MT5 and I’ll call it out here to hopefully save you many hours of trying to figure it out on macOS/Linux. Practically speaking this is incredibly annoying as you’ll be restricted to using it on a Windows endpoint.
There are some weird gaps in the library. For whatever reason, there are a number of weird gaps in the MT5 Python Library. For instance, you cannot place a BUY STOP or SELL STOP order with an instant trailing stop. While I cover how to build your own in a future episode, it’s an odd omission for such a mature platform.
You -> MT5 -> Broker
This can be a point of confusion, so I’ll quickly outline it here. MT5 is a platform that brokers use to provide pricing information to their clients. For instance, I use IC Markets as my broker, so my MT5 is the version of MT5 that IC Markets provides me. I access the IC Markets pricing, which might be different from the pricing that I receive from a different broker.
You’ll need to figure out which broker you’d like to use.
This will make more sense when I show you how to connect to MT5, but for now, just be aware that when we talk about connecting to MT5, we’re really saying “Connect to the version of MT5 that your broker has provided”
How to Connect Python to MetaTrader 5
Create or Update settings.json
If this is the first exchange you’ve added in the book, you’ll need to create your settings.json
. This can be added anywhere on the filesystem of your computer, although many people simply add it straight to the project directory.
**NOTE**
If you're using git or some other version control system (VCS),
and your settings.json is located in your project directory,
**immediately** add this file to your .gitignore (or equivalent)!!!!
Once this is done, add the following:
"mt5": {
"live": {
"username": "Your_Username",
"password": "Your Password",
"server": "Your Server",
"mt5Pathway": "C:/Pathway/to/terminal64.exe",
"symbols": []
},
"paper": {
"username": "Your_Username",
"password": "Your Password",
"server": "Your Server",
"mt5Pathway": "C:/Pathway/to/terminal64.exe",
"symbols": []
}
}
Here you’ve defined the settings you’ll be using for your MT5, making provision for paper and live accounts. You’ll be filling out the details for these accounts next.
Note that on the GitHub project, this can be found in the file example_settings.json
as I’m not going to reveal my passwords :P
Create Your Logins
Create logins for your paper account (or testing account) and live account. This is done through your broker, who will give you the following MT5 login details:
username
which will be an eight-digit numberpassword
which will be auto-generated (I’d recommend immediately changing it)server
which will be the name of the server you should use
**Paper Account**: An account used for conducting fake or practice trades.
**Live Account**: An account used for conducting real trades.
Now, update the fields created in settings.json
with the details you’ve just received.
Locate terminal64.exe
The non-online version of MT5 requires you to install your brokers’ version of MetaTrader onto your computer. When you do this, it will install an executable called terminal64.exe
somewhere on your file system.
This is the executable you need to add to the mt5Pathway
reference in settings.json
.
For every default install I’ve ever done, this has always been located at C:/Program Files/<name of your broker> — MetaTrader 5/terminal64.exe
. For instance, with IC Markets it is C:/Program Files/ICMarkets — MetaTrader 5/terminal64.exe
.
Go and find your terminal64.exe
and add it to settings.json
in both the live
and paper
versions.
Add the metatrader_lib Folder
Making a trading bot as extensible as possible is critical to enable you to easily add new features, functions, and exchanges over time.
For this book, this is done by locating each exchange in its own folder. This creates a pseudo-library structure, where the library is responsible for:
- Connecting to an exchange
- Retrieving data from a specified exchange
- Formatting it into a Common Information Model (CIM)
- Returning a raw Pandas Dataframe
This allows the trading bot to apply your future indicators and strategies to any exchange you choose to add!
In this chapter, you’ll be building the first part of your library — connecting to an exchange.
Add the file mt5_interaction.py
In your newly created library folder, create a file called mt5_interaction.py
. It is through this file that you’ll:
- Receive general commands from your Algorithmic Trading Bot
- Translate them into MT5-specific commands
Start MT5
MT5 requires you to start and then log in to retrieve information. I’m not really sure why this is as the information for logging in is a subset of the information to start, however, it is what it is. It also took me a while to figure that out, with a ton of troubleshooting, so hopefully this helps!
The function below performs the following steps:
- Ensures the
username, password, server, and path
variables are in the correct format. - Attempts to initialize MT5 or returns an error
- Attempts to login to MT5 or returns an error
- If all is successful, returns true
Note. Custom error messages for the Algorithmic Trading Bot haven’t yet been covered, so only generic errors are returned.
Here’s the function:
import MetaTrader5
# Function to start Meta Trader 5 (MT5)
def start_mt5(username, password, server, path):
"""
Initializes and logs into MT5
:param username: 8-digit integer
:param password: string
:param server: string
:param path: string
:return: True if successful, Error if not
"""
# Ensure that all variables are the correct type
uname = int(username) # Username must be an int
pword = str(password) # Password must be a string
trading_server = str(server) # Server must be a string
filepath = str(path) # Filepath must be a string
# Attempt to start MT5
if MetaTrader5.initialize(login=uname, password=pword, server=trading_server, path=filepath):
# Login to MT5
if MetaTrader5.login(login=uname, password=pword, server=trading_server):
return True
else:
print("Login Fail")
quit()
return PermissionError
else:
print("MT5 Initialization Failed")
quit()
return ConnectionAbortedError
Get It Working
You’ll link MetaTrader 5 with the rest of your Python Trading Bot by integrating it into the start process of the bot. In the book, this is done by calling get_project_settings
, then check_exchanges
in __main__
as part of the startup procedure.
Get Project Settings
The get_project_settings
function is responsible for importing settings.json
into your project. The function does the following:
- Checks if the specified file exists. If not, returns an error.
- Opens the file
- Imports the settings
- Closes the file
- Returns a JSON object containing your settings
Note. Custom error messages for the Algorithmic Trading Bot haven’t yet been covered, so only generic errors are returned.
Add the following function to your main.py
:
def get_project_settings(import_filepath):
"""
Function to import settings from settings.json
:param import_filepath:
:return: JSON object with project settings
"""
# Test the filepath to sure it exists
if os.path.exists(import_filepath):
# Open the file
f = open(import_filepath, "r")
# Get the information from file
project_settings = json.load(f)
# Close the file
f.close()
# Return project settings to program
return project_settings
else:
return ImportError
Check Exchanges
The check_exchanges
function ensures that exchanges can be connected to. As you add more and more exchanges to your algorithmic trading bot, this function ensures that they all work, saving you from the frustration of “Why the heck didn’t this work!?!”.
If this is your first exchange, add the function def check_exchanges(project_settings):
to your main.py
Now add the lines to confirm that the exchange works for both paper and live trading:
def check_exchanges(project_settings):
"""
Function to check if exchanges are working
:param project_settings:
:return: Bool
"""
# Check MT5 Live trading
mt5_live_check = mt5_interaction.start_mt5(
username=project_settings["mt5"]["live"]["username"],
password=project_settings["mt5"]["live"]["password"],
server=project_settings["mt5"]["live"]["server"],
path=project_settings["mt5"]["live"]["mt5Pathway"],
)
if not mt5_live_check:
print("MT5 Live Connection Error")
return PermissionError
# Check MT5 Paper Trading
mt5_paper_check = mt5_interaction.start_mt5(
username=project_settings["mt5"]["paper"]["username"],
password=project_settings["mt5"]["paper"]["password"],
server=project_settings["mt5"]["paper"]["server"],
path=project_settings["mt5"]["paper"]["mt5Pathway"],
)
if not mt5_paper_check:
print("MT5 Paper Connection Error")
return PermissionError
# Return True if all steps pass
return True
Note. As custom error handling hasn’t yet been added, the errors will not be overly helpful at this stage. These are placeholders for an upcoming chapter.
Make It So
Finally, to make it work, update your __main__
as follows:
# Press the green button in the gutter to run the script.
if __name__ == '__main__':
# Import project settings
project_settings = get_project_settings(import_filepath=import_filepath)
# Check Exchanges
check_exchanges(project_settings=project_settings)
Now, define your import_filepath
variable in your main.py
so that the program knows where to locate the settings file. For instance, if your settings.json
is in the folder of your project, this would be:
import_filepath = "settings.json"
If all goes well, when you press play on your Integrated Development Environment (IDE), MetaTrader 5 should open!
You’re all set!
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
Links
- Project GitHub
- MetaTrader 5 website
- MetaTrader Python Documentation
- MetaTrader Python Package (PyPi)
- Meta Query Langage
- Build Your Own Algorithmic Trading Bot with Python Introduction
- IC Markets
- Pandas Dataframe
Full Code Samples
Main.py
import json
import os
from metatrader_lib import mt5_interaction
# Variable for the location of settings.json
import_filepath = "settings.json"
# Function to import settings from settings.json
def get_project_settings(import_filepath):
"""
Function to import settings from settings.json
:param import_filepath:
:return: JSON object with project settings
"""
# Test the filepath to sure it exists
if os.path.exists(import_filepath):
# Open the file
f = open(import_filepath, "r")
# Get the information from file
project_settings = json.load(f)
# Close the file
f.close()
# Return project settings to program
return project_settings
else:
return ImportError
def check_exchanges(project_settings):
"""
Function to check if exchanges are working
:param project_settings:
:return: Bool
"""
# Check MT5 Live trading
mt5_live_check = mt5_interaction.start_mt5(
username=project_settings["mt5"]["live"]["username"],
password=project_settings["mt5"]["live"]["password"],
server=project_settings["mt5"]["live"]["server"],
path=project_settings["mt5"]["live"]["mt5Pathway"],
)
if not mt5_live_check:
print("MT5 Live Connection Error")
return PermissionError
# Check MT5 Paper Trading
mt5_paper_check = mt5_interaction.start_mt5(
username=project_settings["mt5"]["paper"]["username"],
password=project_settings["mt5"]["paper"]["password"],
server=project_settings["mt5"]["paper"]["server"],
path=project_settings["mt5"]["paper"]["mt5Pathway"],
)
if not mt5_paper_check:
print("MT5 Paper Connection Error")
return PermissionError
# Return True if all steps pass
return True
# Press the green button in the gutter to run the script.
if __name__ == '__main__':
# Import project settings
project_settings = get_project_settings(import_filepath=import_filepath)
# Check Exchanges
check_exchanges(project_settings=project_settings)
mt5_interaction.py
import MetaTrader5
# Function to start Meta Trader 5 (MT5)
def start_mt5(username, password, server, path):
"""
Initializes and logs into MT5
:param username: 8 digit integer
:param password: string
:param server: string
:param path: string
:return: True if successful, Error if not
"""
# Ensure that all variables are the correct type
uname = int(username) # Username must be an int
pword = str(password) # Password must be a string
trading_server = str(server) # Server must be a string
filepath = str(path) # Filepath must be a string
# Attempt to start MT5
if MetaTrader5.initialize(login=uname, password=pword, server=trading_server, path=filepath):
# Login to MT5
if MetaTrader5.login(login=uname, password=pword, server=trading_server):
return True
else:
print("Login Fail")
quit()
return PermissionError
else:
print("MT5 Initialization Failed")
quit()
return ConnectionAbortedError