How I Run a 13-Pair Forex Bot From a Mac (It's on a Windows VPS)
MetaTrader 5 doesn't run on macOS. Not natively, not well through Wine, and not at all if you need reliable order execution. I develop on a Mac and my bot needs to run 24/5. The solution is boring but reliable: code locally, deploy to a Windows VPS.
Here's the full setup and every problem I hit getting it working.
The architecture
Local (MacBook): VS Code + Claude Code for writing MQL5 code. I can compile locally using Wine + MetaTrader 5, which works fine for syntax checking. I wrote a whole post about getting that working.
Remote (ForexVPS.net): Windows Server 2022 running MetaTrader 5, connected to Fusion Markets. The VPS is in New York, close to major liquidity providers. Costs $30/month for a basic plan with 2GB RAM, which is enough for one MT5 instance.
Deployment: Push to GitHub, SSH into VPS, pull and copy files to the MT5 data directory. No fancy CI/CD — the deployment surface is small enough that a manual process with a pre-push checklist is safer.
The bot
13 currency pairs, all running the same strategy: EMA(5) crossover with dual RSI(21/14) confirmation on 1-hour bars. The strategy backtested to zero losing years across 24 years of data. Running live on a A$5,000 account at Fusion Markets.
The pairs: EURUSD, GBPUSD, USDJPY, AUDUSD, NZDUSD, USDCAD, USDCHF, EURGBP, EURJPY, GBPJPY, AUDNZD, EURAUD, GBPAUD.
Each pair runs as a separate chart window in MT5 with its own instance of the EA (Expert Advisor). Magic numbers differentiate the trades.
The gotchas
This is the section I wish existed when I was setting this up.
1. AutoTrading is a GUI toggle (Error 10027)
You cannot enable AutoTrading via script, command line, or MQL5 code. It's a button in the MT5 toolbar. If the VPS reboots and MT5 starts automatically, AutoTrading will be OFF by default.
If you try to place a trade with AutoTrading disabled, you get error 10027 (TRADE_RETCODE_CLIENT_DISABLES_AT). There's no programmatic workaround. You have to RDP into the VPS and click the button.
My fix: I have a startup script that opens MT5, but I still need to manually verify AutoTrading is on after any reboot. I check this every Monday morning before the Sydney open.
2. Task Scheduler needs the /IT flag
Windows Task Scheduler can start MT5 automatically on boot. But if you create the task via SSH (which I do for automation), you need the /IT flag to allow it to interact with the desktop:
schtasks /create /tn "StartMT5" /tr "C:\Program Files\MetaTrader 5\terminal64.exe" /sc onstart /ru SYSTEM /ITWithout /IT, MT5 starts as a background process with no GUI. No GUI means no charts, no EAs running, and no AutoTrading toggle. The bot appears to be running but does nothing.
3. Filling mode varies by pair
Different brokers and pairs use different order filling modes. Fusion Markets uses ORDER_FILLING_FOK (fill or kill) for most pairs, but some like AUDNZD require it explicitly. If you send an order with the wrong filling mode, it silently fails.
My EA auto-detects the filling mode:
long filling = SymbolInfoInteger(_Symbol, SYMBOL_FILLING_MODE);
if((filling & SYMBOL_FILLING_FOK) != 0)
request.type_filling = ORDER_FILLING_FOK;
else if((filling & SYMBOL_FILLING_IOC) != 0)
request.type_filling = ORDER_FILLING_IOC;
else
request.type_filling = ORDER_FILLING_RETURN;Without this, AUDNZD orders would fail while EURUSD worked fine. Took me two days to figure out why one pair wasn't trading.
4. VPS timezone confusion
My VPS clock is UTC. I'm in AEST (UTC+10). When I SSH in and see "March 10 16:00," I used to panic thinking the bot was a day behind. It wasn't — I was just 10 hours ahead.
This sounds trivial but it caused real confusion when checking logs. "Why hasn't the bot traded today?" Because "today" in AEST started 10 hours ago but on the VPS it's still yesterday afternoon.
I now keep a sticky note: VPS = UTC. You = UTC+10. Relax.
5. RDP disconnects kill chart layouts
If your Remote Desktop session disconnects uncleanly (network drop, laptop sleep), MT5 sometimes loses its chart layout. All 13 charts close. The EAs stop running. MT5 is open but nothing is loaded.
Fix: Save a default profile in MT5 (File > Profiles > Save As). If charts disappear, load the profile. I also have a Windows batch script that kills and restarts MT5 with the correct profile:
taskkill /IM terminal64.exe /F
timeout /t 5
start "" "C:\Program Files\MetaTrader 5\terminal64.exe" /portable /profile:ForexBotThe deployment workflow
- Write/edit MQL5 code locally in Claude Code
- Compile locally to check syntax (Wine + MT5)
- Push to GitHub (pre-push hook shows checklist)
- SSH into VPS:
ssh forex-vps - Pull changes:
cd C:\repos\forex-ai && git pull - Copy EA to MT5 data folder:
copy /Y *.mq5 "%APPDATA%\MetaTrader 5\MQL5\Experts\" - In MT5: Compile (F7), verify no errors, restart EA on each chart
Steps 4-7 take about 3 minutes. I could automate more of it, but for live trading, I prefer the manual verification at each step.
Is it worth it?
The VPS costs $30/month. The bot has been profitable (small but consistent) since going live. The setup took about a week to get right, mostly because of the gotchas above.
If you're developing MQL5 on a Mac, the hardest part isn't the code — it's the deployment environment. MetaTrader 5 was built for Windows traders sitting at a desktop, not developers deploying from a terminal. Every piece of friction in this post comes from that mismatch.
I sometimes think about rewriting the whole thing in Python with a different broker API. Then I look at the 24-year backtest and the live equity curve and decide that fighting MT5's quirks is cheaper than rebuilding a proven strategy from scratch. Sometimes the right tool is the annoying one.