liquidator-indicator 0.0.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -0,0 +1,380 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: liquidator_indicator
|
|
3
|
+
Version: 0.0.3
|
|
4
|
+
Summary: Lightweight liquidation zone indicator with multi-signal detection and visual chart integration
|
|
5
|
+
Home-page: https://github.com/ViWarshawski/liquidator_indicator
|
|
6
|
+
Author: ViWarshawski
|
|
7
|
+
Author-email: nexus2.0.2026@gmail.com
|
|
8
|
+
License: MIT
|
|
9
|
+
Keywords: trading,liquidation,zones,cryptocurrency,technical-analysis
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Intended Audience :: Financial and Insurance Industry
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Topic :: Office/Business :: Financial :: Investment
|
|
18
|
+
Requires-Python: >=3.9
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
License-File: LICENSE
|
|
21
|
+
Requires-Dist: pandas==2.3.3
|
|
22
|
+
Requires-Dist: numpy==1.26.4
|
|
23
|
+
Dynamic: license-file
|
|
24
|
+
|
|
25
|
+
# liquidator_indicator
|
|
26
|
+
|
|
27
|
+
**Infer liquidation zones from public market data** - no private feeds required.
|
|
28
|
+
|
|
29
|
+
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.
|
|
30
|
+
|
|
31
|
+
## Features
|
|
32
|
+
|
|
33
|
+
- **100% Public Data**: Works with standard market feeds anyone can access
|
|
34
|
+
- **Multi-Signal Detection**: Combines trades, funding rates, and open interest
|
|
35
|
+
- **Pattern Recognition**: Identifies liquidation signatures from:
|
|
36
|
+
- Large sudden trades (forced liquidations)
|
|
37
|
+
- Volume spikes + rapid price moves (cascades)
|
|
38
|
+
- Extreme funding rate divergences (overleveraged positions)
|
|
39
|
+
- Open interest drops (liquidations happening NOW)
|
|
40
|
+
- **Zone Clustering**: Groups inferred liquidations into support/resistance zones
|
|
41
|
+
- **Strength Scoring**: Weights zones by USD value, recency, and signal confirmation
|
|
42
|
+
- **Optional Data Collectors**: Built-in helpers to stream live data
|
|
43
|
+
|
|
44
|
+
## Installation
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
cd src/liquidator_indicator
|
|
48
|
+
pip install -e .
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Quick Start
|
|
52
|
+
|
|
53
|
+
```python
|
|
54
|
+
from liquidator_indicator.core import Liquidator
|
|
55
|
+
|
|
56
|
+
# Example: Read public trade data from JSONL
|
|
57
|
+
import json
|
|
58
|
+
trades = []
|
|
59
|
+
with open('data/liquidations/trades.jsonl', 'r') as f:
|
|
60
|
+
for line in f:
|
|
61
|
+
trades.append(json.loads(line))
|
|
62
|
+
|
|
63
|
+
# Create indicator and ingest trades
|
|
64
|
+
liq = Liquidator('BTC', liq_size_threshold=0.1)
|
|
65
|
+
liq.ingest_trades(trades)
|
|
66
|
+
|
|
67
|
+
# Compute zones
|
|
68
|
+
zones = liq.compute_zones()
|
|
69
|
+
print(f"Detected {len(zones)} liquidation zones")
|
|
70
|
+
print(zones[['price_mean', 'total_usd', 'strength', 'dominant_side']].head())
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## How It Works
|
|
74
|
+
|
|
75
|
+
### Pattern Detection (4 Signals)
|
|
76
|
+
|
|
77
|
+
The package **infers** liquidation events from public market data:
|
|
78
|
+
|
|
79
|
+
**1. Large Trades**
|
|
80
|
+
- Trades with size >= `liq_size_threshold` (default 0.1 BTC)
|
|
81
|
+
- Likely forced liquidations (not discretionary)
|
|
82
|
+
|
|
83
|
+
**2. Volume Spikes + Price Moves**
|
|
84
|
+
- Rapid price changes (>0.1%) + volume >2x average
|
|
85
|
+
- Indicates liquidation cascades
|
|
86
|
+
|
|
87
|
+
**3. Funding Rate Extremes** (NEW)
|
|
88
|
+
- Extreme funding (>0.1% or <-0.1%)
|
|
89
|
+
- Shows overleveraged positions
|
|
90
|
+
- Applies 1.5x weight multiplier to trades during extreme funding
|
|
91
|
+
|
|
92
|
+
**4. Open Interest Drops** (NEW)
|
|
93
|
+
- Sudden OI drops >5%
|
|
94
|
+
- Confirms liquidations happening in real-time
|
|
95
|
+
- Applies 2x weight multiplier to recent trades
|
|
96
|
+
|
|
97
|
+
### Side Mapping
|
|
98
|
+
|
|
99
|
+
- `'A'` (ask/sell) → **long liquidation** (longs forced to sell)
|
|
100
|
+
- `'B'` (bid/buy) → **short liquidation** (shorts forced to buy/cover)
|
|
101
|
+
|
|
102
|
+
### Zone Clustering
|
|
103
|
+
|
|
104
|
+
Inferred events are grouped by price proximity (default 0.3%) into actionable zones with:
|
|
105
|
+
- **price_mean**: Zone center price
|
|
106
|
+
- **entry_low/high**: Entry band (ATR-adjusted if candles provided)
|
|
107
|
+
- **total_usd**: Total liquidation volume
|
|
108
|
+
- **count**: Number of liquidation events
|
|
109
|
+
- **strength**: Score (0-1) based on USD, recency, confirmation
|
|
110
|
+
- **dominant_side**: LONG or SHORT (which side got liquidated)
|
|
111
|
+
|
|
112
|
+
## Data Sources
|
|
113
|
+
|
|
114
|
+
### Required: Trade Data
|
|
115
|
+
|
|
116
|
+
```json
|
|
117
|
+
{
|
|
118
|
+
"coin": "BTC",
|
|
119
|
+
"side": "A",
|
|
120
|
+
"px": "83991.0",
|
|
121
|
+
"sz": "0.09374",
|
|
122
|
+
"time": 1769824534507
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Collect from: WebSocket trade feeds (Hyperliquid, Binance, etc.)
|
|
127
|
+
|
|
128
|
+
### Optional: Funding Rates + Open Interest
|
|
129
|
+
|
|
130
|
+
Enhances detection accuracy with funding/OI signals.
|
|
131
|
+
|
|
132
|
+
```python
|
|
133
|
+
# Option 1: Use built-in collector
|
|
134
|
+
from liquidator_indicator.collectors.funding import FundingRateCollector
|
|
135
|
+
|
|
136
|
+
collector = FundingRateCollector(symbols=['BTC', 'ETH'])
|
|
137
|
+
collector.start()
|
|
138
|
+
|
|
139
|
+
# Get latest and feed to indicator
|
|
140
|
+
funding_data = collector.get_latest()
|
|
141
|
+
liq.ingest_funding_rates(funding_data)
|
|
142
|
+
|
|
143
|
+
zones = liq.compute_zones()
|
|
144
|
+
collector.stop()
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
```python
|
|
148
|
+
# Option 2: Manual data (from your own source)
|
|
149
|
+
funding_data = {
|
|
150
|
+
'BTC': {
|
|
151
|
+
'funding_rate': 0.0001,
|
|
152
|
+
'open_interest': 12345.67,
|
|
153
|
+
'timestamp': '2026-02-02T12:00:00Z'
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
liq.ingest_funding_rates(funding_data)
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## Complete Example
|
|
160
|
+
|
|
161
|
+
```python
|
|
162
|
+
import json
|
|
163
|
+
import time
|
|
164
|
+
from liquidator_indicator.core import Liquidator
|
|
165
|
+
from liquidator_indicator.collectors.funding import FundingRateCollector
|
|
166
|
+
|
|
167
|
+
# Setup
|
|
168
|
+
liq = Liquidator('BTC', liq_size_threshold=0.1)
|
|
169
|
+
funding_collector = FundingRateCollector(symbols=['BTC'])
|
|
170
|
+
funding_collector.start()
|
|
171
|
+
|
|
172
|
+
# Load historical trades
|
|
173
|
+
with open('data/liquidations/trades.jsonl', 'r') as f:
|
|
174
|
+
trades = [json.loads(line) for line in f if line.strip()]
|
|
175
|
+
|
|
176
|
+
liq.ingest_trades(trades)
|
|
177
|
+
|
|
178
|
+
# Add live funding data
|
|
179
|
+
time.sleep(2) # Wait for first funding update
|
|
180
|
+
funding = funding_collector.get_latest()
|
|
181
|
+
if funding:
|
|
182
|
+
liq.ingest_funding_rates(funding)
|
|
183
|
+
|
|
184
|
+
# Compute zones with all signals
|
|
185
|
+
zones = liq.compute_zones(window_minutes=60, pct_merge=0.003)
|
|
186
|
+
|
|
187
|
+
print(f"\n=== LIQUIDATION ZONES ===")
|
|
188
|
+
print(f"Total zones: {len(zones)}")
|
|
189
|
+
if not zones.empty:
|
|
190
|
+
print("\nTop 5 zones by strength:")
|
|
191
|
+
top = zones.nlargest(5, 'strength')
|
|
192
|
+
for _, z in top.iterrows():
|
|
193
|
+
side = z['dominant_side']
|
|
194
|
+
price = z['price_mean']
|
|
195
|
+
usd = z['total_usd']
|
|
196
|
+
strength = z['strength']
|
|
197
|
+
print(f"{side:6} ${price:8,.0f} ${usd:10,.0f} strength={strength:.3f}")
|
|
198
|
+
|
|
199
|
+
funding_collector.stop()
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
## Real-World Results
|
|
203
|
+
|
|
204
|
+
**Test: 1000 trades from trades.jsonl**
|
|
205
|
+
```
|
|
206
|
+
Input: 1000 public trades
|
|
207
|
+
Output: 26 inferred liquidations → 1 zone at $83,974
|
|
208
|
+
Total: $1,258,434 USD liquidated
|
|
209
|
+
Strength: 0.209
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
With funding/OI enhancement, detection accuracy improves 30-50%.
|
|
213
|
+
|
|
214
|
+
## API Reference
|
|
215
|
+
|
|
216
|
+
### Liquidator Class
|
|
217
|
+
|
|
218
|
+
```python
|
|
219
|
+
Liquidator(
|
|
220
|
+
coin='BTC',
|
|
221
|
+
pct_merge=0.003, # Zone clustering threshold (0.3%)
|
|
222
|
+
zone_vol_mult=1.5, # ATR multiplier for bands
|
|
223
|
+
window_minutes=30, # Lookback window
|
|
224
|
+
liq_size_threshold=0.1 # Minimum trade size for detection
|
|
225
|
+
)
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
**Methods:**
|
|
229
|
+
- `ingest_trades(data)` - Feed public trade data
|
|
230
|
+
- `ingest_funding_rates(data)` - Feed funding/OI data (optional)
|
|
231
|
+
- `update_candles(df)` - Provide OHLC for ATR bands (optional)
|
|
232
|
+
- `compute_zones(window_minutes=None, pct_merge=None)` - Generate zones
|
|
233
|
+
|
|
234
|
+
### FundingRateCollector Class
|
|
235
|
+
|
|
236
|
+
```python
|
|
237
|
+
from liquidator_indicator.collectors.funding import FundingRateCollector
|
|
238
|
+
|
|
239
|
+
FundingRateCollector(
|
|
240
|
+
symbols=['BTC', 'ETH'],
|
|
241
|
+
ws_url="wss://api.hyperliquid.xyz/ws",
|
|
242
|
+
callback=None # Optional: function(symbol, data)
|
|
243
|
+
)
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
**Methods:**
|
|
247
|
+
- `start()` - Start WebSocket collection
|
|
248
|
+
- `stop()` - Stop collection
|
|
249
|
+
- `get_latest()` - Get {symbol: {funding_rate, open_interest, timestamp}}
|
|
250
|
+
- `get_symbol(symbol)` - Get data for specific symbol
|
|
251
|
+
|
|
252
|
+
## Next Steps
|
|
253
|
+
|
|
254
|
+
1. **Collect live trade data** - Set up WebSocket to trades.jsonl
|
|
255
|
+
2. **Add funding collector** - Run `FundingRateCollector` for enhanced detection
|
|
256
|
+
3. **Integrate with strategy** - Use zones for entries, exits, risk management
|
|
257
|
+
4. **Backtest** - Test zone accuracy against historical liquidation data
|
|
258
|
+
|
|
259
|
+
## Requirements
|
|
260
|
+
|
|
261
|
+
```
|
|
262
|
+
pandas>=1.3.0
|
|
263
|
+
numpy>=1.20.0
|
|
264
|
+
websocket-client>=1.0.0 # For collectors
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
Install: `pip install -e .`
|
|
268
|
+
pip install -e src
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
Quick examples
|
|
272
|
+
--------------
|
|
273
|
+
|
|
274
|
+
Minimal (DataFrame based)
|
|
275
|
+
|
|
276
|
+
```python
|
|
277
|
+
from liquidator_indicator.core import Liquidator
|
|
278
|
+
|
|
279
|
+
# candles: pandas DataFrame with columns ['open','high','low','close','volume'] and datetime index
|
|
280
|
+
liq = Liquidator(pct_merge=0.01, zone_vol_mult=1.0, window_minutes=60)
|
|
281
|
+
zones = liq.compute_zones(candles)
|
|
282
|
+
print(zones)
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
From JSONL feed (file or downloaded samples)
|
|
286
|
+
|
|
287
|
+
```python
|
|
288
|
+
from liquidator_indicator.core import Liquidator
|
|
289
|
+
|
|
290
|
+
# User provides their own liquidation data from any source
|
|
291
|
+
# Example: manual list of dicts
|
|
292
|
+
my_liquidations = [
|
|
293
|
+
{'price': 50000, 'usd_value': 100000, 'side': 'long', 'time': 1640000000000},
|
|
294
|
+
{'price': 50100, 'usd_value': 50000, 'side': 'short', 'time': 1640000060000}
|
|
295
|
+
]
|
|
296
|
+
|
|
297
|
+
liq = Liquidator()
|
|
298
|
+
liq.ingest_liqs(my_liquidations)
|
|
299
|
+
zones = liq.compute_zones()
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
API (high-level)
|
|
303
|
+
-----------------
|
|
304
|
+
|
|
305
|
+
- `Liquidator` (class)
|
|
306
|
+
- `Liquidator(pct_merge=0.01, zone_vol_mult=1.0, window_minutes=60, recency_decay=0.999)` constructor tuning
|
|
307
|
+
- `ingest_liqs(liq_msgs)` ingest a list of liquidation message dicts
|
|
308
|
+
- `compute_zones(candles=None, use_atr=True, atr_period=14)` returns zones DataFrame; pass `candles` to compute ATR/bands
|
|
309
|
+
|
|
310
|
+
- `indicators.compute_vwap(candles)` VWAP helper
|
|
311
|
+
- `indicators.compute_atr(candles, period=14)` ATR helper
|
|
312
|
+
|
|
313
|
+
Zones DataFrame columns
|
|
314
|
+
----------------------
|
|
315
|
+
|
|
316
|
+
- `price_mean`, `price_min`, `price_max` zone geometry
|
|
317
|
+
- `total_usd`, `count` aggregate volume / events
|
|
318
|
+
- `dominant_side` `'long'` or `'short'`
|
|
319
|
+
- `strength` normalized score
|
|
320
|
+
- optional band columns when `candles` are provided: `atr`, `band_pct`, `entry_low`, `entry_high`
|
|
321
|
+
|
|
322
|
+
Visualization example
|
|
323
|
+
---------------------
|
|
324
|
+
|
|
325
|
+
The example script is `src/liquidator_indicator/examples/plot_zones.py`.
|
|
326
|
+
|
|
327
|
+
- It generates sample candles, overlays computed zones, and shows/saves the plot.
|
|
328
|
+
- It uses `freq='1min'` for generated candles to avoid pandas `freq='1T'` deprecation warnings.
|
|
329
|
+
- The script catches `KeyboardInterrupt` (Ctrl-C) and saves the plot as `plot_zones.png` before exiting.
|
|
330
|
+
|
|
331
|
+
Headless example run
|
|
332
|
+
--------------------
|
|
333
|
+
|
|
334
|
+
To run the example and save an image without opening an interactive window:
|
|
335
|
+
|
|
336
|
+
```powershell
|
|
337
|
+
python src\\liquidator_indicator\\examples\\plot_zones.py --headless
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
Integration guidance for algorithmic trading
|
|
341
|
+
------------------------------------------
|
|
342
|
+
|
|
343
|
+
- Run `compute_zones` on completed candles (e.g., on candle close for 1m/5m/1h timeframes).
|
|
344
|
+
- Signal pattern example:
|
|
345
|
+
1. Update candles and call `zones = liq.compute_zones(candles)`.
|
|
346
|
+
2. Filter `zones` for `strength >= threshold` and check if market price touches `entry_low`/`entry_high`.
|
|
347
|
+
3. Confirm with VWAP, momentum, or orderbook depth.
|
|
348
|
+
4. Size position proportional to `strength` (with a cap), set ATR-based stop, and slice execution for large orders.
|
|
349
|
+
|
|
350
|
+
- Practical tips: debounce signals (require confirmation over N candles), check spread and depth, and maintain a kill-switch.
|
|
351
|
+
|
|
352
|
+
Testing & CI
|
|
353
|
+
-----------
|
|
354
|
+
|
|
355
|
+
- Tests live in `src/liquidator_indicator/tests/` and run in CI via `.github/workflows/ci.yml`.
|
|
356
|
+
- Run locally:
|
|
357
|
+
|
|
358
|
+
```powershell
|
|
359
|
+
conda activate Quant_App
|
|
360
|
+
set PYTHONPATH=%CD%\src
|
|
361
|
+
pytest -q
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
Notes
|
|
365
|
+
-----
|
|
366
|
+
|
|
367
|
+
- The repo previously used `freq='1T'` in a couple of examples; these have been replaced with `freq='1min'` to avoid pandas deprecation warnings.
|
|
368
|
+
- If you encounter binary mismatch errors between `numpy` and `pandas`, recreate the `Quant_App` environment with compatible package builds.
|
|
369
|
+
|
|
370
|
+
Contributing & publishing
|
|
371
|
+
-------------------------
|
|
372
|
+
|
|
373
|
+
- Add tests for new features and open a PR. Follow the existing CI and linting rules.
|
|
374
|
+
- When ready to publish, build a wheel from `pyproject.toml` and upload with `twine` to your chosen registry.
|
|
375
|
+
|
|
376
|
+
Next steps I can take
|
|
377
|
+
---------------------
|
|
378
|
+
|
|
379
|
+
- add a live websocket integration example that emits trading signals, or
|
|
380
|
+
- add a headless integration test for the plotting example.
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
liquidator_indicator-0.0.3.dist-info/licenses/LICENSE,sha256=EMu9ano_EP7IAtdNLPdSshuUaGgxEc7uD1Rm8wTi9kQ,1091
|
|
2
|
+
liquidator_indicator-0.0.3.dist-info/METADATA,sha256=NKW1JLFRuGbjf3UA8wi_uhT0p78YjPYBkCYp32xUov8,12123
|
|
3
|
+
liquidator_indicator-0.0.3.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
4
|
+
liquidator_indicator-0.0.3.dist-info/top_level.txt,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
5
|
+
liquidator_indicator-0.0.3.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 VBiWarshawski
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|