new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

Quant · Exchange APIs · all subjects

CCXT recipes

5 notes, read out of this brain and free to use. Each one was extracted from a source and is re-checked against its exam.

Unified vs implicit methods in CCXT — which should I use?

Unified methods (`createOrder`, `fetchBalance`, `fetchOrder`, `fetchMyTrades`) are normalized across exchanges — use them for anything portable. Implicit methods are auto-generated raw REST wrappers (`privateGetOrder`, `fapiPrivatePostListenKey`) for everything the unified API does not cover: OCO, listenKey keepalives, sub-account transfers, leverage brackets. Mixing both in one bot is normal and expected. Unified responses normalize `price`, `amount`, `filled`, `average`, `status`, `fee` — but exchange-specific data (commission asset, funding, reduceOnly flags, bracket info) lives only in the raw `info` field of the response. Caveat: normalized `status` strings lose nuance (e.g. expired-vs-canceled); when order lifecycle matters, check `info.status` too.

How do I pass exchange-specific parameters through CCXT createOrder?

`createOrder(symbol, type, side, amount, price, params)` merges `params` into the raw request — this is the escape hatch for every exchange-specific flag. Binance futures: `{ timeInForce: 'GTX', reduceOnly: true, positionSide: 'LONG', workingType: 'MARK_PRICE', stopPrice: 95000 }`. Bybit v5: `{ triggerPrice: 95000, triggerBy: 'MarkPrice', tpslMode: 'Full', orderLinkId: 'my-id-123' }`. OKX: `{ tdMode: 'isolated', clOrdId: 'x', reduceOnly: true }`. Params are passed through essentially unchecked: a typo silently becomes an ignored field, and the order succeeds WITHOUT the protection you meant to attach (the classic is a misspelled reduceOnly on a stop leg). Verify flags landed by fetching the order back and inspecting `info`, and prove behavior with minimum-size test orders.

How should I handle CCXT errors (NetworkError vs ExchangeError)?

CCXT's taxonomy maps to retry strategy. `NetworkError` subclasses (`RequestTimeout`, `ExchangeNotAvailable`, `DDoSProtection`) are transient: retry with backoff — BUT for write operations (create/cancel order) a timeout means unknown outcome, so reconcile by client order id before resubmitting, not blindly. `ExchangeError` subclasses (`BadSymbol`, `InvalidOrder`, `InsufficientFunds`, `AuthenticationError`, `BadRequest`) are deterministic: retrying changes nothing, fix the request. `RateLimitExceeded` sits between: wait per `Retry-After`, then retry. CCXT picks the subclass from exchange error codes, so catch narrowly (`except InsufficientFunds`) instead of swallowing broad exceptions. Always log `err.message` — it embeds the raw exchange code (-1021, 10006, 50011) you need for debugging.

Which CCXT options gotchas bite the most?

Top offenders: 1) `binance.options['defaultType']` defaults to `'spot'` — set `'swap'` for USD-M perps or `fetchBalance`/`fetchPositions` silently query the wrong account. 2) `enableRateLimit: true` turns on the built-in token bucket — without it, any loop will eventually eat a 429/418; set it on every instance, and remember each CCXT instance has its OWN limiter. 3) `setSandboxMode(true)` switches to testnet/demo URLs — testnet books are thin and behavior differs from prod; validate plumbing there, not strategy. 4) `loadMarkets()` caches markets in memory; long-running bots must reload periodically (delistings, changed precision) or trade on stale filters. 5) `options.adjustForTimeDifference` auto-fixes -1021 by syncing server time. 6) Per-exchange `options` like `defaultType` also affect `fetchOHLCV`/`fetchOrderBook` market resolution.

ccxt.pro watch() vs REST polling — what are the tradeoffs?

`ccxt.pro` watch methods (`watchOrderBook`, `watchTrades`, `watchOrders`, `watchBalance`) maintain a WebSocket-backed cache: far lower latency and no REST weight cost, but you inherit every WS failure mode — gaps, stale caches, silent disconnects. For order books, check the exchange-specific nonce/sequence handling and be ready to resync; for private state, still reconcile against REST periodically. Polling (`fetch*`) is slower and burns rate-limit budget but is self-healing: every call is ground truth. Practical split: watch for market data (latency-sensitive, self-correcting), watch + scheduled REST reconcile for orders/positions, pure poll for low-frequency accounting. Note `fetchOrder(id)` is not universal: some exchanges cannot fetch old/filled orders by id — fall back to `fetchClosedOrders`/`fetchOrders` and filter client-side.

Give your agent this brain