Historical Replay
Replay market data over the same socket with original timing or controlled speed.
Replay
Historical replay
Replay historical data with original timing preserved and adjustable playback speed.
JavaScript
// Start historical replay at 10x speed (Hyperliquid)ws.send(JSON.stringify({ op: "replay", channel: "orderbook", symbol: "BTC", start: 1681516800000, // Unix timestamp in ms end: 1681603200000, speed: 10 // 10x playback speed}));
// Start Lighter.xyz orderbook replay with granularityws.send(JSON.stringify({ op: "replay", channel: "lighter_orderbook", symbol: "BTC", start: 1706140800000, end: 1706227200000, speed: 10, granularity: "10s" // Options: checkpoint, 30s, 10s, 1s, tick}));
// Replay candles with specific intervalws.send(JSON.stringify({ op: "replay", channel: "candles", symbol: "ETH", start: 1681516800000, end: 1681603200000, speed: 10, interval: "1h" // Options: 1m, 5m, 15m, 30m, 1h, 4h, 1d, 1w}));
// Replay OI/funding dataws.send(JSON.stringify({ op: "replay", channel: "open_interest", symbol: "BTC", start: 1684540800000, end: 1684627200000, speed: 10}));
// Multi-channel synchronized replay (all channels must be same exchange)// Data is interleaved in timestamp order across channelsws.send(JSON.stringify({ op: "replay", channels: ["orderbook", "trades", "funding"], // Use "channels" (plural) for multi-channel symbol: "BTC", start: 1681516800000, end: 1681603200000, speed: 10}));
// Multi-channel Lighter replayws.send(JSON.stringify({ op: "replay", channels: ["lighter_orderbook", "lighter_trades", "lighter_funding"], symbol: "ETH", start: 1706140800000, end: 1706227200000, speed: 10, granularity: "10s" // Applies to lighter_orderbook channel}));
// Multi-channel replay sends "replay_snapshot" messages before the timeline// starts, providing initial state for each channel:// {"type": "replay_snapshot", "channel": "orderbook", "coin": "BTC", "symbol": "BTC", "timestamp": ..., "data": {...}}// {"type": "replay_snapshot", "channel": "funding", "coin": "BTC", "symbol": "BTC", "timestamp": ..., "data": {...}}// Then interleaved historical_data messages follow in timestamp order
// Pause replayws.send(JSON.stringify({ op: "replay.pause" }));
// Resume replayws.send(JSON.stringify({ op: "replay.resume" }));
// Seek to specific timestampws.send(JSON.stringify({ op: "replay.seek", timestamp: 1681550000000}));
// Stop replayws.send(JSON.stringify({ op: "replay.stop" }));Gap detection
Replay emits gap_detected whenever continuity falls below the threshold.
JavaScript
// Gap detection during replayws.onmessage = (event) => { const msg = JSON.parse(event.data);
if (msg.type === 'gap_detected') { console.log(`Gap in ${msg.channel}/${msg.symbol}:`); console.log(` From: ${new Date(msg.gap_start).toISOString()}`); console.log(` To: ${new Date(msg.gap_end).toISOString()}`); console.log(` Duration: ${msg.duration_minutes} minutes`); }
// Handle other message types... if (msg.type === 'historical_data') { // Process data }};