Official Python client for the TickerAll REST + WebSocket API — place trades, stream live market data, and manage broker sessions without an MT4/MT5 terminal in the path.
Project description
tickerall
Official Python client for the TickerAll REST + WebSocket API.
Place trades, stream live market data, and manage broker sessions programmatically — without an MT4/MT5 terminal in the path. No Windows VM, no Wine, no MetaTrader5 terminal to babysit, no thread-safety workarounds.
pip install tickerall
Requires Python 3.9+. Depends only on httpx and websocket-client.
Why
The official MetaTrader5 Python package only runs on Windows, drives a local terminal over a single-threaded IPC channel, and falls over under concurrency. TickerAll hosts the broker connection for you and exposes it as a clean HTTP + WebSocket API, so your bot can run anywhere — Linux, macOS, a container, a Raspberry Pi — and stream ticks instead of polling.
MetaTrader5 (local terminal) |
tickerall |
|
|---|---|---|
| OS | Windows only | anywhere Python runs |
| Live ticks | poll symbol_info_tick() per symbol |
push over WebSocket |
| Concurrency | single-threaded IPC, not thread-safe | stateless HTTP, thread-safe |
| Deploy | a terminal per account to babysit | pip install |
Quickstart
from tickerall import Tickerall
client = Tickerall(api_key="cf_live_...")
# Connect a broker account → get a TickerAll account_id
session = client.sessions.start(
broker="mt5",
server="Exness-MT5Trial7",
account=12345678,
password="...",
)
# Place a market order
order = client.orders.place(
session.account_id,
type="market",
symbol="BTCUSDm",
side="BUY",
volume=0.10,
stop_loss=58000.0,
take_profit=72000.0,
)
print(order.ticket, order.status)
client.sessions.end(session.account_id)
The client is a context manager too:
with Tickerall(api_key="cf_live_...") as client:
...
Streaming — push, not poll
The stream runs on its own background thread. Register callbacks and go; it heartbeats, reconnects with backoff, and re-subscribes automatically.
client = Tickerall(api_key="cf_live_...")
session = client.sessions.start(broker="mt5", server="Exness-MT5Trial7",
account=12345678, password="...")
stream = client.stream.connect()
stream.on("tick", lambda e: print(e.symbol, e.bid, e.ask, e.timestamp))
stream.on("position", lambda e: print(e.event, e.position.ticket, e.position.profit))
stream.subscribe_ticks(session.account_id, ["BTCUSDm", "ETHUSDm"])
stream.subscribe_positions(session.account_id)
# ... your app runs ...
stream.close()
Keep an in-memory tick cache fresh (zero polling)
A common pattern: let the WebSocket fill a dict so price reads are O(1) with no network call — strictly better than polling a terminal per symbol.
latest: dict[str, "TickEvent"] = {}
stream = client.stream.connect()
stream.on("tick", lambda e: latest.__setitem__(e.symbol, e))
stream.subscribe_ticks(session.account_id, ["BTCUSDm", "ETHUSDm", "XAUUSDm"])
# Anywhere in your app — instant, no IPC, no thread-safety dance:
tick = latest.get("BTCUSDm")
Market data & history
# Historical OHLC candles (coarser timeframes reach further back)
bars = client.candles.get(session.account_id, symbol="BTCUSDm", hours=24, timeframe="M5")
for c in bars:
print(c.timestamp, c.open, c.high, c.low, c.close)
# Closed-trade history (recent broker window)
trades = client.history.get(session.account_id, symbol="BTCUSDm", limit=100)
# Tradeable symbols and their volume specs
symbols = client.accounts.symbols(session.account_id)
specs = client.accounts.symbol_specs(session.account_id) # min / max / step per symbol
Positions
detail = client.accounts.get(session.account_id)
for p in detail.positions:
print(p.ticket, p.symbol, p.side, p.volume, p.profit)
client.positions.modify(session.account_id, ticket=p.ticket, stop_loss=60000.0)
client.positions.close(session.account_id, ticket=p.ticket) # full close
client.positions.close(session.account_id, ticket=p.ticket, volume=0.05) # partial
Always-hot sessions & transparent re-arm
For connections that must stay up across restarts, use keep_alive. The
credentials live in this process's memory only (never persisted); if the
account goes cold (e.g. TickerAll restarted), the next call transparently
re-supplies them and retries once.
session = client.sessions.keep_alive(broker="mt5", server="Exness-MT5Trial7",
account=12345678, password="...")
# ... later, after an outage, this just works — the client re-arms under the hood:
client.accounts.get(session.account_id)
# Stop keeping it alive (drops the cached credentials):
client.sessions.stop_keep_alive(session.account_id)
Reliability — idempotency & queue-and-replay
State-changing calls (sessions.start, orders.place, positions.close,
positions.modify) carry a stable Idempotency-Key, so a retried call can't
double-execute. By default a transient connectivity failure
(TickerallServiceUnavailableError, .transient == True) fails fast so you
can re-decide with fresh prices:
from tickerall import TickerallServiceUnavailableError
try:
client.orders.place(account_id, type="market", symbol="BTCUSDm", side="BUY", volume=0.1)
except TickerallServiceUnavailableError:
... # momentary blip — safe to retry
For price-insensitive orders (pending orders, SL/TP edits) you can instead queue-and-replay until connectivity returns:
client.orders.place(
account_id, type="limit", symbol="BTCUSDm", side="BUY", volume=0.1, price=60000.0,
queue_if_reconnecting=True, queue_max_s=60.0,
)
Errors
All errors derive from TickerallApiError and carry .status, .code,
.request_id, .details, and .transient:
| Class | When |
|---|---|
TickerallAuthError |
401 — bad/missing API key |
TickerallForbiddenError |
403 — plan limit / reserved resource |
TickerallValidationError |
400 / 422 — malformed request |
TickerallNotFoundError |
404 — account / position not found |
TickerallBrokerError |
broker rejected or could not satisfy the request |
TickerallServiceUnavailableError |
transient — TickerAll momentarily unreachable (safe to retry) |
Using it from an async app
REST methods are synchronous and thread-safe, so call them from an event loop
via asyncio.to_thread:
detail = await asyncio.to_thread(client.accounts.get, account_id)
The stream is already non-blocking (its own thread) — callbacks fire as events arrive.
License
MIT © Miguel Santos
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file tickerall-0.1.4.tar.gz.
File metadata
- Download URL: tickerall-0.1.4.tar.gz
- Upload date:
- Size: 19.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7f61e551f5486761c0377c31a68942bd05216d1b98fee3e3365dd8ae2ae82e75
|
|
| MD5 |
afcc74e00ad269297f03d1e58bcfd76d
|
|
| BLAKE2b-256 |
567b08c2c2a626a8ec029e0c7ab3a5c05f7ce5afefb78003279b0b710bbd6ab7
|
File details
Details for the file tickerall-0.1.4-py3-none-any.whl.
File metadata
- Download URL: tickerall-0.1.4-py3-none-any.whl
- Upload date:
- Size: 26.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6d27400213813078d211e7adeeebdebf29b6dcef3c52f11e41db57f5df0e0c4f
|
|
| MD5 |
a5065d3011ed17165f5977e0a7d3c19a
|
|
| BLAKE2b-256 |
d3960ba7bf4fe9bc40185208e115dd6ac18eafc9d4141d520268d53ae857dfd6
|