TICKERALL!
Official SDK · TypeScript / Node

TickerAll TypeScript SDK

A typed client for the TickerAll REST + WebSocket API — place trades, stream live market data, and manage broker sessions, with idempotency keys and automatic reconnects built in. Requires Node 18+.

Install & connect

One client object holds your API key and exposes every namespace. The same key can drive many broker accounts at once, each addressed by its accountId.

Install

Add the package. Requires Node 18+ / Python 3.9+; no native dependencies.

TypeScript
npm install @tickerall/sdk
new Tickerall(config)

Create a client. Only apiKey is required; baseUrl / streamUrl / timeout / userAgent / onRearm are optional.

TypeScript
import { Tickerall } from '@tickerall/sdk'

const client = new Tickerall({
  apiKey: process.env.TICKERALL_API_KEY!,
  // baseUrl?:   'https://api.tickerall.com'
  // streamUrl?: 'wss://api.tickerall.com/v1/stream'
  // timeout?:   30_000  (ms, per request)
})

Sessions

Connect a broker account and get its accountId. keepAlive caches the credentials in this process’s memory (never persisted) so the client transparently re-arms an account that goes cold — e.g. after a service restart.

sessions.start(params)

Connect a broker account → returns its accountId, isDemo, status, expiresAt. Pass terminalType to pick the terminal type (MOBILE default, or WEB — WEB requires the broker’s webTerminalUrl).

TypeScript
const session = await client.sessions.start({
  broker: 'mt5',
  server: 'Exness-MT5Trial7',
  account: 12345678,
  password: process.env.MT5_PASSWORD!,
  // Optional terminal type — 'MOBILE' (default) or 'WEB'. Omit for MOBILE.
  terminalType: 'MOBILE',
})
// session.accountId, session.isDemo

// For WEB, the broker's web-terminal URL is required (TypeScript enforces it):
// const web = await client.sessions.start({
//   broker: 'mt5', server: 'YourBroker-Server', account: 12345678,
//   password: process.env.MT5_PASSWORD!,
//   terminalType: 'WEB', webTerminalUrl: 'https://mt5.yourbroker.com',
// })
sessions.keepAlive(params)

Start a session AND keep it alive — credentials cached in RAM for transparent re-arm.

TypeScript
const session = await client.sessions.keepAlive({
  broker: 'mt5', server: 'Exness-MT5Trial7',
  account: 12345678, password: '...',
})
// later calls re-arm automatically if the account went cold
sessions.stopKeepAlive(accountId)

Stop auto-re-arming an account and drop its cached credentials.

TypeScript
client.sessions.stopKeepAlive(accountId)
sessions.rearm(accountId)

Manually re-arm a kept account now (normally unnecessary — the client does it on demand).

TypeScript
await client.sessions.rearm(accountId)
sessions.pendingRearm()

Always-hot accounts that currently have no live connection (need a credentials refresh).

TypeScript
const pending = await client.sessions.pendingRearm()
sessions.rearmPending()

Re-arm every pending account you hold kept credentials for. Returns the re-armed IDs.

TypeScript
const ids = await client.sessions.rearmPending()
sessions.end(accountId)

Disconnect a session (also stops keeping it alive).

TypeScript
await client.sessions.end(accountId)

Accounts

List and inspect the broker accounts linked to your key — balances, open positions, tradeable symbols and their volume specs.

accounts.list()

All broker accounts linked to your API key.

TypeScript
const accounts = await client.accounts.list()
accounts.get(accountId)

Full snapshot — balance/leverage info and open positions when online.

TypeScript
const detail = await client.accounts.get(accountId)
for (const p of detail.positions) {
  console.log(p.ticket, p.symbol, p.side, p.volume, p.profit)
}
accounts.symbols(accountId)

The broker-native symbol names this account can trade.

TypeScript
const symbols = await client.accounts.symbols(accountId)
accounts.symbolSpecs(accountId)

Per-symbol volume specs (min / max / step) + trade mode — validate an order size before placing it (MT5 only).

TypeScript
const specs = await client.accounts.symbolSpecs(accountId)
// each: { name, volumeMin, volumeMax, volumeStep, specSource, tradeMode }
accounts.remove(accountId)

Remove a broker account from your roster — disconnects it and drops it from your list and billing. Does not touch the broker account or its open positions; reconnect with sessions.start to re-add it.

TypeScript
await client.accounts.remove(accountId)
accounts.migrate(accountId, to)

Switch the terminal type (MOBILE↔WEB) on a live account. Open positions/orders/balance are preserved (they live broker-side). The switch is zero-gap — the new transport is warmed before the old is dropped — and runs only when the account is idle. Returns status:"noop" if already on `to`.

TypeScript
const res = await client.accounts.migrate(accountId, 'WEB')
// res.terminalType, res.status ('noop' | 'migrated')

Orders

Place market and pending (limit / stop) orders, and manage resting pending orders. State-changing calls carry a stable idempotency key so a retry can’t double-execute.

orders.place(accountId, params)

Place a market / limit / stop order. price is required for limit & stop.

TypeScript
const order = await client.orders.place(accountId, {
  type: 'market',
  symbol: 'BTCUSDm',
  side: 'BUY',
  volume: 0.1,
  stopLoss: 58000,
  takeProfit: 72000,
})
// order.ticket, order.status ('open' | 'pending')
orders.listPending(accountId)

List resting pending orders (LIMIT / STOP). MT5 only — MT4 returns an empty list.

TypeScript
const pending = await client.orders.listPending(accountId)
// each: { ticket, symbol, type, side, orderType, volume, price, ... }
orders.cancelPending(accountId, ticket)

Cancel a resting pending order by its ticket.

