Realtime & replay

Stream live data, aggregate ticks into bars, and replay historical data at controlled speed.

DataAdapter interface

interface DataAdapter {
  fetchHistory(symbol, timeframe, limit?): Promise<OHLCBar[]>
  subscribe(symbol, timeframe, handler): () => void
}

Built-in: BinanceAdapter (REST + WS, typed validators, auto-reconnect).

Tick aggregation

Roll raw ticks into OHLC bars per timeframe:

import { TickAggregator } from '@tradecanvas/chart'

const agg = new TickAggregator('1m')
agg.processTick({ time, price, volume })

const current = agg.getCurrentBar()         // forming bar
const closed = agg.flushClosedBars()        // bars that have rolled over

Reconnect

ReconnectManager handles exponential backoff with a cap and a final give-up.

import { ReconnectManager } from '@tradecanvas/chart'

const rm = new ReconnectManager({
  maxAttempts: 6,
  baseDelayMs: 500,
  capMs: 30_000,
})

rm.attempt(async () => connectWebsocket())

Replay mode (0.8)

Drive a historical DataSeries forward at controlled speed. Decoupled from Chart so it can power both UI replay and headless backtests.

import { ReplayController } from '@tradecanvas/chart'

const replay = new ReplayController({
  data: historicalBars,
  speed: 10,      // bars per second
  startIndex: 0,
})

// Seed the chart with everything before startIndex
chart.setData(replay.getPrefix())

// Wire each emitted bar into the chart
replay.on('bar', ({ bar }) => chart.appendBar(bar))
replay.on('finished', () => console.log('done'))

replay.start()
// replay.pause(); replay.resume(); replay.step(5); replay.seek(200); replay.setSpeed(20)

API

MethodPurpose
start()Begin emitting from current index.
pause() / resume()Pause/continue timer.
step(n)Emit N bars synchronously without the timer.
seek(index)Jump without emitting in-between bars.
setSpeed(bps)Bars per second (clamped to >= 0.01).
destroy()Clear timer + listeners.

See Analytics for using replay alongside the backtester.