The futures market is a high-risk zone: over the past years, total liquidations on centralized exchanges have exceeded $100 billion. Each liquidation is not just a lost position but a market signal. A sharp increase in long liquidations indicates panic and potential continued decline. A cascade of short liquidations can trigger a short squeeze. The problem is that each exchange provides data differently: different formats, different historical depth, different latencies. APIs can degrade under load, which is critical for algorithmic trading. Traders often face a situation where liquidations on Bybit arrive with a 2–3 second delay, while on Binance they are instant. Such inconsistency breaks the calculation of liquidation delta and leads to false signals. Without a normalized stream, you risk making decisions based on noisy data. We solved this problem: we developed collectors that connect to WebSocket and REST APIs of 5+ exchanges, normalize the stream into a single interface, and write to TimescaleDB. The result is a consistent liquidation data stream for your strategies. It should be noted that timely detection of liquidation cascades can prevent losses comparable to a year's trading budget.
According to Wikipedia, liquidation is the forced closure of a position when margin is insufficient.
Which exchanges provide real-time liquidations?
Centralized:
Binance — WebSocket endpoint wss://fstream.binance.com/ws/!forceOrder@arr streams liquidations for all futures pairs. Event format:
{
"e": "forceOrder",
"E": 1704067200000,
"o": {
"s": "BTCUSDT",
"S": "SELL", // SELL = long liquidation
"o": "LIMIT",
"f": "IOC",
"q": "0.014", // quantity
"p": "41850.00", // price
"ap": "41800.00", // average price
"X": "FILLED",
"l": "0.014",
"z": "0.014",
"T": 1704067200000
}
}Historical data — only last hour via REST (/fapi/v1/forceOrders). Full history requires continuous writing since launch.
OKX — WebSocket channel liquidation-orders, REST history 3 months (/api/v5/public/liquidation-orders). Bybit — topic liquidation.{symbol}, data via /v5/market/recent-trade. Bitmex — oldest source (data since launch). Deribit — options and BTC/ETH futures.
Decentralized:
GMX v2 — PositionLiquidated event on Arbitrum, parsing via The Graph or direct subscription. dYdX v4 — Cosmos RPC. Hyperliquid — own L1 with full history. Aave v3 and Compound v3 — lending liquidations via LiquidationCall / AbsorbCollateral. They are not perps but complement the picture.
How to normalize data from different exchanges?
A unified structure is critical. We use the interface:
interface LiquidationEvent {
exchange: string;
symbol: string;
side: 'long' | 'short';
price: number;
quantity: number;
quantity_usd: number;
timestamp: number;
raw: Record<string, unknown>;
}Example collector implementation for Binance:
import WebSocket from 'ws';
class BinanceLiquidationCollector {
private ws: WebSocket;
private reconnectDelay = 1000;
async connect(onEvent: (event: LiquidationEvent) => Promise<void>) {
this.ws = new WebSocket('wss://fstream.binance.com/ws/!forceOrder@arr');
this.ws.on('message', async (data) => {
const raw = JSON.parse(data.toString());
const event = this.normalize(raw);
await onEvent(event);
});
this.ws.on('close', () => {
setTimeout(() => {
this.reconnectDelay = Math.min(this.reconnectDelay * 2, 30000);
this.connect(onEvent);
}, this.reconnectDelay);
});
this.ws.on('open', () => {
this.reconnectDelay = 1000;
});
}
private normalize(raw: any): LiquidationEvent {
return {
exchange: 'binance',
symbol: raw.o.s,
side: raw.o.S === 'SELL' ? 'long' : 'short',
price: parseFloat(raw.o.ap),
quantity: parseFloat(raw.o.q),
quantity_usd: parseFloat(raw.o.ap) * parseFloat(raw.o.q),
timestamp: raw.E,
raw,
};
}
}Each exchange has its own implementation with normalization of side, price, quantity. Side errors are common: on Binance SELL means long liquidation, but on others it may be reversed. We verify logic on test data.
Exchange API comparison
| Exchange | WebSocket | REST history | Limitations |
|---|---|---|---|
| Binance | !forceOrder@arr |
last hour | No deep history |
| OKX | liquidation-orders |
3 months | Different field names |
| Bybit | liquidation.{symbol} |
recent-trade | Only as trades |
| Bitmex | liquidation |
since 2014 | Deprecated API |
| Deribit | liquidations.{instrument} |
full | Only BTC/ETH |
| GMX v2 | on-chain event | full history | Arbitrum RPC |
Why TimescaleDB for storing liquidations?
TimescaleDB is the #1 choice for time-series. Hypertable:
CREATE TABLE liquidations (
time TIMESTAMPTZ NOT NULL,
exchange TEXT NOT NULL,
symbol TEXT NOT NULL,
base_asset TEXT NOT NULL,
side TEXT NOT NULL,
price NUMERIC(20, 8),
quantity NUMERIC(20, 8),
quantity_usd NUMERIC(20, 2),
raw JSONB
);
SELECT create_hypertable('liquidations', 'time');
CREATE INDEX ON liquidations (base_asset, time DESC);
CREATE MATERIALIZED VIEW liquidations_1m
WITH (timescaledb.continuous) AS
SELECT
time_bucket('1 minute', time) AS bucket,
base_asset,
exchange,
SUM(CASE WHEN side = 'long' THEN quantity_usd ELSE 0 END) AS long_liq_usd,
SUM(CASE WHEN side = 'short' THEN quantity_usd ELSE 0 END) AS short_liq_usd,
COUNT(*) AS count
FROM liquidations
GROUP BY bucket, base_asset, exchange;TimescaleDB processes queries 10x faster than PostgreSQL for this type of data.
Metrics and indicators
- Cumulative liquidation volume — sum over a period. Sharp increase >3σ from moving average signals a cascade.
- Long/Short ratio of liquidations — if 80%+ one side, directional signal.
- Liquidation clusters — price levels with high liquidation concentration (support/resistance levels).
Metric comparison:
| Metric | Description | Interpretation |
|---|---|---|
| Cumulative liquidation volume | Liquidation volume over a period | >3σ from moving average → cascade |
| Long/Short ratio | Share of long vs short liquidations | >80% one side → directional signal |
| Liquidation clusters | Price levels with concentration | Support/resistance |
import pandas as pd
import numpy as np
def detect_liquidation_cascade(df: pd.DataFrame, window_minutes: int = 5, std_multiplier: float = 3.0) -> pd.Series:
rolling = df.set_index('time')['quantity_usd'].rolling(f'{window_minutes}T')
mean = rolling.mean()
std = rolling.std()
current = df.set_index('time')['quantity_usd']
return current > (mean + std_multiplier * std) More about reconnection mechanism
The collector uses exponential backoff with an initial delay of 1 second and a maximum of 30 seconds. Each disconnect doubles the delay. After successful connection, it resets. This prevents server overload and ensures a stable connection.How we build a liquidation collection system: step by step
- Requirements analysis and exchange selection.
- Development of WebSocket collectors with normalization.
- Designing the TimescaleDB schema and indexes.
- Configuring continuous aggregates for analytics.
- Integrating a Grafana dashboard.
- Load testing and monitoring.
- Documentation and training.
Investment in such a system is discussed individually — we adapt the solution to the scale of your project. Order the development of a liquidation collection system — get an engineer consultation and implementation plan.
Limitations and edge cases
Exchanges do not always provide all data: they aggregate small liquidations, introduce delays. Historical data may be revised. WebSocket message lag: under high load, latency of 1–5 seconds — exactly when data is most important. Timestamp in raw is liquidation time, not delivery time. Cross-exchange deduplication: one position may be split into multiple orders.
What is included in the work
- Collector code for 5+ exchanges (centralized + DeFi) with automatic reconnection and backoff.
- Normalization into a unified interface and writing to TimescaleDB with continuous aggregates.
- Architecture documentation and API for integration.
- Grafana dashboard with liquidation heatmap and cascade detector.
- Training your team on the system.
- Support for 1 month after launch.
Our experience and guarantees
5+ years of blockchain solution development, 30+ projects in high-load parsing of exchange data. We guarantee 99.9% uptime of the collectors' stable data stream. We will evaluate your project and offer the optimal solution — contact us for a consultation.