TypeScript
await client.orders.cancelPending(accountId, 4521969907)
orders.modifyPending(accountId, ticket, params)

Change a pending order’s trigger price / SL / TP. Omitted fields are preserved.

TypeScript
await client.orders.modifyPending(accountId, 4521969907, {
  price: 60000, stopLoss: 58000, takeProfit: 72000,
})

Positions

Close (fully or partially) and modify the stop-loss / take-profit on open positions.

positions.close(accountId, ticket, params?)

Close a position fully, or partially when volume is given.

TypeScript
await client.positions.close(accountId, 70001)            // full
await client.positions.close(accountId, 70001, { volume: 0.05 }) // partial
positions.modify(accountId, ticket, params)

Set or change the SL / TP on an open position. Provide at least one.

TypeScript
await client.positions.modify(accountId, 70001, {
  stopLoss: 60000, takeProfit: 72000,
})

Candles

Historical OHLC candles from a connected account, across all nine timeframes. Coarser timeframes reach further back; deep look-backs ride an isolated history connection so they don’t disturb your live tick stream.

candles.get(accountId, params)

Fetch OHLC bars for a symbol. Pass a large hours and take what comes back.

TypeScript
const bars = await client.candles.get(accountId, {
  symbol: 'BTCUSDm', hours: 8760, timeframe: 'D1',
})
// each: { timestamp, open, high, low, close, bid }

Trade history

Closed-trade history — executed deals paired into round-trips, from the broker’s recent deal window plus any closes seen live this session.

history.get(accountId, params?)

Closed round-trips, optionally filtered by symbol / from / to / limit.

TypeScript
const trades = await client.history.get(accountId, {
  symbol: 'BTCUSDm', limit: 100,
})
// each: { ticket, side, volume, openPrice, closePrice, profit, ... }

Realtime stream

A single self-healing WebSocket pushes live ticks, position events, and account snapshots. It heartbeats, reconnects with backoff, and re-subscribes automatically — you register callbacks and go.

stream.connect()

Open the stream, register callbacks, and subscribe to topics.

TypeScript
const stream = await client.stream.connect()

stream.on('tick', (e) => console.log(e.symbol, e.bid, e.ask, e.timestamp))
stream.on('position', (e) => console.log(e.event, e.position.ticket, e.position.profit))
stream.on('account', (e) => console.log(e.snapshot.balance))
stream.on('reconnect', (e) => console.log('reconnecting', e.attempt))

await stream.subscribeTicks(accountId, ['BTCUSDm', 'ETHUSDm'])
await stream.subscribePositions(accountId)
await stream.subscribeAccount(accountId)
O(1) tick cache pattern

Let the WebSocket fill a dict/map so price reads are instant with no polling.

TypeScript
const latest = new Map<string, TickEvent>()
stream.on('tick', (e) => latest.set(e.symbol, e))
// latest.get('BTCUSDm') — instant, no network
state & teardown

Query connection state, wait for it, unsubscribe, and close.

TypeScript
stream.getState()          // 'connecting' | 'open' | 'reconnecting' | 'closed'
stream.isConnected()
await stream.waitUntilConnected(30_000)
await stream.unsubscribeTicks(accountId, ['ETHUSDm'])
await stream.close()
setBeforeResubscribe(cb)

Advanced hook — runs after a reconnect, just before subscriptions are re-sent. Use it to re-arm kept sessions so the stream transparently survives a backend restart.

TypeScript
stream.setBeforeResubscribe(async () => {
  await client.sessions.rearmPending()
})

Errors

Every failure is a typed error carrying status / code / requestId / details / transient. Catch the base class, or a narrow subclass. transient marks a momentary connectivity issue that is safe to retry.

Error hierarchy

TickerallApiError (base) → Auth (401), Forbidden (403), Validation (400/422), NotFound (404), Broker (broker rejection), ServiceUnavailable (transient).

TypeScript
import {
  TickerallApiError,
  TickerallServiceUnavailableError,
  TickerallBrokerError,
} from '@tickerall/sdk'

try {
  await client.orders.place(accountId, { type: 'market', symbol: 'BTCUSDm', side: 'BUY', volume: 0.1 })
} catch (err) {
  if (err instanceof TickerallServiceUnavailableError) {
    // transient — TickerAll momentarily unreachable; safe to retry
  } else if (err instanceof TickerallBrokerError) {
    // broker rejected the order — err.code, err.message
  } else if (err instanceof TickerallApiError) {
    console.error(err.status, err.code, err.requestId, err.transient)
  }
}

Reliability

State-changing calls (sessions.start, orders.place, positions.close / modify, pending cancel / modify) carry a stable Idempotency-Key, so a retried call can’t double-execute. By default a transient failure fails fast so you can re-decide with fresh prices.

Idempotency keys

Auto-generated per call; supply your own to make a retry safe across process restarts.

TypeScript
await client.orders.place(
  accountId,
  { type: 'market', symbol: 'BTCUSDm', side: 'BUY', volume: 0.1 },
  { idempotencyKey: 'order-2026-06-02-001' },
)
Queue-and-replay

For price-insensitive orders (pending, SL/TP edits), opt into queue-and-replay: held in order and retried with the stable key until connectivity returns.

TypeScript
await client.orders.place(
  accountId,
  { type: 'limit', symbol: 'BTCUSDm', side: 'BUY', volume: 0.1, price: 60000 },
  { queueIfReconnecting: true, queueMaxMs: 60_000 },
)
Kept sessions across restarts

For an always-on connection, keepAlive caches credentials so the client transparently re-arms after a service restart — no manual reconnect.

TypeScript
await client.sessions.keepAlive({ broker: 'mt5', server, account, password })
// later calls just work; the client re-arms under the hood
TypeScript SDK — TickerAll Docs · Ticker All!