tickerall-com Trade History API
The Trade History API from tickerall-com — 4 operation(s) for trade history.
The Trade History API from tickerall-com — 4 operation(s) for trade history.
Every API here is available over the APIs.io API and to AI agents over MCP.
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
find_apisBrowse and filter every API in the catalog.get_api_artifactsOne API's artifacts, grouped by type.get_openapiThe primary OpenAPI for this API.find_similar_apisAPIs that look like this one.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.curl "https://apis.io/api/v1/apis/tickerall-com:tickerall-com-trade-history-api"
curl "https://apis.io/api/v1/apis?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
title: TickerAll Trade History API
version: 1.0.0
description: 'Hosted MetaTrader 5 & MT4 broker API. Connect a broker account, then place trades, pull historical candles, read positions and closed-trade history, and manage your accounts — from your own code, with no local MetaTrader terminal (runs on Linux, macOS, containers, anywhere).
Live market data streams over a WebSocket at `wss://api.tickerall.com/v1/stream`, authenticated with the same bearer token (an `Authorization: Bearer ` header on the upgrade, or `?token=` for browser clients).
**Authentication:** every endpoint except the public demo feed takes an `Authorization: Bearer ` header. Get an API key at https://tickerall.com.
**Error codes:**
- `UNAUTHORIZED` (401): Missing, malformed, or invalid Authorization header / API key.
- `VALIDATION_ERROR` (400): The request body or params failed validation. A details array lists the offending fields.
- `BROKER_AUTH_FAILED` (401): The broker rejected the login — wrong account number, password, or server. Returned by POST /v1/sessions and POST /v1/accounts/:id/reconnect. Fix the detail and retry.
- `BROKER_UNREACHABLE` (503): Could not reach the broker (network/endpoint down). Retry shortly. (A wrong password no longer maps here — see BROKER_AUTH_FAILED.)
- `BROKER_ACCOUNT_NOT_HOT` (409): The connection cooled. Call POST /v1/sessions with credentials to reconnect.
- `BROKER_REJECTED` (422): The broker refused the order/close/modify. The reason is in message (e.g. bad volume, market closed, stop level).
- `TICKET_NOT_FOUND` (404): The position ticket is not open on this account.
- `BROKER_ACCOUNT_NOT_FOUND` (404): No broker account with that id belongs to your key.
- `BROKER_ACCOUNT_ALREADY_LINKED` (409): That broker account is already linked to another TickerAll customer.
- `FREE_TIER_LIVE_REJECTED` (403): Live account on Free outside the Terminal, or a second one at once. API live starts at Trader.
- `DEMO_ACCOUNT_RESERVED` (403): That broker account is reserved by TickerAll for the public demo and cannot be attached.
- `TIER_ACCOUNT_CAP_REACHED` (403): You hit your plan’s broker-account cap. Upgrade, or contact us for Enterprise.
- `BROKER_NOT_FOUND` (422): The server name could not be resolved — it is not a known MT4/MT5 server. Use the exact name your terminal shows (MT5 servers are usually "Broker-MT5…"). No account row is left behind by a failed attempt.
- `BROKER_ACCOUNT_INVALID` (422): The broker refused the account itself (disabled, archived, expired). Fix it in your broker portal; retrying will not help.
- `DISCOVERY_UNAVAILABLE` (503): Broker lookup is temporarily paused after upstream errors. Your server name was NOT rejected — retry in a few minutes. Never a verdict on the name.
- `SYMBOL_CATALOG_UNAVAILABLE` (503): The account is connected but its instrument list could not be read (a TickerAll-side gap, not an empty account). GET /symbols and /symbol-specs return this instead of an empty list, so an empty array never masquerades as "no symbols". Retry; if it persists, contact support with the broker and account type.
- `ALWAYS_HOT_TIER_REQUIRED` (403): Always-hot needs a paid plan: Trader ($0.99/mo per connection) or Pro / Enterprise (included).
- `VAULT_PURGE_PENDING` (503): DELETE /v1/accounts/:id could not yet destroy the account’s remembered password, so the account was not removed. Retry shortly.
- `REMEMBER_PRO_REQUIRED` (403): Remembered credentials (server-side password storage, opt-in) are available on the Pro and Enterprise plans.
- `rate_limited` (429): Too many requests for this API key this minute. Budgets per key: 300/min order writes (a bulk call counts once), 600/min candles and history, 120/min POST /v1/sessions, 2000/min everything else. Wait Retry-After seconds; every response carries RateLimit-Limit, RateLimit-Remaining and RateLimit-Reset (seconds) for its budget.
- `INTERNAL_ERROR` (500): Unexpected server error. Safe to retry idempotent calls.'
contact:
name: TickerAll
url: https://tickerall.com
email: hello@tickerall.com
x-providerName: tickerall.com
x-origin:
- format: openapi
version: '3.0'
url: https://tickerall.com/openapi.json
x-logo:
url: https://tickerall.com/tickerall-social-logo-v4.png
servers:
- url: https://api.tickerall.com
description: TickerAll production API
security:
- bearerAuth: []
tags:
- name: Trade History
paths:
/v1/accounts/{id}/history:
get:
tags:
- Trade History
summary: Closed-trade history for the account — executed trades paired into round-trips…
description: 'Closed-trade history for the account — executed trades paired into round-trips (entry + exit), the equivalent of MT5’s history_deals_get. Returns the recent window your broker provides on connect plus any trades closed live during the session. Filter by symbol and close-time range.
- openTime / closeTime are UTC. brokerOpenTime / brokerCloseTime are the same instants in the broker’s server-local time (RFC 3339 with offset), and serverTimeOffsetSeconds is that offset, measured from the broker’s own records. null means it could not be derived yet (no deal or open position on the account, or MT4); 0 means a UTC server.
- Returns what the broker provides for the account on connect plus trades closed live during the current session — how far back that reaches is set by the broker. from/to filter those rows; they do not fetch beyond what the broker provides.
- Each row is a round-trip: ticket is the open/position ticket; closeTicket is the closing deal (may be null for a trade closed live this session). profit is realised P/L in the account currency.
- Open positions are never listed here — they live under GET /v1/accounts/:id/positions. complete=true is a confirmed round-trip with trustworthy P/L; complete=false marks a closed row we could not pair with its opening deal, where profit is reported as null rather than a misleading 0.
- A partially closed position that still has volume open is listed as one row with partial: true: volume is the closed volume so far, remainingVolume is the volume still open, profit/swap/commission are the broker-booked figures for the closed part, and complete is false. When the rest closes, that row is replaced by a single row with the same ticket, the full volume, complete: true and no partial or remainingVolume fields.
- swap is provided: the swap the broker booked on the position, in the account currency (non-zero for positions held across a rollover). commission is the commission the broker charged on the round-trip (opening plus closing deal), in the account currency, stored as the broker books it: negative for a charge, 0 on account types that charge none. A trade opened and closed within the current session shows its commission within about 30 seconds of the close (the ledger is re-read on the next history read after a balance change)
- A cheap read that never disturbs your live tick stream. On a connection that has cooled you get 409 BROKER_ACCOUNT_NOT_HOT — POST /v1/sessions to reconnect.'
operationId: getV1AccountsIdHistory
parameters:
- name: id
in: path
required: true
description: accountId.
schema:
type: string
- name: symbol
in: query
required: false
description: Narrow to one broker-native symbol, e.g. "ETHUSD". Omit for all symbols.
schema:
type: string
- name: from
in: query
required: false
description: Only trades closed at/after this time. A value that does not parse is 400 INVALID_DATE.
schema:
type: string
format: date-time
- name: to
in: query
required: false
description: Only trades closed at/before this time.
schema:
type: string
format: date-time
- name: limit
in: query
required: false
description: Rows per page, newest-first. Defaults to 500, capped at 5000.
schema:
type: number
- name: cursor
in: query
required: false
description: The nextCursor from the previous page, passed back unchanged to get the next (older) page. Omit for the newest page. A malformed cursor, or one from another endpoint, is 400 INVALID_CURSOR.
schema:
type: string
- name: waitMs
in: query
required: false
description: How long to wait (ms) for history to populate on a just-connected account. Defaults to 4000; pass 0 to skip the wait on a warm connection.
schema:
type: number
responses:
'200':
description: 200 OK
content:
application/json:
schema:
type: object
example:
trades:
- ticket: '4072808150'
symbol: ETHUSD
side: BUY
volume: 0.1
openPrice: 2500.5
closePrice: 2510.25
openTime: '2026-05-20T10:00:00.000Z'
closeTime: '2026-05-20T12:30:00.000Z'
brokerOpenTime: '2026-05-20T13:00:00+03:00'
brokerCloseTime: '2026-05-20T15:30:00+03:00'
profit: 0.98
swap: -0.12
commission: 0
stopLoss: 0
takeProfit: 0
closeTicket: '4072808151'
complete: true
count: 1
limit: 500
hasMore: false
nextCursor: null
serverTimeOffsetSeconds: 10800
'400':
$ref: '#/components/responses/Error'
'401':
$ref: '#/components/responses/Error'
default:
$ref: '#/components/responses/Error'
/v1/accounts/{id}/deals-history:
get:
tags:
- Trade History
summary: Individual deal fills for the account — one row per executed deal, the…
description: 'Individual deal fills for the account — one row per executed deal, the equivalent of MT5’s "Deals" view (while /history is the aggregated one-row-per-position "Positions" view). Each entry — the open, and every PARTIAL and full close — is its own row with its own ticket, time, price and volume. Filter by symbol and time range.
- One row per DEAL (fill), not per position: a position opened and then closed in two parts is three rows — the open (entry "IN") and the two closing deals (entry "OUT"), each with its own ticket, time, price and volume. Use this when you need the individual exits; use GET /v1/accounts/:id/history for the aggregated one-row-per-position view (an MT5 terminal shows both the same way, as "Deals" and "Positions").
- entry is the deal’s role: "IN" opened/added, "OUT" closed/reduced, "INOUT" a reversal, "OUT_BY" closed by an opposing position. positionId ties every deal to the position it belongs to; ticket is the deal’s own id.
- profit / swap / commission are the broker-booked realised figures on a CLOSE ("OUT") fill, in the account currency — so a partial exit shows its own exact realised P/L. They are ABSENT (not 0) on an "IN" / open fill, which books no P/L — treat absent as "not booked", never as 0.
- time is UTC; brokerTime is the same instant in the broker’s server-local time (RFC 3339 with offset), and serverTimeOffsetSeconds is that offset — null if not derivable yet, 0 for a UTC server.
- Trade fills only — deposits, withdrawals and other balance-ledger entries are NOT here; they live on GET /v1/accounts/:id/balance-operations.
- Paged: while hasMore is true, call again with cursor=nextCursor (same filters) for the next older page; every row comes back exactly once, in order. nextCursor is null on the last page.'
operationId: getV1AccountsIdDealshistory
parameters:
- name: id
in: path
required: true
description: accountId.
schema:
type: string
- name: symbol
in: query
required: false
description: Narrow to one broker-native symbol, e.g. "BTCUSDm". Omit for all symbols.
schema:
type: string
- name: from
in: query
required: false
description: Only deals executed at/after this time. A value that does not parse is 400 INVALID_DATE.
schema:
type: string
format: date-time
- name: to
in: query
required: false
description: Only deals executed at/before this time.
schema:
type: string
format: date-time
- name: limit
in: query
required: false
description: Rows per page, newest-first. Defaults to 500, capped at 5000.
schema:
type: number
- name: cursor
in: query
required: false
description: The nextCursor from the previous page, passed back unchanged to get the next (older) page. Omit for the newest page. A malformed cursor, or one from another endpoint, is 400 INVALID_CURSOR.
schema:
type: string
- name: waitMs
in: query
required: false
description: How long to wait (ms) for history to populate on a just-connected account. Defaults to 4000; pass 0 to skip the wait on a warm connection.
schema:
type: number
responses:
'200':
description: 200 OK
content:
application/json:
schema:
type: object
example:
deals:
- ticket: '1952757330'
positionId: '2075644599'
symbol: BTCUSDm
side: SELL
entry: OUT
volume: 0.05
price: 81390.12
stopLoss: 0
takeProfit: 0
profit: -9.27
swap: 0
commission: -0.4
time: '2026-10-18T14:21:10.000Z'
brokerTime: '2026-10-18T17:21:10+03:00'
count: 1
limit: 500
hasMore: false
nextCursor: null
serverTimeOffsetSeconds: 10800
'400':
$ref: '#/components/responses/Error'
'401':
$ref: '#/components/responses/Error'
default:
$ref: '#/components/responses/Error'
/v1/accounts/{id}/orders-history:
get:
tags:
- Trade History
summary: Historical ORDERS for the account — one row per order that reached a terminal…
description: 'Historical ORDERS for the account — one row per order that reached a terminal state (filled, cancelled, expired, rejected), the equivalent of MT5’s history orders. Distinct from /deals-history (the individual fills) and /history (the aggregated round-trips): this is the order-lifecycle view. Filter by symbol and time range.
- One row per ORDER. orderTicket is the order’s own ticket (distinct from the position ticket); positionId links it to the position it opened or acted on. volume is the order’s volume and price its request / fill price.
- state is the order’s final ENUM_ORDER_STATE: "FILLED", "CANCELED", "EXPIRED", "REJECTED", "PARTIAL", "PLACED" or "UNKNOWN". dealCount is how many deal fills the order produced (a market order is normally 1).
- time is UTC; brokerTime is the same instant in the broker’s server-local time (RFC 3339 with offset), and serverTimeOffsetSeconds is that offset — null if not derivable yet, 0 for a UTC server.
- For the individual fills an order produced, use GET /v1/accounts/:id/deals-history (join on positionId); for the aggregated round-trip with realised P/L, GET /v1/accounts/:id/history. Trade orders only — no balance-ledger entries.
- Paged: while hasMore is true, call again with cursor=nextCursor (same filters) for the next older page; every row comes back exactly once, in order. nextCursor is null on the last page.'
operationId: getV1AccountsIdOrdershistory
parameters:
- name: id
in: path
required: true
description: accountId.
schema:
type: string
- name: symbol
in: query
required: false
description: Narrow to one broker-native symbol, e.g. "BTCUSDm". Omit for all symbols.
schema:
type: string
- name: from
in: query
required: false
description: Only orders at/after this time. A value that does not parse is 400 INVALID_DATE.
schema:
type: string
format: date-time
- name: to
in: query
required: false
description: Only orders at/before this time.
schema:
type: string
format: date-time
- name: limit
in: query
required: false
description: Rows per page, newest-first. Defaults to 500, capped at 5000.
schema:
type: number
- name: cursor
in: query
required: false
description: The nextCursor from the previous page, passed back unchanged to get the next (older) page. Omit for the newest page. A malformed cursor, or one from another endpoint, is 400 INVALID_CURSOR.
schema:
type: string
- name: waitMs
in: query
required: false
description: How long to wait (ms) for history to populate on a just-connected account. Defaults to 4000; pass 0 to skip the wait on a warm connection.
schema:
type: number
responses:
'200':
description: 200 OK
content:
application/json:
schema:
type: object
example:
orders:
- orderTicket: '2075644598'
positionId: '2075644599'
symbol: BTCUSDm
side: BUY
volume: 0.1
price: 81555
state: FILLED
dealCount: 1
time: '2026-10-18T14:20:02.000Z'
brokerTime: '2026-10-18T17:20:02+03:00'
count: 1
limit: 500
hasMore: false
nextCursor: null
serverTimeOffsetSeconds: 10800
'400':
$ref: '#/components/responses/Error'
'401':
$ref: '#/components/responses/Error'
default:
$ref: '#/components/responses/Error'
/v1/accounts/{id}/balance-operations:
get:
tags:
- Trade History
summary: Balance operations for the account — money moving in or out (deposits…
description: 'Balance operations for the account — money moving in or out (deposits, withdrawals, credits, charges, corrections, bonuses), kept separate from trades so a deposit is never summed as P/L. The equivalent of MT5’s DEAL_TYPE_BALANCE family. Newest-first, like every history route — reverse it to fold into an equity curve.
- type is one of deposit, withdrawal, credit, charge, correction, bonus, commission, other. deposit / withdrawal are derived from the sign of amount; the rest map the broker’s own ledger kinds. dealType is the broker’s raw ENUM_DEAL_TYPE, passed through so an unrecognised kind is never silently flattened.
- amount is signed and in the account currency, exactly as the broker booked it: positive = money in, negative = money out.
- Paged: while hasMore is true, call again with cursor=nextCursor (same filters) for the next older page; every row comes back exactly once, in order. nextCursor is null on the last page.
- time is UTC; brokerTime is the same instant in the broker’s server-local time (RFC 3339 with offset), and serverTimeOffsetSeconds is that offset. null means it could not be derived yet (no deal or open position on the account, or MT4); 0 means a UTC server.
- Returns what the broker provides for the account on connect — the same rule as /history. An empty list means no operations in what the broker provided, not that the account was never funded; treat the oldest row as a floor, not the account’s opening.
- No symbol filter: balance operations are account-level. Realtime: the WebSocket account channel pushes an account_update on every balance change, including deposits and withdrawals — read this endpoint on that push to learn what moved the balance. A new operation is refreshed from the broker on the first read after the balance moved, so it is readable within seconds of the push.
- A cheap read that never disturbs your live tick stream. On a connection that has cooled you get 409 BROKER_ACCOUNT_NOT_HOT — POST /v1/sessions to reconnect.'
operationId: getV1AccountsIdBalanceoperations
parameters:
- name: id
in: path
required: true
description: accountId.
schema:
type: string
- name: from
in: query
required: false
description: Only operations at/after this time. A value that does not parse is 400 INVALID_DATE.
schema:
type: string
format: date-time
- name: to
in: query
required: false
description: Only operations at/before this time.
schema:
type: string
format: date-time
- name: limit
in: query
required: false
description: Rows per page, newest-first (limit=1 is the most recent operation). Defaults to 500, capped at 5000.
schema:
type: number
- name: cursor
in: query
required: false
description: The nextCursor from the previous page, passed back unchanged to get the next (older) page. Omit for the newest page. A malformed cursor, or one from another endpoint, is 400 INVALID_CURSOR.
schema:
type: string
- name: waitMs
in: query
required: false
description: How long to wait (ms) for history to populate on a just-connected account. Defaults to 4000; pass 0 to skip the wait on a warm connection.
schema:
type: number
responses:
'200':
description: 200 OK
content:
application/json:
schema:
type: object
example:
operations:
- ticket: '4138294581'
type: deposit
dealType: 2
amount: 500
time: '2026-09-12T15:44:08.000Z'
brokerTime: '2026-09-12T18:44:08+03:00'
account: 434221754
count: 1
limit: 500
hasMore: false
nextCursor: null
serverTimeOffsetSeconds: 10800
windowed: true
'400':
$ref: '#/components/responses/Error'
'401':
$ref: '#/components/responses/Error'
default:
$ref: '#/components/responses/Error'
components:
schemas:
Error:
type: object
properties:
error:
type: object
properties:
code:
type: string
description: Machine-readable error code (see the description).
message:
type: string
description: Human-readable explanation.
details:
type: array
items:
type: object
description: Optional per-field validation details.
required:
- code
- message
responses:
Error:
description: Error — see the `code` field and the error-code list in the API description.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
securitySchemes:
bearerAuth:
type: http
scheme: bearer
description: 'Your TickerAll API key, sent as `Authorization: Bearer <API_KEY>`.'