TICKERALL!
← All posts
August 24, 20263 min read

What a MetaTrader 5 REST API Actually Looks Like

There's no native MetaTrader 5 REST API — MT5 speaks a binary desktop protocol. Here's the mental model for the hosted kind, one worked example end to end, and the three things that trip developers up.

MetaTrader 5REST APIWebSocketTrading

You searched for a MetaTrader 5 REST API, and somewhere around the third result you learned the awkward truth: there isn't one. MT5 talks to its broker over a binary protocol between the desktop terminal and the server — there's no HTTP endpoint to call, and the official MetaTrader5 Python package just drives a local terminal over IPC.

So when people say "MT5 REST API," they mean a hosted service that runs the MT5 side and re-exposes it as REST + WebSocket. This post isn't the endpoint reference (that's what the docs are for) — it's the mental model, one example end to end, and the handful of things that actually trip developers up.

The one idea that makes it click

Almost every mistake I see comes from missing a single distinction: REST is how you drive the account; the WebSocket is how you watch it.

REST drive it — you ask, it answers Read account state, symbols, candles Place, modify, close a trade One request → one result WebSocket watch it — it tells you Live ticks as prices move Positions open, change, close Balance / equity updates
If you're asking a question, it's REST. If you want to be told when something happens, it's the WebSocket.

Get this split right and the rest of the API almost designs itself. Get it wrong and you end up polling GET /prices in a loop, hammering the API for data the WebSocket would have pushed you for free.

One example, start to finish

Forget the endpoint catalog. Here's a complete, realistic slice: connect, check you can afford the trade, place it with a stop and target, then watch the position live. That's REST, REST, REST, then WebSocket — the whole model in one screen.

from tickerall import Tickerall

client = Tickerall(api_key="cf_...")

# 1. Connect once. Every later call rides this session — you never resend the password.
session = client.sessions.start(
    broker="mt5", server="Your-Broker-Server", account=12345678, password="...",
)
acc = session.account_id

# 2. Drive: read state before you act.
info = client.accounts.get(acc)
if info.free_margin < 200:
    raise SystemExit("not enough free margin")

# 3. Drive: place a guarded entry. The result comes straight back — no polling.
order = client.orders.place(acc, symbol="EURUSD", side="buy",
                            volume=0.10, sl=1.0850, tp=1.0950)
print("filled", order.ticket, "at", order.price)

# 4. Watch: react to the position over the stream instead of re-fetching it.
stream = client.stream.connect()
stream.on("position", lambda p: print(p.ticket, "P/L", p.profit))
stream.subscribe_positions(acc)

Every line maps to the model: steps 1–3 drive the account (each a single request that returns a result), and step 4 watches it (the server pushes updates as the market moves). No terminal, no polling loop, no binary protocol — just an HTTP client and a socket.

Three things that trip people up

1. Connect once, then reuse. The sessions.start call is the only place a password appears. After that, the account is warm and every request and the stream ride that session. If you find yourself re-authenticating per call, you've misunderstood the lifecycle — and you're paying a connection cost on every trade.

2. Don't poll what you can stream. The single most common performance mistake is calling GET on prices or positions in a tight loop. Prices are a firehose; that's what the WebSocket is for. Poll on-demand facts (candles, account snapshot); subscribe to anything that changes on its own.

A good rule: if you'd refresh it by hitting F5, it's REST. If you'd sit and watch it, it's the WebSocket.

3. A trade result is synchronous. orders.place returns the fill — ticket, price, status — in the response. You don't submit an order and then poll to find out what happened. The hosted terminal does the round-trip to your broker over MT5's native protocol and hands you the clean result. (The position's later life — its moving P/L, its close — is the streaming part.)

Why it's shaped this way

A native app has to speak MT5's wire protocol, manage a stateful socket, and run a terminal. Collapsing all of that into "one bearer token, REST to drive, WebSocket to watch" is the entire value of a hosted API — and it's why the same integration runs unchanged on Linux, in a container, or in CI. (For the why behind skipping a local terminal, see Running MetaTrader 5 from Python on Linux.)

Wrapping up

There's no MetaTrader 5 REST API in the box because MT5 isn't an HTTP service. But the hosted shape is small and predictable: authenticate with a key, connect a session once, drive the account over REST, and watch it over a WebSocket. Hold that model in your head and the full reference reads like a formality.

What a MetaTrader 5 REST API Actually Looks Like · Ticker All!