npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@tickerall/sdk

v0.1.9

Published

Official TypeScript client for the TickerAll REST + WebSocket API.

Readme

@tickerall/sdk

Official TypeScript 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.

Install

npm install @tickerall/sdk

Requires Node.js 18 or later (native fetch). Bun and Deno are also supported.

Quickstart

import { Tickerall } from '@tickerall/sdk'

const ticker = new Tickerall({ apiKey: process.env.TICKERALL_API_KEY! })

const { accountId } = await ticker.sessions.start({
  broker: 'mt5',
  server: 'Exness-MT5Trial7',
  account: 12345678,
  password: process.env.MT5_PASSWORD!,
})

const order = await ticker.orders.place(accountId, {
  type: 'market',
  symbol: 'EURUSDm',
  side: 'BUY',
  volume: 0.1,
  stopLoss: 1.0800,
  takeProfit: 1.1000,
})

await ticker.sessions.end(accountId)

Configuration

new Tickerall({
  apiKey: 'cf_live_...',                       // required
  baseUrl: 'https://api.tickerall.com',        // optional; override for staging
  streamUrl: 'wss://api.tickerall.com/v1/stream',
  timeout: 30_000,                             // ms; per-request default
  fetch: globalThis.fetch,                     // injection point for tests
  userAgent: 'my-algo/1.0',                    // tacked onto outgoing UA
})

Multiple Tickerall instances are independent — useful for multi-tenant code.

Sessions

const session = await ticker.sessions.start({
  broker: 'mt5',
  server: 'Exness-MT5Trial7',
  account: 12345678,
  password: '...',
})
// { accountId, isDemo, status: 'connected', expiresAt }

await ticker.sessions.end(session.accountId)

Credentials are sent on each sessions.start. TickerAll never persists broker passwords; a session lives only as long as the underlying broker connection.

Terminal type (MOBILE / WEB)

terminalType picks which client the connection presents AS — 'MOBILE' (the default) or 'WEB'. Both expose the full surface (account, quotes, positions, history). 'WEB' requires the broker's web-terminal URL (webTerminalUrl) — web terminals are per-broker-domain, so the URL must be supplied. TypeScript enforces it (passing terminalType: 'WEB' without webTerminalUrl is a compile error):

const session = await ticker.sessions.start({
  broker: 'mt5',
  server: 'YourBroker-Server',
  account: 12345678,
  password: '...',
  terminalType: 'WEB',
  webTerminalUrl: 'https://mt5.yourbroker.com', // required for WEB
  // webEndpoint: 'wss://host/path',            // optional WS override (rare)
})

Accounts

const accounts = await ticker.accounts.list()
const account  = await ticker.accounts.get(accountId)
const symbols  = await ticker.accounts.symbols(accountId)

// Remove an account from your roster (disconnects it + drops it from your list
// and billing; broker account and open positions are untouched). Reversible —
// reconnect the same login with sessions.start to re-add it.
await ticker.accounts.remove(accountId)

If account.status === 'offline', call sessions.start again with credentials to reconnect.

Candles (historical OHLC)

const bars = await ticker.candles.get({ symbol: 'BTCUSDm', hours: 8760, timeframe: 'D1' })
// [{ timestamp, open, high, low, close, bid }, ...]
// timestamp is the bar OPEN time (Unix seconds, UTC); bid mirrors close.

