TICKERALL!
← All posts
August 25, 20263 min read

Streaming Live MT5 Tick Data over WebSocket in Python

Polling for MetaTrader 5 prices in a loop is the classic beginner mistake. Here's how to stream live MT5 ticks over a WebSocket in Python — the right way to feed a trading bot real-time data.

MetaTrader 5WebSocketPythonMarket Data

If your MetaTrader 5 bot needs live prices, there are two ways to get them — and one of them is a mistake almost everyone makes first: calling a GET /price endpoint in a tight loop. It's slow, it's wasteful, you're always a beat behind the market, and you'll hammer any API into rate-limiting you.

Prices are a firehose. The right tool for a firehose is a WebSocket — you open one connection, subscribe to the symbols you care about, and the server pushes each tick to you the instant it happens.

Broker feed prices move Hosted terminal subscribed to symbols WSS push Your code on_tick(...)
You subscribe once; every tick is pushed to your handler as prices move. No loop, no polling, no lag.

The whole thing in a few lines

Because there's no native MT5 HTTP interface (MT5 speaks a binary desktop protocol — see what a MetaTrader 5 REST API actually looks like), this uses a hosted API that exposes an MT5 WebSocket. Connect, register a handler, subscribe:

from tickerall import Tickerall

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

# Warm the broker session once (same login you'd use in MetaTrader).
session = client.sessions.start(
    broker="mt5", server="Your-Broker-Server", account=12345678, password="...",
)

stream = client.stream.connect()

@stream.on("tick")
def on_tick(t):
    print(t.symbol, t.bid, t.ask, t.time)

stream.subscribe_ticks(session.account_id, ["EURUSD", "GBPUSD", "XAUUSD"])
stream.run_forever()

One connection carries every symbol you subscribe to. Add or drop symbols at runtime with more subscribe_ticks / unsubscribe_ticks calls — you don't open a socket per symbol.

One socket, more than just ticks

The same WebSocket streams the other things that change on their own, so your bot can react instead of re-fetching:

Subscribe to You get pushed Use it for
ticks Every bid/ask update Signals, live pricing, execution timing
positions Open/modify/close + moving P/L Trailing stops, risk, dashboards
account Balance / equity / margin changes Drawdown guards, exposure limits
stream.on("position", lambda p: print("position", p.ticket, "P/L", p.profit))
stream.subscribe_positions(session.account_id)

Two things that will bite you if you skip them

1. Ticks are irregular — don't assume a fixed cadence. Real markets deliver ticks in bursts: a flurry during a news spike, then seconds of silence when it's quiet. A dry second means nothing happened, not that the feed broke. Never build logic that expects "a tick every N milliseconds," and never treat a quiet window as a failure.

If you need evenly-spaced data (say, a value every second), don't infer it from tick timing — resample: keep the last tick you saw and read it on your own timer. Let ticks update state; let your clock drive cadence.

2. Connections drop — plan for reconnects. Any long-lived socket will eventually be cut (network blips, deploys, idle timeouts). A good client reconnects and re-subscribes automatically so your streams resume; make sure yours does, and treat a reconnect as normal, not exceptional. If you're building the socket yourself, back off and retry — don't hot-loop on failure.

A tiny worked example: a live price alert

Ticks update state; your own logic decides what matters. Here's a complete price-crossing alert in a handful of lines:

LEVEL = 1.1000
armed = True

@stream.on("tick")
def watch(t):
    global armed
    if t.symbol != "EURUSD":
        return
    if armed and t.bid >= LEVEL:
        print(f"EURUSD crossed {LEVEL} — bid {t.bid}")
        armed = False   # fire once; re-arm on your own terms

stream.subscribe_ticks(session.account_id, ["EURUSD"])
stream.run_forever()

Swap the print for a Telegram message, an order, or a database write and you have the skeleton of a real bot — all driven by pushed ticks, no polling loop in sight.

Wrapping up

Live MetaTrader 5 data is a push problem, so use a push tool: one WebSocket, a handler, and a subscribe call. Let ticks update state, let your own clock drive timing, and handle reconnects as routine. That's the whole pattern — and because the terminal runs on the API's side, it works the same on a laptop, a Linux server, or in the cloud (more on that in Running MetaTrader 5 from Python on Linux).

The full WebSocket reference and SDKs are in the TickerAll docs.

Streaming Live MT5 Tick Data over WebSocket in Python · Ticker All!