AI Guide Map
Candle-Close Pipeline with Bybit APIs & WebSockets
A direct implementation guide for Bybit candle systems that need REST API kline backfill, kline WebSocket subscription acknowledgement, live buffering, deterministic replay, confirm=true candle-close execution, reconnect resync, and clean shutdown.
Perfect for indicator driven systems that need a cache of candles, with a trigger on candle close.
Default Scope
- Runtime: Node.js LTS
- Recommended language: TypeScript
- Package: bybit-api
- Product: Bybit Spot
- Starter sample: BTCUSDT spot 1m with explicit symbol, category, and interval config
- Example use case: Converting a PineScript strategy or indicator that relies on candle closes into a realtime system with live data and historical backfill.
- Credentials: public endpoints only
Resources
Start with the task-specific resources below, then use SDK and exchange docs to verify exact method names, request fields, topics, and product rules.
Historical Backfill with Live WebSocket Streams
Historical Backfill with Live WebSocket Streams recipe
Historical Backfill with Live WebSocket Streams Conformance Pack
Bybit JavaScript SDK guide
Machine-readable recipe
Markdown snapshot
Task-focused LLM index
AI prompt generator
SDK catalog
Agent skill
Bybit SDK repository
Siebly Bybit examples
Bybit public kline WebSocket docs
Bybit historical kline docs
Implementation Steps
Follow these in order; use the linked artifacts only where they clarify the current step.
1. Verify Bybit API surfaces first
Before writing code, inspect the current bybit-api docs, examples, types, and package source for the exact REST API client, WebSocket client, public kline topic shape, subscription acknowledgement payload, kline event type, reconnect events, and shutdown method.
- Expected surfaces to verify include RestClientV5, WebsocketClient, getKline(...), subscribeV5('kline.1.BTCUSDT', 'spot'), WSKlineV5.confirm, response, reconnect, reconnected, and closeAll(true).
- Do not copy private examples for public-only market-data work.
2. Subscribe and wait for acknowledgement
Create WebsocketClient without credentials, subscribe to the public topic with subscribeV5('kline.1.BTCUSDT', 'spot'), and wait for a response event where op is subscribe, success is true, and req_id identifies the kline topic.
- Treat socket open, subscription request sent, subscription acknowledgement, and workflow readiness as different states.
- Do not start dependent workflow logic from subscribe() return value or socket open alone.
3. Backfill with the public REST API
Use RestClientV5 without API keys and call getKline({ category: 'spot', symbol: 'BTCUSDT', interval: '1', limit: 200 }) or the current documented equivalent for the selected category, symbol, interval, and history depth.
- Normalize Bybit REST API tuples into one internal candle shape with symbol, category, interval, start time, end time, OHLCV, and finalization state.
- Keep the store keyed by category, symbol, interval, and candle start time.
4. Buffer live events during backfill
After subscription acknowledgement, buffer incoming kline updates while REST API backfill runs. Store raw events or normalized events with receive timestamps, but do not run strategy, indicator, signal generation, optional external alert, order-intent, or account-decision workflows yet.
- Open candles may update local state, but cannot trigger strategy, indicator, signal generation, optional external alert, order-intent, or account-decision workflows.
- Malformed, unexpected, stale, or duplicate events should be logged and skipped conservatively.
5. Replay, then enable live processing
When REST API backfill completes, replay buffered events in deterministic order, skip stale or duplicate records, update the in-memory store, and only then mark the pipeline live-ready.
- The system is not live-ready until subscription acknowledgement, REST API backfill, buffered replay, and readiness enablement are complete.
- Replay must not run the same candle-close workflow twice.
6. Run workflows only on confirm=true
For Bybit klines, treat the kline confirm field as the candle-close boundary. Only run strategy, indicator, signal generation, optional external alert, order-intent, or account-decision workflows when WSKlineV5.confirm is true.
- Do not infer candle finality from local timers.
- Persist or record enough normalized state to test duplicate and out-of-order final candles.
7. Resync after reconnect
A WebSocket reconnect restores transport, not application correctness. On reconnect, mark workflows not ready, await subscription acknowledgement again if needed, run REST API resync, replay buffered events, and re-enable candle-close processing only after reconciliation.
- Log reconnecting, reconnected, resync started, resync completed, and live-ready transitions.
- Reconnects must not create duplicate candles or duplicate workflow executions.
8. Shut down cleanly
Handle process signals and close Bybit WebSocket connections before exit. For bybit-api, verify and use closeAll(true) or the current documented shutdown method.
- Document the public-only boundary and the no-live-orders guarantee in README/setup notes.
- Keep storage behind a small interface so the first in-memory store can later become SQLite, Postgres, Redis, or event-log backed storage.
9. Prove lifecycle behavior
Keep the implementation public-data-only, but validate the full Bybit kline lifecycle before treating it as ready.
- Candle lifecycle validation must cover subscription acknowledgement, REST backfill, buffered replay, duplicate/stale/out-of-order candles, open-candle no-op, final-candle once-only execution, malformed or wrong-symbol events, reconnect resync, public-only boundaries, and sample-symbol/config handling.
- Do not copy BTCUSDT, spot, or 1 minute into runtime defaults; symbol, category, and interval stay explicit config.
- Do not mark the pipeline complete until three consecutive full data-lifecycle review passes produce no code, tests, fixtures, or documentation changes.
Readiness gates
| State | Source | Required before workflow |
|---|---|---|
| Transport open | open event | No |
| Subscription request sent | subscribeV5('kline.1.BTCUSDT', 'spot') | No |
| Exchange acknowledgement | response event with op=subscribe, success=true, req_id topic | Yes |
| REST API backfill complete | RestClientV5.getKline(...) result normalized into store | Yes |
| Buffered replay complete | local replay of buffered kline events | Yes |
| Live processing enabled | local readiness flag after reconciliation | Yes |
Pipeline invariants
- Correctness-sensitive workflows cannot run until the selected subscription acknowledgement, backfill, buffered replay, and live-processing gates are complete.
- No strategy, indicator, signal generation, optional external alert, order-intent, or account-decision workflows can run from a kline update unless confirm is true.
- Reconnect handling must pause workflow readiness until REST API resync/reconciliation completes.
- The code must run without API keys and must not include private clients, account reads, or order endpoints.
- Every data-lifecycle claim in README or code comments needs a fixture or replay case. Behaviors without fixtures should be documented as unsupported or unverified.