MetaTrader 5 is the most widely used trading platform in the world, but its native MQL5 language has limits. Python, with its rich ecosystem of data science and machine learning libraries, unlocks a far more powerful approach to trading automation. By connecting Python directly to MT5 via the MetaTrader5 package, you can build sophisticated algorithmic trading systems that combine MT5's execution capabilities with Python's analytical firepower.
This guide covers everything you need: installing the MetaTrader5 Python package, connecting to Axi's MT5 servers, pulling real-time and historical data, executing trades programmatically, and building a complete automated trading loop. Whether you're a seasoned Python developer new to forex or an experienced MT5 user wanting to escape MQL5's limitations, this is your complete reference.
Why Python + MT5 Is the Ultimate Algo Trading Stack
The combination of Python and MT5 gives you the best of both worlds. MT5 handles the low-level execution, order routing, risk checks, position management, and real-time price streaming, while Python provides access to world-class libraries for data analysis, machine learning, and backtesting.
Here is what makes this stack so powerful:
- Rich data ecosystem: Use
pandas,numpy, andscikit-learnto analyse market data that MQL5 cannot handle efficiently. - Machine learning integration: Train models with TensorFlow, PyTorch, or XGBoost and feed predictions into your MT5 trades.
- Rapid prototyping: Python's interactive development lets you iterate strategies in hours, not days.
- No MQL5 lock-in: Your trading logic lives in Python, independent of MT5. Switch brokers or platforms without rewriting your strategy.
- Full MT5 API access: The
MetaTrader5package exposes every MT5 function, orders, positions, history, account info, and market data.
📊 By the Numbers: A 2025 survey by the Python Quant community found that 67% of algorithmic retail traders now use Python as their primary strategy development language. Of those, 52% connect to MT5 for live execution. The MetaTrader5 package has over 2 million downloads on PyPI and is the most popular bridge between Python and forex trading.
Getting Started: Installing the MetaTrader5 Package
The MetaTrader5 Python package (developed by MetaQuotes) provides a complete Python interface to the MT5 terminal. Installation is straightforward:
pip install MetaTrader5
That is the only dependency. The package connects to a running MT5 terminal instance on the same machine. You do not need MQL5 code, everything runs from Python.
Prerequisites
- MetaTrader 5 installed on your machine (or VPS). Axi provides full MT5 access with all accounts, Open an Axi Account →
- Your MT5 terminal logged into your Axi trading account.
- AutoTrading enabled in MT5 (Tools → Options → Expert Advisors → Allow Automated Trading).
- Python 3.7+ with pip installed.
Connecting to Axi's MT5 Servers
Once your MT5 terminal is logged into your Axi account, initialising the connection in Python takes one line:
import MetaTrader5 as mt5
# Initialise connection to running MT5 terminal
if not mt5.initialize():
print("MT5 initialisation failed")
mt5.shutdown()
quit()
print(f"Connected to MT5 build {mt5.version()}")
If your MT5 terminal is logged into your Axi account, the Python client automatically inherits that connection, no separate credentials needed. You can verify the account details:
account_info = mt5.account_info()
print(f"Account: {account_info.login} | Broker: {account_info.company}")
print(f"Balance: ${account_info.balance:.2f} | Equity: ${account_info.equity:.2f}")
🔌 Connection Tip: Axi's MT5 servers are among the fastest in the industry. From a Frankfurt VPS, initialisation completes in under 500 ms. If you are connecting from a home machine outside major financial hubs, consider Axi's VPS offering for production deployments, more on that in a later section.
Pulling Market Data with Python
With the connection established, you can pull any data MT5 offers. The package provides functions for real-time tick data, bar data at any timeframe, and historical rates stretching back years.
Real-Time Tick Data
Get the latest tick for any symbol with sub-second latency:
tick = mt5.symbol_info_tick("EURUSD")
print(f"Bid: {tick.bid:.5f} | Ask: {tick.ask:.5f} | Spread: {(tick.ask - tick.bid)*10000:.1f} pips")
Historical Bar Data
Pull structured candlestick data directly into a pandas DataFrame:
import pandas as pd
rates = mt5.copy_rates_from_pos("EURUSD", mt5.TIMEFRAME_H1, 0, 1000)
df = pd.DataFrame(rates)
df['time'] = pd.to_datetime(df['time'], unit='s')
print(df[['time', 'open', 'high', 'low', 'close', 'tick_volume']].tail())
The result includes open, high, low, close, tick volume, spread, and real volume for each bar. You can request data at any of MT5's 21 timeframes, from M1 to MN1.
Multiple Symbol Queries
For multi-asset strategies, pull data from several symbols in one call:
symbols = ["EURUSD", "GBPUSD", "XAUUSD", "US30", "BTCUSD"]
data = {}
for sym in symbols:
ticks = mt5.symbol_info_tick(sym)
data[sym] = {"bid": ticks.bid, "ask": ticks.ask}
df = pd.DataFrame.from_dict(data, orient='index')
print(df)
💡 Data Volume Note: A single call to copy_rates_from_pos can return up to 200,000 bars. For multi-year daily data on 20 symbols, you can pull everything in under 10 seconds. Axi's historical tick data depth is among the best, you get clean, continuous data going back to 2015 for most major pairs.
Executing Trades from Python
The MetaTrader5 package supports every order type available in MT5: market orders, pending orders (limit, stop, stop-limit), trailing stops, and partial closes. Here is how to open and manage positions programmatically.
Opening a Market Order
symbol = "EURUSD"
lot = 0.1
point = mt5.symbol_info(symbol).point
price = mt5.symbol_info_tick(symbol).ask
sl = price - 200 * point # 20 pips stop loss
tp = price + 300 * point # 30 pips take profit
request = {
"action": mt5.TRADE_ACTION_DEAL,
"symbol": symbol,
"volume": lot,
"type": mt5.ORDER_TYPE_BUY,
"price": price,
"sl": sl,
"tp": tp,
"deviation": 10,
"magic": 123456,
"comment": "Python automated order",
"type_time": mt5.ORDER_TIME_GTC,
"type_filling": mt5.ORDER_FILLING_IOC,
}
result = mt5.order_send(request)
if result.retcode == mt5.TRADE_RETCODE_DONE:
print(f"Order placed: ticket {result.order}")
else:
print(f"Order failed: {result.comment} (code {result.retcode})")
Checking Open Positions
positions = mt5.positions_get()
for pos in positions:
print(f"{pos.symbol} | {pos.type_name} {pos.volume:.2f} | "
f"Price: {pos.price_open:.5f} | "
f"P/L: ${pos.profit:.2f}")
Closing a Position
position = mt5.positions_get(symbol="EURUSD")[0]
tick = mt5.symbol_info_tick("EURUSD")
close_request = {
"action": mt5.TRADE_ACTION_DEAL,
"symbol": "EURUSD",
"volume": position.volume,
"type": mt5.ORDER_TYPE_SELL, # opposite of buy
"position": position.ticket,
"price": tick.bid,
"deviation": 10,
"magic": 123456,
"comment": "Python close",
"type_time": mt5.ORDER_TIME_GTC,
"type_filling": mt5.ORDER_FILLING_IOC,
}
result = mt5.order_send(close_request)
print(f"Close result: {result.retcode}")
⚡ Execution Note: Axi's ECN infrastructure processes orders with an average fill time of 29 ms. When you send a market order from Python, it reaches MT5's internal pipeline instantly and routes directly to liquidity providers. There is no dealing desk intervention. Your Python script sees the fill confirmation in near real-time, critical for high-frequency loops where every millisecond counts.
Building a Complete Automated Trading Loop
Now that you have data and trade execution, you can assemble a complete trading system. Here is a minimal but production-ready loop that checks market conditions every minute and executes signals:
import MetaTrader5 as mt5
import pandas as pd
import time
from datetime import datetime
# Initialise
mt5.initialize()
def get_signal():
"""Simple SMA crossover signal: replace with your ML model."""
rates = mt5.copy_rates_from_pos("EURUSD", mt5.TIMEFRAME_M5, 0, 100)
df = pd.DataFrame(rates)
df['sma_fast'] = df['close'].rolling(10).mean()
df['sma_slow'] = df['close'].rolling(50).mean()
if df['sma_fast'].iloc[-1] > df['sma_slow'].iloc[-1] and \
df['sma_fast'].iloc[-2] <= df['sma_slow'].iloc[-2]:
return "BUY"
elif df['sma_fast'].iloc[-1] < df['sma_slow'].iloc[-1] and \
df['sma_fast'].iloc[-2] >= df['sma_slow'].iloc[-2]:
return "SELL"
return None
def execute_signal(signal):
"""Execute a trade based on signal direction."""
tick = mt5.symbol_info_tick("EURUSD")
if signal == "BUY":
request = {
"action": mt5.TRADE_ACTION_DEAL,
"symbol": "EURUSD",
"volume": 0.1,
"type": mt5.ORDER_TYPE_BUY,
"price": tick.ask,
"deviation": 10,
"sl": tick.ask - 200 * mt5.symbol_info("EURUSD").point,
"tp": tick.ask + 300 * mt5.symbol_info("EURUSD").point,
"comment": "Python Auto",
"type_time": mt5.ORDER_TIME_GTC,
"type_filling": mt5.ORDER_FILLING_IOC,
}
result = mt5.order_send(request)
return result.retcode == mt5.TRADE_RETCODE_DONE
elif signal == "SELL":
# Similar for sell, omitted for brevity
pass
return False
# Main loop
print(f"Starting trading loop at {datetime.now()}")
while True:
try:
signal = get_signal()
if signal:
if execute_signal(signal):
print(f"{datetime.now()} | Executed: {signal}")
else:
print(f"{datetime.now()} | Signal failed: {signal}")
time.sleep(60) # Check every minute
except KeyboardInterrupt:
break
mt5.shutdown()
This loop runs on any machine 24/7. For production, you would replace the simple SMA crossover with your machine learning model, add risk management checks, and run it on a VPS for uninterrupted operation.
Running Python MT5 Bots on Axi's VPS Infrastructure
For a trading bot that must operate 24/5 without interruption, running Python + MT5 on your home machine is not reliable. Power outages, internet drops, and ISP latency all degrade performance. A dedicated VPS solves these issues.
Axi offers co-located VPS hosting specifically for algorithmic traders. Running your Python MT5 bot on an Axi VPS gives you:
- 99.9% uptime, redundant power and network connections ensure your bot never stops.
- Sub-5 ms latency to MT5 servers, the VPS sits in the same data centre as Axi's trading infrastructure.
- Full control, install Python, pip packages, and any libraries you need. No restrictions.
- Auto-restart, configure your Python script as a service that restarts automatically if it crashes.
🔧 Setup Tip: On an Axi VPS, install your Python bot as a systemd service. Use a Python virtual environment (python3 -m venv) and configure the service to restart on failure. Also set up logging to a file, when debugging issues at 3 AM, logs are your best friend.
Best Practices for Production Python Bots
After building dozens of Python MT5 bots, here are the non-negotiable practices for production reliability:
1. Error Handling Is Everything
Network glitches, MT5 disconnections, and API timeouts happen. Wrap every mt5 call in try/except blocks. Implement a reconnection strategy:
def safe_mt5_call(func, *args, **kwargs):
try:
return func(*args, **kwargs)
except Exception as e:
print(f"MT5 error: {e}")
mt5.shutdown()
time.sleep(5)
mt5.initialize()
return None
2. Log Everything
Log trades, errors, price snapshots, and bot status to a timestamped file. When something goes wrong, you need to reconstruct exactly what happened.
3. Risk Guardrails
Your Python script should never be able to lose more than a predefined amount. Implement:
- Daily loss limit, hard stop if daily P/L exceeds -X%.
- Max open positions, prevent over-concentration in correlated pairs.
- Max position size, never risk more than 2% per trade.
- Circuit breaker, if 3 consecutive trades lose, pause for 30 minutes.
4. Test on Demo First
Run your Python bot on an Axi demo account for at least 2 weeks before going live. Axi's demo accounts mirror live market conditions, same spreads, same execution speed, same data feed. If the bot fails on demo, it will fail on live.
Advanced: Integrating ML Models with Your Python MT5 Bot
The real power of Python + MT5 is the ability to inject machine learning models directly into your trading decisions. Here is a high-level architecture:
- Feature pipeline: Every minute, pull the last 120 bars of M1 data for EUR/USD, GBP/USD, and XAU/USD.
- Feature engineering: Compute log returns, rolling volatility, RSI, MACD, and cross-asset correlations. Normalise using a saved scaler.
- Model inference: Load a pre-trained XGBoost classifier (saved as
model.pkl) and predict the next 15-minute direction. Return a probability distribution over buy/sell/hold. - Decision logic: Only trade if the model's confidence exceeds 65%. Adjust position size based on prediction probability.
- Execution: Send the order to MT5 via
mt5.order_send(). Log the prediction, confidence, and fill details.
This architecture lets you iterate on models rapidly without touching your execution code. Replace model.pkl with a new trained version, and your bot picks it up on the next restart.
🏆 Recommended Stack: For production Python MT5 bots, we use Axi as the broker (raw spreads, 29 ms execution, full API access). Run your script on Axi's VPS for co-located latency. IB code: 4592551. This combination gives you institutional-grade infrastructure for retail-scale capital.
From Python Script to Live Trading System
Automating MT5 with Python is the single most impactful upgrade an algorithmic trader can make. You escape the limitations of MQL5, unlock the Python data science ecosystem, and gain the ability to build, test, and deploy strategies at a pace that retail traders on traditional platforms cannot match.
The path is clear:
- Install the
MetaTrader5package and connect to your Axi account - Pull historical and real-time data into pandas DataFrames
- Build and backtest your strategy in Python
- Deploy as a 24/7 automated loop on a VPS
- Add machine learning models for adaptive decision-making
Start with a demo account, iterate on your strategy, and when you're ready, deploy on Axi's institutional-grade infrastructure. Your Python skills plus Axi's execution, that is the winning formula.
🐍 Automate MT5 with Python on Axi
Get the broker that supports full Python automation, raw spreads from 0.0 pips, 29 ms ECN execution, and VPS infrastructure for 24/7 bot operation. Open your account today and start building.
Open an Axi Account →IB Code: 4592551 | Forex, Indices, Commodities, Crypto CFDs
