Lightweight liquidation zone indicator with multi-signal detection and visual chart integration
Project description
liquidator_indicator
Infer liquidation zones from public market data - no private feeds required.
Instead of relying on private liquidation event streams, this package analyzes PUBLIC MARKET DATA (trades, funding rates, open interest) to detect liquidation-like patterns and cluster them into actionable zones. Works with data anyone can collect from public exchange APIs/websockets.
Features
- 100% Public Data: Works with standard market feeds anyone can access
- Multi-Exchange Support (v0.0.7): Native parsers for 21 exchanges - works with ANY major exchange!
- Hyperliquid, Binance, Coinbase, Bybit, Kraken, OKX, HTX, Gate.io, MEXC, and more
- Automatic symbol normalization and format conversion
- REST API + WebSocket support per exchange
- Real Liquidation Data Validation (v0.0.8): Cross-validate with actual exchange liquidation feeds
- 8 Working Collectors: Binance, Bybit, OKX, BitMEX, Deribit, HTX, Phemex, MEXC
- 686 liquidations captured in 60s live test ($12.9M total value)
- Quality score boosting (up to +30%) for zones matching real liquidations
- Cross-exchange cascade detection (multiple exchanges liquidating at same price)
- Inference accuracy validation (compare inferred vs real)
- ML-Powered Predictions (v0.0.7): Machine learning for zone hold/break probability
- 10 engineered features from zone characteristics
- SQN-compatible performance metrics (win_rate, expectancy, sqn_score)
- Continuous learning from real zone outcomes
- Optional (enable_ml=False by default)
- Multi-Signal Detection: Combines trades, funding rates, and open interest
- Pattern Recognition: Identifies liquidation signatures from:
- Large sudden trades (forced liquidations)
- Volume spikes + rapid price moves (cascades)
- Extreme funding rate divergences (overleveraged positions)
- Open interest drops (liquidations happening NOW)
- Zone Clustering: Groups inferred liquidations into support/resistance zones
- Quality Scoring (v0.0.7): Automatic zone quality assessment (0-100 score, weak/medium/strong labels)
- Multi-Timeframe Analysis (v0.0.7): Detect zones across 15 timeframes with alignment scoring
- Real-Time Streaming Mode (v0.0.7): Incremental updates with event callbacks for live trading
- Interactive Visualization (v0.0.7): Plotly charts with TradingView Pine Script export
- Strength Scoring: Weights zones by USD value, recency, and signal confirmation
- Optional Data Collectors: Built-in helpers to stream live data
Installation
cd src/liquidator_indicator
pip install -e .
Quick Start
Option 1: Multi-Exchange Support (NEW v0.0.7)
from liquidator_indicator import Liquidator
# Works with ANY exchange - automatic parser selection!
# Hyperliquid (direct format)
hyperliquid_trades = [
{"coin": "BTC", "side": "A", "px": "83991.0", "sz": "1.5", "time": 1769824534507}
]
L = Liquidator.from_exchange('BTC', 'hyperliquid', raw_data=hyperliquid_trades)
# Binance (aggTrades format)
binance_trades = [
{"a": 1, "p": "80000", "q": "1.5", "T": 1672531200000, "m": False}
]
L = Liquidator.from_exchange('BTC', 'binance', raw_data=binance_trades)
# Coinbase (matches format)
coinbase_trades = [
{"time": "2024-01-01T12:00:00Z", "price": "80000", "size": "1.5", "side": "buy"}
]
L = Liquidator.from_exchange('BTC', 'coinbase', raw_data=coinbase_trades)
# Same API for all exchanges!
zones = L.compute_zones()
print(f"Detected {len(zones)} liquidation zones")
Option 2: Real Liquidation Data (NEW v0.0.8)
from liquidator_indicator import Liquidator
from liquidator_indicator.collectors import MultiExchangeLiquidationCollector
# Collect REAL liquidation events from multiple exchanges
collector = MultiExchangeLiquidationCollector(
exchanges=['binance', 'bybit', 'okx', 'bitmex', 'deribit'],
symbols=['BTC', 'ETH']
)
collector.start()
# Collect for 60 seconds (or run continuously in background)
import time
time.sleep(60)
# Get real liquidation data
real_liqs = collector.get_liquidations()
print(f"Collected {len(real_liqs)} real liquidations")
# Create indicator and validate with real data
liq = Liquidator('BTC')
liq.ingest_trades(your_trade_data) # Inferred liquidations
liq.ingest_liquidations(real_liqs) # Real liquidations for validation
# Compute zones (quality scores boosted by real data!)
zones = liq.compute_zones()
# Zones matching real liquidations get +10-30% quality boost
validated_zones = zones[zones['real_liq_count'] > 0]
print(f"{len(validated_zones)} zones validated with real liquidations")
collector.stop()
See examples/multi_exchange_liquidations.py for full demo.
Option 3: Manual Trade Ingestion
from liquidator_indicator.core import Liquidator
# Example: Read public trade data from JSONL
import json
trades = []
with open('data/liquidations/trades.jsonl', 'r') as f:
for line in f:
trades.append(json.loads(line))
# Create indicator and ingest trades
liq = Liquidator('BTC', liq_size_threshold=0.1)
liq.ingest_trades(trades)
# Compute zones
zones = liq.compute_zones()
print(f"Detected {len(zones)} liquidation zones")
print(zones[['price_mean', 'total_usd', 'strength', 'dominant_side']].head())
How It Works
Pattern Detection (4 Signals)
The package infers liquidation events from public market data:
1. Large Trades
- Trades with size >=
liq_size_threshold(default 0.1 BTC) - Likely forced liquidations (not discretionary)
2. Volume Spikes + Price Moves
- Rapid price changes (>0.1%) + volume >2x average
- Indicates liquidation cascades
3. Funding Rate Extremes (NEW)
- Extreme funding (>0.1% or <-0.1%)
- Shows overleveraged positions
- Applies 1.5x weight multiplier to trades during extreme funding
4. Open Interest Drops (NEW)
- Sudden OI drops >5%
- Confirms liquidations happening in real-time
- Applies 2x weight multiplier to recent trades
Side Mapping
'A'(ask/sell) → long liquidation (longs forced to sell)'B'(bid/buy) → short liquidation (shorts forced to buy/cover)
Zone Clustering
Inferred events are grouped by price proximity (default 0.3%) into actionable zones with:
- price_mean: Zone center price
- entry_low/high: Entry band (ATR-adjusted if candles provided)
- total_usd: Total liquidation volume
- count: Number of liquidation events
- strength: Score (0-1) based on USD, recency, confirmation
- dominant_side: LONG or SHORT (which side got liquidated)
- quality_score (v0.0.7): 0-100 quality rating based on volume, recency, density, tightness
- quality_label (v0.0.7): 'weak', 'medium', or 'strong' classification
- alignment_score (v0.0.7): Cross-timeframe alignment percentage (0-100)
Data Sources
Required: Trade Data
{
"coin": "BTC",
"side": "A",
"px": "83991.0",
"sz": "0.09374",
"time": 1769824534507
}
Collect from: WebSocket trade feeds (Hyperliquid, Binance, etc.)
Optional: Funding Rates + Open Interest
Enhances detection accuracy with funding/OI signals.
# Option 1: Use built-in collector
from liquidator_indicator.collectors.funding import FundingRateCollector
collector = FundingRateCollector(symbols=['BTC', 'ETH'])
collector.start()
# Get latest and feed to indicator
funding_data = collector.get_latest()
liq.ingest_funding_rates(funding_data)
zones = liq.compute_zones()
collector.stop()
# Option 2: Manual data (from your own source)
funding_data = {
'BTC': {
'funding_rate': 0.0001,
'open_interest': 12345.67,
'timestamp': '2026-02-02T12:00:00Z'
}
}
liq.ingest_funding_rates(funding_data)
Complete Example
import json
import time
from liquidator_indicator.core import Liquidator
from liquidator_indicator.collectors.funding import FundingRateCollector
# Setup
liq = Liquidator('BTC', liq_size_threshold=0.1)
funding_collector = FundingRateCollector(symbols=['BTC'])
funding_collector.start()
# Load historical trades
with open('data/liquidations/trades.jsonl', 'r') as f:
trades = [json.loads(line) for line in f if line.strip()]
liq.ingest_trades(trades)
# Add live funding data
time.sleep(2) # Wait for first funding update
funding = funding_collector.get_latest()
if funding:
liq.ingest_funding_rates(funding)
# Compute zones with all signals
zones = liq.compute_zones(window_minutes=60, pct_merge=0.003)
print(f"\n=== LIQUIDATION ZONES ===")
print(f"Total zones: {len(zones)}")
if not zones.empty:
print("\nTop 5 zones by strength:")
top = zones.nlargest(5, 'strength')
for _, z in top.iterrows():
side = z['dominant_side']
price = z['price_mean']
usd = z['total_usd']
strength = z['strength']
print(f"{side:6} ${price:8,.0f} ${usd:10,.0f} strength={strength:.3f}")
funding_collector.stop()
Real-World Results
Test: 1000 trades from trades.jsonl
Input: 1000 public trades
Output: 26 inferred liquidations → 1 zone at $83,974
Total: $1,258,434 USD liquidated
Strength: 0.209
With funding/OI enhancement, detection accuracy improves 30-50%.
API Reference
Liquidator Class
Liquidator(
coin='BTC',
pct_merge=0.003, # Zone clustering threshold (0.3%)
zone_vol_mult=1.5, # ATR multiplier for bands
window_minutes=30, # Lookback window
liq_size_threshold=0.1 # Minimum trade size for detection
)
Methods:
ingest_trades(data)- Feed public trade dataingest_funding_rates(data)- Feed funding/OI data (optional)update_candles(df)- Provide OHLC for ATR bands (optional)compute_zones(window_minutes=None, pct_merge=None, min_quality=None)- Generate zonesmin_quality: Filter by quality ('weak', 'medium', 'strong', or None for all)
compute_multi_timeframe_zones(timeframes=None, min_quality=None)- Multi-timeframe analysis (v0.0.7)timeframes: List of timeframes (e.g., ['5m', '1h', '4h']) or None for all 15- Supported: 1m, 3m, 5m, 15m, 30m, 1h, 2h, 4h, 6h, 8h, 12h, 1d, 3d, 1w, 1M
update_incremental(new_trades)- Add trades and update zones (streaming mode, v0.0.7)on_zone_formed(callback)- Register callback for new zone detection (v0.0.7)on_zone_updated(callback)- Register callback for zone updates (v0.0.7)on_zone_broken(callback)- Register callback for zone breaks (v0.0.7)plot(zones, candles, show, save_path, export)- Interactive visualization (v0.0.7)export='tradingview': Export zones as TradingView Pine Script
FundingRateCollector Class
from liquidator_indicator.collectors.funding import FundingRateCollector
FundingRateCollector(
symbols=['BTC', 'ETH'],
ws_url="wss://api.hyperliquid.xyz/ws",
callback=None # Optional: function(symbol, data)
)
Methods:
start()- Start WebSocket collectionstop()- Stop collectionget_latest()- Get {symbol: {funding_rate, open_interest, timestamp}}get_symbol(symbol)- Get data for specific symbol
Next Steps
- Collect live trade data - Set up WebSocket to trades.jsonl
- Add funding collector - Run
FundingRateCollectorfor enhanced detection - Use quality scoring (v0.0.7) - Filter zones by quality to reduce noise
- Try multi-timeframe analysis (v0.0.7) - Find zones that align across timeframes
- Integrate with strategy - Use zones for entries, exits, risk management
- Backtest - Test zone accuracy against historical liquidation data
v0.0.7 Quick Examples
Quality Scoring
# Get high-quality zones only
strong_zones = L.compute_zones(min_quality='strong')
print(strong_zones[['price_mean', 'quality_score', 'quality_label']])
Multi-Timeframe Analysis
# Scalping: Short timeframes
scalping = L.compute_multi_timeframe_zones(timeframes=['1m', '5m', '15m'])
# Day trading: Intraday timeframes
day_trading = L.compute_multi_timeframe_zones(timeframes=['15m', '1h', '4h'])
# Swing trading: Higher timeframes
swing = L.compute_multi_timeframe_zones(timeframes=['4h', '1d', '3d', '1w'])
# High-alignment zones (appear on multiple timeframes)
high_align = scalping[scalping['alignment_score'] >= 75]
Combined: Quality + Multi-Timeframe
# Premium zones: Strong quality + high alignment
premium = L.compute_multi_timeframe_zones(
timeframes=['1h', '4h', '1d'],
min_quality='strong'
)
premium = premium[premium['alignment_score'] >= 75]
print(f"Found {len(premium)} premium trading opportunities")
Requirements
pandas>=1.3.0
numpy>=1.20.0
websocket-client>=1.0.0 # For collectors
Install: pip install -e .
pip install -e src
Quick examples
--------------
Minimal (DataFrame based)
```python
from liquidator_indicator.core import Liquidator
# candles: pandas DataFrame with columns ['open','high','low','close','volume'] and datetime index
liq = Liquidator(pct_merge=0.01, zone_vol_mult=1.0, window_minutes=60)
zones = liq.compute_zones(candles)
print(zones)
From JSONL feed (file or downloaded samples)
from liquidator_indicator.core import Liquidator
# User provides their own liquidation data from any source
# Example: manual list of dicts
my_liquidations = [
{'price': 50000, 'usd_value': 100000, 'side': 'long', 'time': 1640000000000},
{'price': 50100, 'usd_value': 50000, 'side': 'short', 'time': 1640000060000}
]
liq = Liquidator()
liq.ingest_liqs(my_liquidations)
zones = liq.compute_zones()
API (high-level)
-
Liquidator(class)Liquidator(pct_merge=0.01, zone_vol_mult=1.0, window_minutes=60, recency_decay=0.999)constructor tuningingest_liqs(liq_msgs)ingest a list of liquidation message dictscompute_zones(candles=None, use_atr=True, atr_period=14)returns zones DataFrame; passcandlesto compute ATR/bands
-
indicators.compute_vwap(candles)VWAP helper -
indicators.compute_atr(candles, period=14)ATR helper
Zones DataFrame columns
price_mean,price_min,price_maxzone geometrytotal_usd,countaggregate volume / eventsdominant_side'long'or'short'strengthnormalized score- optional band columns when
candlesare provided:atr,band_pct,entry_low,entry_high
Visualization example
The example script is src/liquidator_indicator/examples/plot_zones.py.
- It generates sample candles, overlays computed zones, and shows/saves the plot.
- It uses
freq='1min'for generated candles to avoid pandasfreq='1T'deprecation warnings. - The script catches
KeyboardInterrupt(Ctrl-C) and saves the plot asplot_zones.pngbefore exiting.
Headless example run
To run the example and save an image without opening an interactive window:
python src\\liquidator_indicator\\examples\\plot_zones.py --headless
Integration guidance for algorithmic trading
-
Run
compute_zoneson completed candles (e.g., on candle close for 1m/5m/1h timeframes). -
Signal pattern example:
- Update candles and call
zones = liq.compute_zones(candles). - Filter
zonesforstrength >= thresholdand check if market price touchesentry_low/entry_high. - Confirm with VWAP, momentum, or orderbook depth.
- Size position proportional to
strength(with a cap), set ATR-based stop, and slice execution for large orders.
- Update candles and call
-
Practical tips: debounce signals (require confirmation over N candles), check spread and depth, and maintain a kill-switch.
Testing & CI
- Tests live in
src/liquidator_indicator/tests/and run in CI via.github/workflows/ci.yml. - Run locally:
conda activate Quant_App
set PYTHONPATH=%CD%\src
pytest -q
Notes
- The repo previously used
freq='1T'in a couple of examples; these have been replaced withfreq='1min'to avoid pandas deprecation warnings. - If you encounter binary mismatch errors between
numpyandpandas, recreate theQuant_Appenvironment with compatible package builds.
Contributing & publishing
- Add tests for new features and open a PR. Follow the existing CI and linting rules.
- When ready to publish, build a wheel from
pyproject.tomland upload withtwineto your chosen registry.
Contributors
Special thanks to @arosstale for future project ideas and production verification testing. See CONTRIBUTORS.md for full details.
Next steps I can take
- add a live websocket integration example that emits trading signals, or
- add a headless integration test for the plotting example.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file liquidator_indicator-0.1.1.tar.gz.
File metadata
- Download URL: liquidator_indicator-0.1.1.tar.gz
- Upload date:
- Size: 102.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4eccc6c2d9142126b1dc0677e4e76bd0567ccc6e3b054b4fa9a6412266b9a2f9
|
|
| MD5 |
20e286436fbf4478954dcb7a01069386
|
|
| BLAKE2b-256 |
82b12472c0c508de9c1f827a565bb3eb7724098c415ef88c1b53e6c0def93b93
|
File details
Details for the file liquidator_indicator-0.1.1-py3-none-any.whl.
File metadata
- Download URL: liquidator_indicator-0.1.1-py3-none-any.whl
- Upload date:
- Size: 77.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0a0011f93717976d5dcdc96387d088d5afd644b4f469ccf04173a726de448b80
|
|
| MD5 |
1abd03ad5fb7f71eaa2f060df844d3f2
|
|
| BLAKE2b-256 |
bc952f5623c825b28977fc60e81fd3dc1bf5563f7039ebb2e1e45a333f1fa80c
|