Historical Replay

Replay market data over the same socket with original timing or controlled speed.

Mode
Replay over WebSocket
Gap handling
gap_detected events included

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 granularity
ws.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 interval
ws.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 data
ws.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 channels
ws.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 replay
ws.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 replay
ws.send(JSON.stringify({ op: "replay.pause" }));
// Resume replay
ws.send(JSON.stringify({ op: "replay.resume" }));
// Seek to specific timestamp
ws.send(JSON.stringify({
op: "replay.seek",
timestamp: 1681550000000
}));
// Stop replay
ws.send(JSON.stringify({ op: "replay.stop" }));

Gap detection

Replay emits gap_detected whenever continuity falls below the threshold.

JavaScript
// Gap detection during replay
ws.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
}
};

Keep exploring WebSocket