MarketTrace
M1PositioningM2FootprintM3LiquidationsM4FundingM5Volume ProfileM6Book Depth
Methodology · v1.1.0 · updated 2026-09-02

Cross-exchange liquidations

How the liquidations tape is sourced, normalised, sized and read: WS feeds, schema, side semantics, adaptive bucketing, cluster detection, freshness rules.

See the live widget at /perpetuals/liquidations.

Data sources

Three exchange WebSocket feeds, one normalised Redis stream per asset. Every executed liquidation print lands in the tape — we do not estimate liquidation pressure from open interest, do not infer stop zones, do not synthesise prints.

A single Rust binary mt-liqd — all seven assets across the three liquidation venues in one process — writes events into a per-asset Redis Streamprod:liq:<asset>:events capped at MAXLEN ≈ 10 000 (≈ 4 hours of cascade-heavy tape, often the full 24 h on quiet days). The backend reads from one stream per asset for both REST and WebSocket surfaces; there is no separate pubsub channel — the stream itself is the broadcast surface.

Event schema

Per-event fields are identical across the three sources. The two timestamps are deliberately kept distinct:

Side semantics

Liquidation streams encode the side from the perspective of the exchange's closing order, which is the opposite of the trader's position. We normalise to the position that lost:

One venue-specific note: Bybit's allLiquidation.S is the position side, not the closing-order side — so S: "Buy"means a long was liquidated, the inverse of Binance's forceOrder convention. mt-liqd maps it accordingly.

Tape colour follows this: red dot = long blew up (price dropped); green dot = short blew up (price rose).

Size scaling

Each dot's radius in viewBox-px is clamp(√(usd / $10 000) × 2, 4, 22). The sqrt damps linear-by-area scaling so a $1 M event reads as ~3.16× a $100 K event — not 10× — and a single cascade print can't blot out everything around it. The lower clamp keeps a readable hit zone on sub-$10 K dust; the upper clamp keeps the biggest cascade from overflowing the panel.

r = clamp(sqrt(usd / 10_000) * 2, 4, 22)   // viewBox-px

# Reference values (vs the size legend)
$10 K   → r ≈ 4
$100 K  → r ≈ 6.3
$1 M    → r = 20
$10 M+  → r = 22 (clamped)

Adaptive rendering

Raw scatter only scales to the ~15-minute regime. Past that, hundreds of small prints in a single second smear into a uniform glow, and cascade structure disappears. We switch render modes by window:

Hit-testing, top-N annotations and tooltips run against the rendered (bucketed) events; cluster detection, cumulative pane and rate sub-pane scan raw events since those signals are about per-event density and side flow, not hover targets.

Cluster detection

Price-cluster bands are detected on the raw events of the active window:

reference_price = current mid (latest event price)
bin_width       = reference_price * 0.001    // 0.1 %
bin events by round((price - reference) / bin_width)

for each bin:
  if Σ usd ≥ 15 % of window total AND distinct events ≥ 3:
    flag as cluster
    cluster_price = volume-weighted mean of bin's prices

keep top 3 clusters by Σ usd

Each cluster gets a dashed horizontal line + badge $X cluster · N× @ price. The volume-weighted mean (rather than the nominal bin midpoint) keeps the line sitting at the depth where the dollars actually concentrated.

Cascade alert threshold

A separate daemon, mt-cascade, reads the same streams and posts an alert when a window clears the bar. Every 30 s it re-reads the trailing 5-minute window per asset; a cascade fires when the window total reaches the threshold AND at least two venues contributed. The threshold is the trailing p99 of non-empty clock-aligned 5-minute liquidation buckets over a 7-day lookback, recomputed every 5 minutes and floored at $50 M; until 100 such buckets exist a $50 M default holds instead. On a detection the daemon waits 90 s and re-reads the window before posting, so the published figure is the settled peak rather than the first trigger, and that asset then stays quiet for 30 minutes. The floor went from $1 M to $50 M on 2026-08-18: an adaptive p99 tracking the prevailing regime is the point, but a quiet week had dragged the effective BTC bar down to roughly $2 M and ordinary flow was posting as a cascade.

fire when  Σ usd over the trailing 300 s ≥ max(p99(5-min buckets, 7 d), $50M)
      and  distinct venues ≥ 2
      and  no alert for this asset in the last 1800 s

Top-N inline annotations

Up to three of the largest dots in the window get an inline $amount · time · venue|N× label so the eye lands on the biggest cascade immediately. The $50 K floor avoids labelling dust. Label anchors flip based on which half of the plot the dot is in, so the text never spills past the right axis or under the left edge.

Liquidation rate sub-pane

Under the cumulative pane, a mirrored bar chart shows Σ usdper time bucket split by side: shorts extend UP from the baseline (green), longs DOWN (red). Bucket size follows the scatter's adaptive thresholds (30 s at ≤ 15 m, 1 min at 1–4 h, 5 min at 24 h) so the columns visually align with the dots above.

Feed health

A per-(asset, exchange) status hash prod:liq:status:<asset>:<exchange> is refreshed every 5 s with a 60 s TTL. The backend converts that into three states:

The latency p50 / p99 numbers in the health tooltip are sampled from the mt-liqd binary's rolling 200-event ring buffer of producer_ts_ms − ts_ms.

Empty-time bands

Contiguous spans of the window with no liquidations at all get a subtle background tint. Without this, a 24 h view with 6 h of local data reads as a broken renderer rather than as “there were no cascades in that stretch”. The threshold is gap ≥ 5 % of window — short enough to flag a quiet 30 m on a 24 h view, long enough to avoid striping the chart with micro-bands during quiet seconds.

Caching

Limitations

Versioning

Methodology version v1.1.0 · updated 2026-09-02. v1.1.0 on 2026-09-02: USD notionals relabelled as estimates built on each venue's source reference price (2026-08-04), and the cascade-alert threshold documented, with its floor raised to $50 M (2026-08-18). Material changes (new venues, formula tweaks, threshold changes) bump the version and update dateModified in the structured data above.