MT5 + Python architecture
Why this lesson
Section titled “Why this lesson”You have validated a strategy on net costs. To run it, Python has to reach a broker — and at retail CFD brokers there is no REST order API the way there is for US equities (the industry contrast is real). Your two realistic paths are the native MetaTrader5 package and an EA bridge. They are not interchangeable: one is Windows-bound and in-process, the other is platform-agnostic and file/socket-based, and the choice quietly decides your VPS, your latency budget, and how you debug at 3am. This lesson makes you fluent in both and gets working code onto a demo terminal.
Segment: 20:21–25:55 — When NOT to use DWX Connectwatch full video
The explainer
Section titled “The explainer”Two architectures, one decision. Both approaches end with Python deciding and MetaTrader executing. They differ in how the two processes talk.
Path A — the native MetaTrader5 package. You pip install MetaTrader5, and your Python process makes in-process calls to a running MT5 terminal on the same machine through local inter-process communication (IPC), not a network API. mt5.initialize() attaches to the terminal; copy_rates_range and copy_ticks_range pull history into pandas; order_send places and closes orders; positions_get and orders_get read live state (official API reference). The walkthrough above demonstrates the whole surface against an IC Markets demo. The catch is stated plainly in the package docs: it is Windows-only and needs the terminal alive next to it. Linux and macOS have only workarounds — Wine, or the community mt5linux RPC shim — neither of which you want under real money. So the native path dictates a Windows VPS. That is the whole reason the architecture question is not academic.
Path B — the EA bridge. Here an Expert Advisor runs inside the terminal and exchanges messages with your Python “brain” — historically over ZeroMQ sockets, now more often over files. DWX Connect is the reference implementation: one client codebase covering both MT4 and MT5, with reference clients in Python, Java, and C#, handling every order type, modification, closing by ticket/symbol/magic, and market-data subscription. The team that built it explains why they abandoned their own ZeroMQ series in 2021: subscribing to many symbols made it too CPU-hungry, and average users could not debug socket connectivity. File-based IPC replaced it with a default ~25ms poll interval — and they are refreshingly explicit that if your strategy is genuinely latency-sensitive, you should not use any MetaTrader bridge; you should use their separate FIX API. The older ZeroMQ videos (still instructive as architecture history) show the pattern in the raw, including the classic gotcha that stops are specified in points, not pips.
The fork, decided: the native package is simpler, in-process, and Windows-bound — best when your system is one Python process on a Windows VPS beside its terminal. The EA bridge is platform-agnostic and lets your brain run anywhere (including Linux) while the EA does the broker-facing work — best when you want language or OS freedom, or you already run MT4. Neither is “faster” in a way that matters for intraday-to-swing systems; both are the wrong tool for true low-latency trading.
Why VPS choice follows from this. The tuning folklore you will read — “trade context busy” error 146, pinning terminals to CPU cores, “buy fewer, faster cores” — is MetaTrader 4 lore: MT4 is a 32-bit single-threaded app with one terminal-wide trade context. The presenter’s own closing caveat (near 31:30) is the load-bearing sentence: MT5 is multi-threaded and resolves most of those issues. So on the native MT5 path you inherit far less of that pain — but you still inherit Windows. Size the VPS for reliability and a low, stable latency to the broker’s server, not for core count.
The honest posture the rest of Level 3 builds on: the demo code you are about to run is the easy 20%. It has no reconnection, no state check on restart, no idempotency. Lessons 3.2 and 3.3 exist because that missing 80% is what actually kills bot accounts.
Run this against a demo MT5 terminal that is open and logged in. It pulls 1000 bars and the current tick, then places and cancels a far-away pending order so nothing can fill.
import MetaTrader5 as mt5import pandas as pd
# 1. Attach to the already-running, logged-in DEMO terminal.if not mt5.initialize(): raise SystemExit(f"initialize() failed: {mt5.last_error()}")
symbol = "EURUSD"mt5.symbol_select(symbol, True)
# 2. Pull the last 1000 M15 bars into a DataFrame.rates = mt5.copy_rates_from_pos(symbol, mt5.TIMEFRAME_M15, 0, 1000)bars = pd.DataFrame(rates)bars["time"] = pd.to_datetime(bars["time"], unit="s")print(bars.tail(3)[["time", "open", "high", "low", "close"]])
# 3. Read the current tick (live bid/ask).tick = mt5.symbol_info_tick(symbol)print(f"bid={tick.bid} ask={tick.ask} spread={round((tick.ask - tick.bid) / mt5.symbol_info(symbol).point)} points")
# 4. Place a BUY LIMIT far below market so it will NOT fill, then cancel it.price = round(tick.bid - 0.0200, mt5.symbol_info(symbol).digits) # 200 pips underrequest = { "action": mt5.TRADE_ACTION_PENDING, "symbol": symbol, "volume": 0.01, "type": mt5.ORDER_TYPE_BUY_LIMIT, "price": price, "magic": 424242, # our client tag — remember this for 3.2 "comment": "course-3.1-demo", "type_time": mt5.ORDER_TIME_GTC, "type_filling": mt5.ORDER_FILLING_RETURN,}sent = mt5.order_send(request)print("placed:", sent.retcode, "ticket:", sent.order)
# 5. Cancel it by ticket.cancel = mt5.order_send({"action": mt5.TRADE_ACTION_REMOVE, "order": sent.order})print("cancelled:", cancel.retcode)
mt5.shutdown()Verify in the terminal’s Trade tab that the pending order appeared and vanished. Note the magic number — that tag is how, in Lesson 3.2, you will tell your orders apart from everything else on the account.
Terms introduced
Section titled “Terms introduced”Check yourself
Why is the native MetaTrader5 Python package effectively Windows-only in production?
Darwinex replaced its ZeroMQ Python-to-MetaTrader bridge with the file-based DWX Connect in 2021 mainly because ZeroMQ was…
The single-terminal 'trade context busy' problem and the single-thread core limits discussed for VPS tuning are…
When is a MetaTrader bridge (native package OR EA bridge) the wrong tool, per the people who build them?
You can move on when you can… stand up the MetaTrader5 package against a demo terminal, pull bars and a tick into pandas, place and cancel a pending order by ticket, and argue the native-package-vs-EA-bridge fork — including why the native path forces a Windows VPS and when neither belongs anywhere near your strategy.
Go deeper
Section titled “Go deeper”- Official MetaTrader5 Python package docs — the canonical API reference; bookmark
order_send,positions_get, andcopy_rates_range. - DWX Connect on GitHub — reference EA-bridge clients in Python, Java, and C# for MT4 and MT5.
mt5linuxRPC shim — the community Linux workaround, useful to understand why it is a workaround and not a solution.- MT4 VPS latency tuning talk — watch the closing caveat that MT5 resolves most of it; it reframes everything before it.