Public endpoint — available on every plan (the API key is sent but isn't required). Timeframes: M1 M5 M15 M30 H1 H4 D1 W1 MN1 (defaults to M5). Coarser timeframes reach further back; one request returns as much history as fits in a few seconds, so pass a large hours and take what comes back.

Orders + positions

const order = await ticker.orders.place(accountId, {
  type: 'market',
  symbol: 'EURUSDm',
  side: 'BUY',
  volume: 0.1,
})
// { ticket, symbol, side, type, volume, status, timestamp, ... }

const limit = await ticker.orders.place(accountId, {
  type: 'limit',
  symbol: 'EURUSDm',
  side: 'BUY',
  volume: 0.1,
  price: 1.0800,
})

await ticker.positions.modify(accountId, order.ticket, { stopLoss: 1.0850 })
await ticker.positions.close(accountId, order.ticket)
await ticker.positions.close(accountId, order.ticket, { volume: 0.05 }) // partial close

Idempotency

State-changing endpoints (sessions.start, orders.place, positions.close, positions.modify) auto-generate an Idempotency-Key (UUID v4) per call. Pass your own to deduplicate retries on your side:

await ticker.orders.place(
  accountId,
  { type: 'market', symbol: 'EURUSDm', side: 'BUY', volume: 0.1 },
  { idempotencyKey: 'my-strategy-tick-12345' },
)

Resilience

TickerAll keeps a fast, always-on connection to your broker, and the SDK is built so a momentary backend blip — a deploy, a restart, a network hiccup — doesn't break an idle app. The stream reconnects silently and re-sends your subscriptions; nothing is thrown unless you actively try to do something during the window.

Trades fail fast by default. If you place an order while TickerAll is momentarily unreachable, you get a TickerallServiceUnavailableError (err.transient === true) right away — so you can re-decide with fresh prices rather than fire a stale order late:

try {
  await ticker.orders.place(accountId, params)
} catch (err) {
  if (err instanceof TickerallServiceUnavailableError) {
    // momentarily unreachable — retry, or skip this tick
  }
}

Queue-and-replay (opt-in). For calls that aren't price-sensitive (a pending order, an SL/TP edit), pass queueIfReconnecting to have the SDK hold the call and replay it — with its stable idempotency key, so it can't double-execute — until connectivity returns or queueMaxMs (default 60s) elapses:

await ticker.positions.modify(
  accountId, ticket, { stopLoss: 1.0850 },
  { queueIfReconnecting: true, queueMaxMs: 30_000 },
)

Queued calls replay in submission order. Avoid this for market orders — a delayed fill at a moved price is usually worse than a fast failure.

Keep a session alive (auto re-arm)

For an account you want to stay connected with no manual reconnect, start it with keepAlive instead of start. The SDK caches the broker credentials in your process's memory (never persisted) and transparently re-supplies them — re-arming the session — if the account ever goes cold (e.g. TickerAll restarted and dropped its server-side credentials):

const { accountId } = await ticker.sessions.keepAlive({
  broker: 'mt5', server: 'Exness-...', account: 123, password: process.env.MT5_PASSWORD!,
})

// A later call that hits a cold account auto-re-arms and retries — once:
await ticker.orders.place(accountId, { type: 'market', symbol: 'ETHUSDm', side: 'BUY', volume: 0.1 })

ticker.sessions.stopKeepAlive(accountId) // forget the cached credentials
  • The live stream re-arms kept sessions automatically when it reconnects, so subscriptions resume against a hot account.
  • Observe re-arms with the onRearm hook: new Tickerall({ apiKey, onRearm: id => log('re-armed', id) }).
  • Proactively recover after a known outage: await ticker.sessions.rearmPending() re-arms every kept account that TickerAll reports cold (or inspect await ticker.sessions.pendingRearm() yourself).
  • Credentials live in RAM only and are dropped on stopKeepAlive or sessions.end. TickerAll never persists broker passwords — which is also why, after a TickerAll restart, a kept session is recovered by your SDK re-supplying them (automatically), not by us having stored them.

Live stream

const stream = await ticker.stream.connect()

await stream.subscribeTicks(accountId, ['EURUSDm', 'XAUUSDm'])
await stream.subscribePositions(accountId)
await stream.subscribeAccount(accountId)

stream.on('tick',     e => console.log(e.symbol, e.bid, e.ask))
stream.on('position', e => console.log(e.event, e.position))
stream.on('account',  e => console.log(e.snapshot.balance))
stream.on('error',    e => console.error(e.message))
stream.on('reconnect', e => console.log('reconnecting, attempt', e.attempt))
stream.on('close',    e => console.log('closed:', e.code, e.reason))

await stream.close()

Connection state is queryable any time — never pushed at you, so an idle app stays quiet:

stream.getState()             // 'connecting' | 'open' | 'reconnecting' | 'closed'
stream.isConnected()          // true only when live
await stream.waitUntilConnected(10_000)  // resolve when open, reject on timeout

The stream:

  • Reconnects on disconnect with exponential backoff (1s, 2s, 4s, 8s, 16s, max 30s, with jitter) — silently, so an idle app never breaks on a backend blip.
  • Re-sends all known subscriptions on reconnect.
  • Sends a heartbeat every 25 seconds; force-reconnects on missed pong.
  • A missing error listener never crashes your process; subscribe to 'reconnect'/'close' only if you want to observe it.
  • Does not buffer missed ticks (mirrors the server contract — resubscribe and discard stale state if you reconnect).

Errors

All API errors extend TickerallApiError. Check err.status and err.code:

import {
  TickerallApiError,
  TickerallAuthError,
  TickerallForbiddenError,
  TickerallValidationError,
  TickerallNotFoundError,
  TickerallBrokerError,
  TickerallServiceUnavailableError,
} from '@tickerall/sdk'

try {
  await ticker.orders.place(accountId, params)
} catch (err) {
  if (err instanceof TickerallServiceUnavailableError) {
    // TickerAll was momentarily unreachable (network blip, deploy, restart).
    // The request never reached a verdict — safe to retry. See "Resilience".
  } else if (err instanceof TickerallBrokerError) {
    // broker rejected the order, broker is offline, etc.
  } else if (err instanceof TickerallForbiddenError && err.code === 'FREE_TIER_LIVE_REJECTED') {
    // user is on the free tier — upgrade to use live accounts
  } else if (err instanceof TickerallValidationError) {
    console.error('bad input:', err.details)
  } else if (err instanceof TickerallApiError) {
    console.error(err.status, err.code, err.message, err.requestId)
  }
}

Every error carries a boolean err.transienttrue only for TickerallServiceUnavailableError (a connectivity blip you can safely retry), false for everything else (auth, validation, broker rejection — these won't change on retry).

| Error class | Status / code | Notes | | ---------------------------------- | ----------------------------------- | ----------------------------------------------------------- | | TickerallAuthError | 401 | invalid or missing API key | | TickerallForbiddenError | 403 | includes FREE_TIER_LIVE_REJECTED | | TickerallValidationError | 400 / 422 | bad request body or params | | TickerallNotFoundError | 404 | unknown account, ticket, etc. | | TickerallBrokerError | broker-coded (e.g. BROKER_*) | broker rejection or broker connection issues | | TickerallServiceUnavailableError | network / timeout / bare 502·503 | transient — TickerAll momentarily unreachable; retry | | TickerallApiError | any | base class; check .code and .transient for specifics |

Timeouts and cancellation

await ticker.accounts.list({ timeout: 5_000 })

const controller = new AbortController()
setTimeout(() => controller.abort(), 1_000)
await ticker.accounts.list({ signal: controller.signal })

TypeScript

The SDK ships hand-written .d.ts files. All public types are exported from the root:

import type { PlaceOrderParams, Position, TickEvent } from '@tickerall/sdk'

License

MIT