The Python-MT5 Integration Architecture
MetaTrader 5 provides a native Python package allowing programmatic account authorization, historical tick retrieval, and direct order placement. In production, however, the terminal connection can drop due to broker server restarts, weekend market freezes, or latency spikes.
Robust Order Placement Wrapper in Python
import MetaTrader5 as mt5
import time
import logging
def safe_send_order(symbol: str, action: str, volume: float, sl_points: int, tp_points: int) -> dict:
'''Sends a market order to MT5 terminal with retry logic and error logging.'''
if not mt5.terminal_info().connected:
logging.error("MT5 terminal disconnected. Attempting reconnection...")
mt5.initialize()
symbol_info = mt5.symbol_info(symbol)
if not symbol_info or not symbol_info.visible:
return {"success": False, "error": f"Symbol {symbol} unavailable"}
point = symbol_info.point
order_type = mt5.ORDER_TYPE_BUY if action == "BUY" else mt5.ORDER_TYPE_SELL
price = mt5.symbol_info_tick(symbol).ask if action == "BUY" else mt5.symbol_info_tick(symbol).bid
sl = price - (sl_points * point) if action == "BUY" else price + (sl_points * point)
tp = price + (tp_points * point) if action == "BUY" else price - (tp_points * point)
request = {
"action": mt5.TRADE_ACTION_DEAL,
"symbol": symbol,
"volume": volume,
"type": order_type,
"price": price,
"sl": sl,
"tp": tp,
"deviation": 10,
"magic": 234001,
"comment": "Python Quant Daemon",
"type_time": mt5.ORDER_TIME_GTC,
"type_filling": mt5.ORDER_FILLING_IOC,
}
result = mt5.order_send(request)
if result.retcode != mt5.TRADE_RETCODE_DONE:
logging.error(f"Order failed: {result.retcode} - {result.comment}")
return {"success": False, "retcode": result.retcode, "comment": result.comment}
return {"success": True, "ticket": result.order, "price": result.price}