Pre-Trade Liquidation Risk Check in Python
Your liquidation price is a number you can compute exactly. What that number means depends on something you cannot compute: how much forced flow lives between it and the current price. This playbook computes the first, pulls the second from a public endpoint, and puts them side by side before you open the position.
The problem: an exact number with an unclear meaning
Liquidation happens when the equity backing a position falls to the maintenance margin requirement. That is a closed-form calculation and any calculator will give you the level in a second. What the level does not tell you is how the market behaves on the way there.
The reason it matters is that liquidation levels are not evenly spread. Entry prices cluster, because traders enter on the same breakouts and the same supports. Leverage clusters harder still, because exchange interfaces ship preset buttons and far more positions open at exactly 10×, 20× or 25× than at 13×. Multiply a clustered entry distribution by a clustered leverage distribution and liquidation levels pile up in narrow bands. When price reaches a band, every position in it is force-closed in the same direction at the same instant, each close pushing price further toward the next band.
So the useful pre-trade question is not just “where is my liquidation price” but “how much forced flow sits between here and there, and is my level inside a zone that has already been proving dense today?” The first half is arithmetic. The second half needs data.
Prerequisites
- Python 3.8+
pip install requests- No API key needed — the liquidation heatmap endpoint is public.
- The maintenance margin rate (MMR) your venue publishes for your notional tier. It is in the contract specifications and it is tiered, so a larger position often carries a higher rate.
Step 1: compute the liquidation level
For an isolated-margin position, ignoring fees and accrued funding:
The 1/L term is the whole story: the distance from entry to
liquidation is approximately the inverse of leverage, before the maintenance buffer. Fees and funding
debits are taken out of margin over time, which drags the level slightly closer to you the longer you
hold — it is not a static number on a multi-day position. If you want to check a single position
by hand rather than in code, the
liquidation calculator
takes the same three inputs, and the
companion guide on liquidation price versus cascade risk
covers the mark-price and cross-margin cases the simplified formula skips.
Step 2: pull real executed liquidations
One GET returns a price × time matrix of forced-liquidation events with pre-computed price-level clusters, aggregated from live WebSocket streams on Binance, OKX, Bybit, Bitget and BitMEX:
| Field | Type | Notes |
|---|---|---|
| clusters | array | Price levels ranked by liquidated notional, with dominant_side |
| totals.count | int | Number of executed events in the window — check before concluding anything |
| by_side | object | Long vs short notional force-closed |
| price_min / price_max | float | Range the window actually covered |
| exchanges | object | Event count per venue, so you can see the mix |
These are executed forced-liquidation events, not modelled “liquidation levels”. That distinction matters and it is covered in full below.
The full script
Expected output
Run against a live four-hour BTC window, the script prints something like this (figures from an actual response captured on 24 August 2026 — a historical observation, not a forecast, and yours will differ):
Three things in that output are worth reading carefully. The window covered $42.8m of executed liquidations across 2,539 events, and they were not spread evenly — in that response the densest single price level carried about $4.78m against a median level of roughly $1.23m, so one level held close to four times the typical one. Shorts were force-bought about $27.3m against $15.6m of longs force-sold, so the pressure in that window ran against shorts. And the 20× liquidation level landed below the bottom of the observed range, which is exactly the case the script refuses to interpret: no events there does not mean it is safe ground, it means this window contains no information about it.
The contrast with a higher leverage on the identical data is the point of running this before you choose a preset. At 50× the same entry gives a level of 78,307.50, only 1.50% away, which lands inside the observed range with about $2.29m of executed liquidations having cleared within half a percent of it — and the script switches to the other branch and says so. Same market, same entry, one button.
What this data cannot tell you
This is the section that decides whether the script is useful or harmful, so it is worth more than a footnote.
- It is backward-looking. Executed liquidations tell you where positions were closed, not where the remaining ones sit. Products that draw forward-looking “liquidation levels” are estimating an unobservable distribution from assumed leverage, and the assumption is doing most of the work.
- Absence of events is not evidence of safety. A price level with no liquidations might be thin ground nobody has visited yet. The script prints that case explicitly rather than scoring it.
- It is not a directional signal. The same publisher runs a descriptive event study of what price does after large liquidation bins and labels it, in the API response itself, as conditional statistics and explicitly not a directional signal. That is the right posture and it is the one to adopt here. We have also run pre-registered studies on whether this family of data forecasts direction and published them including the ones that found no durable edge.
- Your fill is not your liquidation price. The risk engine submits a forced market order at your level; what you receive is whatever the book offers afterwards, and inside a fast cascade that gap widens as depth is consumed.
The legitimate use is narrow and worth stating in one sentence: it tells you whether the level you are about to accept sits in ground that has recently been dense with forced flow, which is a reason to widen the buffer or cut leverage — never a reason to enter.
What to build next
- Run the same check across the leverage ladder before choosing one. Feeding 5×, 10×,
20× and 50× through
liquidation_price()and printing each against the cluster distribution makes the cost of a preset button concrete; the leverage calculator does the same comparison interactively. - Size the position first and check the level second — a smaller position at the same leverage has the same liquidation price, so a haircut does not widen the buffer. The crowding-based sizing playbook covers that half.
- Subtract accrued funding from margin over your intended holding period and recompute, since the level drifts toward you the whole time you hold.
- Compare a 30-minute window against a full 24-hour one (
window_minutesis clamped to 5–1440) to separate a single flush from a session-long pattern. - Render the matrix rather than the clusters, covered in the liquidation heatmap playbook.
See the full API documentation for the rest of the response schema, or browse the code playbooks hub for more integration examples.
Same call, every tracked symbol
This endpoint is public and works for any tracked symbol. A free key raises your daily call cap and opens the rest of the data modules — derivatives, on-chain and whale flow — from the same base URL.
Create a free account