tickstreamdocs

DOCS

Account & Execution API

Query your account positions and place futures orders over a simple API on your own Rithmic broker account.

Overview

The Account & Execution API lets you query your account state and place and manage futures orders over a dead-simple HTTP API, routed to your own Rithmic broker account (prop firms and retail alike). You bring your Rithmic credentials; tickstream is the thin, fast account & execution layer on top.

  • Query every position on your linked accounts — quantity, average open price, open/closed PnL, balances.
  • Pull your trade history — every fill, as data, ready for your own analysis. Works for any linked account, independent of the algos.
  • Order placement — market entry with a stop and target that rest at the broker as one native OCO pair, move or cancel that bracket, flatten; see placing orders.
  • Futures only. Your account, your risk.

requiresAccount & Execution API or above

A standalone package, separate from the data ones, and also included in the Terminal plan, the legacy all-in-one plan, the Desk bundle and every-sleeve algo access. Prices on the pricing page.

Your positions

One call returns every Rithmic account linked to your API key, each with its latest position snapshot: net quantity per symbol, average open fill price, open and closed PnL, and account-level balances. A session is maintained automatically for every account you link — no algo activation required — and snapshots refresh about once a minute.

curl https://api.tick-stream.xyz/v1/exec/positions \
  -H "Authorization: Bearer sk_live_…"
{
  "accounts": [
    {
      "accountId": "acct_9f2c…",
      "updatedAt": 1751712000000,
      "account": {
        "name": "PAPER-12345",
        "metrics": { "accountBalance": 52140.50, "openPnl": 185.00, "closedPnl": -40.00 }
      },
      "positions": [
        {
          "symbol": "NQU6", "exchange": "CME",
          "qty": 2, "avgOpenPrice": 20010.25,
          "openPnl": 185.00, "closedPnl": -40.00
        }
      ]
    }
  ]
}

positions contains open positions (net quantity ≠ 0). updatedAt is the snapshot time in ms; if your session is disconnected the snapshot is the last known state.

Your trade history

