View as Markdown

Python SDK

The tickwire Python package. Typed sync and async clients for MT4 and MT5 accounts, with idempotent trading, safe retries, resumable streams and webhook verification.

tickwire is our Python package for the Tickwire API. It has typed clients, sync and async, and works the same for MT4 and MT5 accounts. It needs Python 3.11 or later.

It isn’t on PyPI yet. We’re publishing the package as tickwire; until it’s there, pip install tickwire won’t find it. If you want to use the SDK before then, contact us. Everything it does is a plain HTTP call, so you can also use the REST API directly with any HTTP client.

Your first calls in the sandbox

from tickwire import Tickwire, trade_succeeded

# TICKWIRE_SANDBOX_URL and TICKWIRE_API_KEY (your sandbox key) from the environment.
with Tickwire(sandbox=True, actor="quickstart") as tw:
    acc = tw.account(tw.list_accounts()[0]["id"])      # MT4 and MT5 look the same
    print(acc.health()["status"])                      # healthy | stale | disconnected | down
    print(acc.price("EURUSD"))
    r = acc.market_order("EURUSD", 0.01, reason="quickstart")   # Idempotency-Key generated for you
    print(trade_succeeded(r), r["numericCode"])
    print(acc.audit(limit=5))                          # who did what, when, why

sandbox=True never guesses a host. It reads sandbox_url= or TICKWIRE_SANDBOX_URL, and raises ConfigError if neither is set. For a live account, pass the URL or set TICKWIRE_API_URL. See Sandbox for how to get a sandbox key.

Async and streaming

AsyncTickwire has the same methods (async with …, await …), plus streams that resume after a reconnect:

from tickwire import AsyncTickwire

async with AsyncTickwire(sandbox=True) as tw:
    async with tw.account(account_id).stream() as s:
        state = await s.wait_synchronized()
        s.on("positionUpdated", lambda frame, st: print(frame["position"]))

The stream re-subscribes from the last sequence number it saw. If it detects a gap, it does a full resync, so your copy of the account is never silently wrong. See Streaming.

What it covers

  • Accounts: health, account information, positions, orders, deals and history, symbols, prices, server time, one-call snapshots, the audit log, and trading.
  • Accounts and webhooks: accounts and webhooks, including deliveries, resends and secret rotation.
  • Sandbox: sign-up and sandbox keys.
  • Agent keys, kill switches and the pre-trade decision hook: the SDK has clients for them (AgentClient and the owner’s admin methods), but the agent API isn’t available yet.

Native /v1 lists are cursor-paginated. tw.pages(...) follows the cursor for you.

Safety defaults

  • Idempotency. Every mutation sends an Idempotency-Key (yours, or a generated one), X-Actor and X-Reason. Pass idempotency_key= so that repeating the same decision is safe across restarts. See Idempotency.
  • Retries only when safe. Reads retry on transport errors and 408, 429, 502, 503 and 504, with backoff and a per-client retry budget. A mutation retries only when the server confirms it didn’t run it, and always with the same key.
  • unknown is never retried. If the reply to a mutation is lost, the SDK raises OutcomeUnknown with the idempotency key, so you can check what happened instead of sending the order twice.
  • Typed errors. NotFound, Conflict, NotSupportedOnMt4, RateLimited, ConfigError and others keep the server’s error envelope in .body. health() returns the body of a 503, because “down” is an answer, not an exception.
  • Webhooks. verify_webhook(secret, headers, body) checks the HMAC-SHA256 signature and rejects replays outside a 5-minute window. See Webhooks.
  • No secrets in logs. Keys never appear in repr().

The CLI

The tickwire command is built on this SDK.