Skip to main content

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 data
  • ingest_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 zones
    • min_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 collection
  • stop() - Stop collection
  • get_latest() - Get {symbol: {funding_rate, open_interest, timestamp}}
  • get_symbol(symbol) - Get data for specific symbol

Next Steps

  1. Collect live trade data - Set up WebSocket to trades.jsonl
  2. Add funding collector - Run FundingRateCollector for enhanced detection
  3. Use quality scoring (v0.0.7) - Filter zones by quality to reduce noise
  4. Try multi-timeframe analysis (v0.0.7) - Find zones that align across timeframes
  5. Integrate with strategy - Use zones for entries, exits, risk management
  6. 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 tuning
    • ingest_liqs(liq_msgs) ingest a list of liquidation message dicts
    • compute_zones(candles=None, use_atr=True, atr_period=14) returns zones DataFrame; pass candles to 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_max zone geometry
  • total_usd, count aggregate volume / events
  • dominant_side 'long' or 'short'
  • strength normalized score
  • optional band columns when candles are 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 pandas freq='1T' deprecation warnings.
  • The script catches KeyboardInterrupt (Ctrl-C) and saves the plot as plot_zones.png before 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_zones on completed candles (e.g., on candle close for 1m/5m/1h timeframes).

  • Signal pattern example:

    1. Update candles and call zones = liq.compute_zones(candles).
    2. Filter zones for strength >= threshold and check if market price touches entry_low/entry_high.
    3. Confirm with VWAP, momentum, or orderbook depth.
    4. Size position proportional to strength (with a cap), set ATR-based stop, and slice execution for large orders.
  • 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 with freq='1min' to avoid pandas deprecation warnings.
  • If you encounter binary mismatch errors between numpy and pandas, recreate the Quant_App environment 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.toml and upload with twine to 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

liquidator_indicator-0.1.2.tar.gz (102.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

liquidator_indicator-0.1.2-py3-none-any.whl (77.3 kB view details)

Uploaded Python 3

File details

Details for the file liquidator_indicator-0.1.2.tar.gz.

File metadata

  • Download URL: liquidator_indicator-0.1.2.tar.gz
  • Upload date:
  • Size: 102.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.12

File hashes

Hashes for liquidator_indicator-0.1.2.tar.gz
Algorithm Hash digest
SHA256 aedf704809b455eac44ae92ee7eb5726719e5819997bf7b289b62e4201a692fd
MD5 23f159a6e0a8cfd4ee2ee25568f5da28
BLAKE2b-256 e0f9d16a85be0efb00492d303da5003b589027d29e3920168a0d9920335c96f1

See more details on using hashes here.

File details

Details for the file liquidator_indicator-0.1.2-py3-none-any.whl.

File metadata

File hashes

Hashes for liquidator_indicator-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 03f73cb09c2aea533f3671683a5b9e00a7994a56c5c4db6ec2f06cd1666d4dbd
MD5 887e1678c3708f8d195ab11f93d8a951
BLAKE2b-256 1a45e4206e96d36e1e77fd12573d34276df7dd6880151866b0e805b7aa9780bb

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page