Make the bot connect to MetaTrader5 on Linux without manual setup or launching extra programs. - Add mt5linux rpyc bridge: MT5 terminal + Windows Python run under Wine, Linux client talks to it over a socket - scripts/mt5_bridge.sh: robust, idempotent launcher (up/down/status/restart/ login-gui/install-service) with .env loading, port health-checks and a systemd --user unit for auto-start on login - src/mt5_connector.py: auto-detect bridge backend (lazy, non-blocking import); auto-start the bridge via mt5_bridge.sh when the port is down so the bot self-connects; attach-mode initialize() first, then explicit login - Use configured SYMBOL instead of hardcoded XAUUSD in connector + news_agent (XM names spot gold 'GOLD') - scripts/test_mt5_bridge.py: connectivity smoke test - docs/MT5-ARCH-LINUX-SETUP.md: full setup, root-cause notes, troubleshooting Verified live: account 345454551 @ XMGlobal-MT5 10, balance read, GOLD M15 data + ticks streaming, trade_allowed=True.
5.6 KiB
MT5 on Arch Linux (Wine + mt5linux bridge)
The MetaTrader5 Python package is Windows-only. On Arch Linux we run the MT5
terminal under Wine plus a Windows Python that exposes the MT5 API over
an rpyc socket (mt5linux). The Linux-side bot connects to that socket.
Linux Python (bot) --rpyc--> Wine Python (mt5linux server) --> MT5 terminal --> broker
mt5linux client MetaTrader5 pkg terminal64.exe
One-time setup (already done on this machine)
- Wine:
wine-11.10 (Staging)✅ - Headless display:
Xvfb(pkgxorg-server-xvfb) ✅ - MT5 terminal installed in Wine:
~/.wine/drive_c/Program Files/MetaTrader 5/terminal64.exe✅ - Windows Python 3.9 in Wine:
~/.wine/drive_c/users/$USER/AppData/Local/Programs/Python/Python39/python.exe✅ - Wine Python packages:
MetaTrader5,mt5linux,rpyc✅ - Linux Python packages:
mt5linux,rpyc✅
To reproduce the Wine Python install:
curl -sL -o /tmp/py39.exe https://www.python.org/ftp/python/3.9.13/python-3.9.13-amd64.exe
DISPLAY=:1 WINEDEBUG=-all wine /tmp/py39.exe /quiet InstallAllUsers=0 PrependPath=1 Include_pip=1
WINPY="$HOME/.wine/drive_c/users/$USER/AppData/Local/Programs/Python/Python39/python.exe"
wine "$WINPY" -m pip install MetaTrader5 mt5linux
Configuration (.env)
MT5_LOGIN=...
MT5_PASSWORD=...
MT5_SERVER=... # exact broker server name (see terminal)
MT5_BRIDGE_HOST=127.0.0.1
MT5_BRIDGE_PORT=18812
MT5_WIN_PATH=C:\Program Files\MetaTrader 5\terminal64.exe
Run (robust, one command)
# Bring the whole bridge up (idempotent): Xvfb + rpyc server + verified login.
# The terminal is auto-launched headless and logged in from .env credentials.
scripts/mt5_bridge.sh up
# Other commands
scripts/mt5_bridge.sh status # components + live login + trade_allowed
scripts/mt5_bridge.sh restart
scripts/mt5_bridge.sh down
up is safe to re-run: it only starts what is missing and health-checks the
rpyc port (no blind sleeps). Credentials and port are read from .env
(MT5_LOGIN/PASSWORD/SERVER, MT5_BRIDGE_PORT, MT5_WIN_PATH).
Auto-start on login (systemd --user)
scripts/mt5_bridge.sh install-service
systemctl --user enable --now mt5-bridge.service
journalctl --user -u mt5-bridge -f # logs
After this the bridge comes up automatically; you never repeat the manual steps. Then just run the bot:
python main_live.py
First-time only
The account must be logged into the terminal once so the profile knows it.
Normally up does this automatically via explicit login. If you ever get
LOGIN_FAIL (-6), do a one-time GUI login:
scripts/mt5_bridge.sh login-gui # File -> Login to Trade Account
The bot (src/mt5_connector.py) auto-detects the bridge: if the native
MetaTrader5 import fails but mt5linux is present, it connects lazily to
MT5_BRIDGE_HOST:MT5_BRIDGE_PORT on the first connect() call, trying
initialize() attach-mode first then explicit login.
Zero-step auto-connect
You do not need to start anything by hand. When the bot calls connect()
and the bridge port is closed, it auto-runs scripts/mt5_bridge.sh up
(Xvfb + rpyc server + login) and waits for it to become ready. So on Linux:
python main_live.py # bridge is started automatically if needed
Disable autostart (e.g. when using the systemd service) with:
export MT5_BRIDGE_AUTOSTART=0
Broker symbol note
XM Global names spot gold GOLD (not XAUUSD). .env sets SYMBOL=GOLD.
The connector pre-selects whatever SYMBOL is configured.
Root cause of the -6 Authorization failed we hit
Per the official mt5linux docs, the intended flow is:
(1) open MT5 and log in via the GUI → (2) start the server → (3) call
initialize() with no credentials to attach to the running terminal.
Our first attempt launched the terminal with /portable and passed
login/password/server to initialize(). A fresh portable profile has no
saved account, so the broker rejected the fresh login attempt with
(-6, 'Authorization failed'). Confirmed: no accounts.dat/servers.dat
account was present in the Wine prefix.
Fixes applied:
- launcher no longer uses
/portable(uses the persistent profile) - added
scripts/mt5_bridge.sh login_guifor the one-time GUI login - the connector + test now try
initialize()attach-mode first
So the credentials were almost certainly fine — the terminal simply had never logged into the account. Do the one-time
login_guistep, then the bridge attaches cleanly.
QA status (verified)
- rpyc server starts and listens on
127.0.0.1:18812✅ - Linux client connects through to the broker ✅
mt5.initialize(...)reaches the broker server ✅src/mt5_connector.pyimports without blocking; backend detected asbridge✅
NOTE: With the supplied XM credentials the broker returned
(-6, 'Authorization failed'). The transport works end-to-end — this is a credential/server-name issue, not an infrastructure problem. Confirm in the MT5 terminal:
- exact server name (XM has several, e.g.
XMGlobal-MT5,XMGlobal-MT5 2…10)- login number and password (investor vs master password)
- account is active and AlgoTrading is enabled
Troubleshooting
Authorization failed (-6)→ wrong server name / login / password, or expired account. Log into the terminal GUI once to confirm the exact server.- Client
result expired/ timeout → the Wine MT5 terminal hung; runscripts/mt5_bridge.sh restart. - Port already in use → another server instance is running;
mt5_bridge.sh stop.