Every fill on your linked accounts, as raw data — analyze your own trading however you like: win rates, per-symbol PnL, time-of-day breakdowns, slippage vs. our tick history. This works for any account you link in the dashboard, whether or not an algo trades it. History accumulates from the moment your account is linked (plus whatever your broker's order plant returns on connect) and survives restarts.

curl "https://api.tick-stream.xyz/v1/exec/fills?start=1751000000&symbol=NQU6" \
  -H "Authorization: Bearer sk_live_…"

Query: ?account=, ?symbol=, ?start=/?end= (epoch seconds), ?limit= (default 5000, most recent kept). Fills are returned oldest-first.

{
  "metrics": { "count": 142, "buyQty": 96, "sellQty": 96 },
  "fills": [
    {
      "accountId": "acct_9f2c…", "id": "20260705-1834",
      "ts": 1751713433, "tradeDate": "20260705",
      "symbol": "NQU6", "side": "buy",
      "qty": 2, "price": 20008.75,
      "orderNum": "233442211", "orderType": "MKT"
    }
  ]
}

Your orders

Every order you place through the Account & Execution API is tracked against the API key that placed it. List them — each one accepted or rejected — and watch them live in your dashboard.

curl "https://api.tick-stream.xyz/v1/exec/orders?status=rejected&symbol=MNQ&start=1789500000" \
  -H "Authorization: Bearer sk_live_…"

The journal records every order, bracket change and flatten that reaches your broker session — whether it came through this API, the terminal's trade panel, or a terminal script — together with what the broker answered. Fills are the record of what actually traded; the journal is the record of what was asked for.

kindorder (market entry), protect (bracket set, moved or cancelled) or close (flatten)
sourceapi, terminal or script
status / erroraccepted by the broker session, or rejected with the broker's reason
submittedAtMilliseconds since the epoch

Query: ?status=accepted|rejected|all (default all), ?account=, ?symbol= (a root like MNQ matches its contracts), ?start=/?end= (epoch seconds), ?limit= (default 1000, newest first). The journal keeps your newest 5,000 entries.

{
  "orders": [
    {
      "id": "j1789557328114-3f2a", "kind": "order", "source": "terminal",
      "account": "APEX-459021-05", "symbol": "MNQZ6", "side": "buy", "qty": 1,
      "orderType": "market", "stop": 29320.25, "target": 29410.25,
      "status": "accepted", "error": null, "submittedAt": 1789557328114
    }
  ]
}

Placing orders

Three write endpoints, all POST with a JSON body and your API key. They route to your own Rithmic account — the same path our GEX terminal's trade panel and our live algo sleeves use. A bare root (MNQ) resolves to the front contract; an explicit contract (MNQU6) is passed through. Prices must sit on the tick grid of the contract.

EndpointBodyWhat it does
/v1/exec/ordersymbol, side, qty, stop?, target? Market entry (buy / sell, 1–5 contracts). With stop and target we place the bracket with a separate protect step after the entry was accepted, as one native OCO pair at the exchange: when one side fills, the other is cancelled there and then, whether or not you are online.
/v1/exec/protectsymbol, stop?, target? Sets, moves or cancels the resting bracket. The call replaces the whole bracket: it cancels what rests for that symbol and places fresh orders sized to your current net position. Between the cancel and the new orders the position is briefly unprotected; if the cancel fails the call answers ok: false and the previous bracket may still rest, unchanged. Idempotent — calling it every minute to trail a stop is how it is meant to be used. Always send both prices; a missing one drops that side, both missing cancels the bracket.
/v1/exec/closesymbol Flattens your position in that symbol at market.

Several Rithmic accounts linked? Name the one to trade with "account": "<accountId>" (ids are in positions); with one account linked it is optional.

Entry with a resting bracket

curl -X POST https://api.tick-stream.xyz/v1/exec/order \
  -H "Authorization: Bearer sk_live_…" -H "Content-Type: application/json" \
  -d '{"symbol": "MNQ", "side": "buy", "qty": 1, "stop": 23380.00, "target": 23440.00}'
import requests
H = {"Authorization": "Bearer sk_live_…"}
r = requests.post("https://api.tick-stream.xyz/v1/exec/order", headers=H, json={
    "symbol": "MNQ", "side": "buy", "qty": 1,
    "stop": 23380.00, "target": 23440.00,
}).json()
{ "ok": true, "orderId": "233442211" }

ok and orderId cover the entry only. To confirm the bracket, look for the protect entry that follows it in /v1/exec/orders, or call /v1/exec/protect with the same levels.

Move the stop or target

Re-send both levels whenever one changes. The response tells you how many orders rest now, how many were replaced, and the position size they cover — qty: 0 means you are flat, so a filled stop or target shows up here on the next call.

curl -X POST https://api.tick-stream.xyz/v1/exec/protect \
  -H "Authorization: Bearer sk_live_…" -H "Content-Type: application/json" \
  -d '{"symbol": "MNQ", "stop": 23395.00, "target": 23440.00}'
while True:
    time.sleep(60)
    px = requests.get("https://api.tick-stream.xyz/v1/quote", params={"symbol": "MNQ"}, headers=H).json()["price"]
    stop = max(stop, round(round((px - 15) / 0.25) * 0.25, 2))   # only ever tighter, on the tick grid
    r = requests.post("https://api.tick-stream.xyz/v1/exec/protect", headers=H,
                      json={"symbol": "MNQ", "stop": stop, "target": target}).json()
    if r["qty"] == 0: break   # one side filled, the exchange cancelled the other
{
  "ok": true, "placed": 2, "cancelled": 2, "qty": 1,
  "stop": 23395.00, "target": 23440.00, "side": "S"
}

Flatten

curl -X POST https://api.tick-stream.xyz/v1/exec/close \
  -H "Authorization: Bearer sk_live_…" -H "Content-Type: application/json" \
  -d '{"symbol": "MNQ"}'

Errors

Every write answers HTTP 409 with {"ok": false, "error": "…"} when the broker refuses (a failed protect also reports protectedQty and unprotected), and one of these codes before anything reaches the broker:

CodeMeaning
execution_requiredYour key does not hold the Account & Execution package.
no_linked_accountNo Rithmic account is linked to this key yet — link one in the dashboard.
unknown_account (404)The account in the body is not one of your linked accounts.
account_requiredMore than one Rithmic account is linked and the body names none.
algo_owns_symbolOne of our algos is active on that root for this account and would reconcile your order away. Deactivate it or trade another account.
bad_symbol / bad_qty / bad_sideUnknown futures symbol, quantity outside 1–5, or a side other than buy/sell.
bad_bodyThe body is not JSON of the shape the endpoint expects.

Endpoints & status

MethodEndpointPurposeStatus
GET/v1/exec/positionsAll positions across your linked accountslive
GET/v1/exec/fillsYour trade history — every fill, filterablelive
GET/v1/exec/ordersList your orderslive
POST/v1/exec/orderMarket entry; with stop/target, a native OCO bracket follows via protectlive
POST/v1/exec/protectSet, move or cancel the resting stop/targetlive
POST/v1/exec/closeFlatten the position at marketlive

Accounts are linked in the dashboard; the read endpoints work from that moment, no algo activation required. Limit orders and cancelling a single order by id are not exposed — the bracket is the one resting order type, and protect with no prices cancels it. Background on Rithmic's own interfaces and why this layer exists: the Rithmic API problem.

Your Rithmic credentials are used only to route your own orders and are never shared. See the broader safety model in our rollout notes — demo-first, per-user isolation, kill-switch.