Skip to content

View original

BtcLiquidationCascadeMomentum

Hypotheses

BTC Liquidation Cascade Momentum

Hypotheses

A crypto-native momentum strategy on BTCUSDT futures using 1-hour bars that exploits liquidation cascades. Large liquidation events in crypto perpetual futures create forced buying/selling that mechanically pushes price further in the same direction, triggering additional liquidations in a positive feedback loop. This strategy monitors liquidation volume from supplementary data and enters in the direction of the cascade when liquidation volume spikes above a threshold, riding the forced-flow momentum. Uses only 4 parameters to keep implementation simple and avoid the frozen-signal bugs that plagued more complex strategies. The 1H timeframe on BTC ensures high trade frequency (target 150-300 trades/year) avoiding the sparse-trade overfitting problem seen in SOL Keltner. Holding period of 3-12 hours captures the cascade effect while keeping per-trade returns well above the 0.15% fee threshold.

Hypotheses

Iteration 3 fix for the Layer-2 failure '_to_ns() takes 1 positional argument but 2 were given': _to_ns was a static method, but the Layer-2 verification proxy re-binds class functions as bound instance methods, injecting self as an extra arg. Converting _to_ns to a normal instance method (def _to_ns(self, ts)) makes it correct under both the real NautilusTrader engine and the proxy. All call sites already used self._to_ns(...); the liquidation-cascade signal, entry/exit and sizing logic that already passed Layer 1 are untouched.

Hypotheses

Not worth optimizing: despite 56,830 bars spanning 2019–2026, the strategy produced only 10 trades and every return falls in a ~7-day Apr–Jun 2026 window (data_days 7, exposure 3.83%, funding_events_available 11), indicating the liquidation supplementary data covers only a recent window rather than the full history. The strategy correctly refuses to trade without its liquidation signal, so it was effectively tested on ~7 days — an uninformative sample far too small for a 3-window walk-forward, and the hypothesis's own 150–300 trades/year target (set to avoid sparse-trade overfitting) collapsed to 10 trades total. In the tiny window it did trade, the edge is strongly negative (profit_factor 0.57, expectancy -$82/trade, avg_win $276 < avg_loss $321, Sharpe -5.07, metrics_reliable=false), and commission_pct_of_gross is 44.99% — the structural fee trap for a 1H strategy with 6h holds against ~0.10% RT. The binding constraint is sparse historical liquidation data, a data-coverage problem for the data engineer, not a developer parameter iteration, and optimization cannot manufacture trades the data doesn't support. FAILURE PATTERN: identical to the abandoned ETH liquidation-cascade sibling — an event-gated liquidation strategy is only testable where liquidation history exists; when that data is recent-only, a huge bars_processed count masks a ~7-day effective sample of 10 trades, and a 1H event strategy at that cadence is fee-dominated (45% of gross) with a negative net edge. No parameter sweep creates trades the feed doesn't cover.

Implementation

BTCUSDT 1H futures liquidation-cascade momentum. Reads the liquidation supplementary feed, sums per-bar forced-buy (short-side liq) vs forced-sell (long-side liq) USD, and enters in the cascade direction when per-bar total liq USD spikes above spike_mult x its rolling baseline, exceeds an absolute floor (min_liq_usd), and one side dominates by imbalance_ratio. Exits after hold_bars or on a stop_pct adverse move. Stays flat when liquidation data is empty (no price-only fallback).

Verification Results

Verification failed (Layer 2 — synthetic scenarios): Parameters used: ['stop_pct', 'hold_bars', 'spike_mult', 'min_liq_usd', 'liq_lookback', 'min_notional', 'position_frac', 'size_precision', 'imbalance_ratio'] Check that __init__ sets all attributes from self.parameters.get(). - steady_uptrend: TypeError: BtcLiquidationCascadeMomentum._to_ns() takes 1 positional argument but 2 were given (bar timestamp: 1735691160000) - steady_downtrend: TypeError: BtcLiquidationCascadeMomentum._to_ns() takes 1 positional argument but 2 were given (bar timestamp: 1735691160000) - flat_ranging: TypeError: BtcLiquidationCascadeMomentum._to_ns() takes 1 positional argument but 2 were given (bar timestamp: 1735691160000) - volatility_spike: TypeError: BtcLiquidationCascadeMomentum._to_ns() takes 1 positional argument but 2 were given (bar timestamp: 1735691160000) - zero_volume: TypeError: BtcLiquidationCascadeMomentum._to_ns() takes 1 positional argument but 2 were given (bar timestamp: 1735691160000) - price_gap: TypeError: BtcLiquidationCascadeMomentum._to_ns() takes 1 positional argument but 2 were given (bar timestamp: 1735691160000)

Backtest Review

Clean, low-parameter (4 signal params), well-engineered event-driven design with robust timestamp-unit normalization and correct 'no price-only fallback' data hygiene

Backtest Review

Long-short on a liquid single instrument (BTC USD-M) — a sound construction if the signal data were available across history

Backtest Review

Only 10 trades over a nominal 6+ year span, all clustered in a ~7-day Apr–Jun 2026 window (data_days 7, exposure 3.83%); the liquidation supplementary data covers only a recent window (funding_events_available 11), so the hypothesis was effectively tested on ~7 days — far too small to optimize

Backtest Review

Hypothesis targeted 150–300 trades/year to avoid sparse-trade overfitting but produced 10 trades total — the exact sparse-sample problem it set out to avoid

Backtest Review

Strongly negative net edge: profit_factor 0.57, expectancy -$82/trade, avg_win $276 < avg_loss $321, Sharpe -5.07 (metrics_reliable=false)

Backtest Review

commission_pct_of_gross 44.99% — fees consume nearly half of gross, the fee trap for a 1H/6h-hold strategy at ~0.10% RT

Backtest Review

The binding limitation is liquidation-data coverage (a data-engineer concern), not a developer parameter fix

Analysis

Do NOT optimize — the strategy only produced 8 trades over 56,038 bars, ALL clustered in April-May 2026, which means the liquidation feed it depends on is empty/sparse for nearly the entire 2019-2025 backtest window. Diagnose the data path before any further work: 1. Verify the injected supplementary data: confirm the harness populates supplementary_data['liquidations'] for BTCUSDT.BINANCE across the FULL 2019-2026 window. Print/log the count and min/max timestamp of self._liq_events right after _load_liq_events() — if events only exist from ~2026, that is the problem. 2. Check the key/format contract: confirm the row schema (timestamp_ns/timestamp, side label 'SELL'/'BUY' vs 'LONG'/'SHORT', usd_value/quantity*price) matches what the collector actually stores. A key or label mismatch would silently drop most events even if data exists. 3. Check timestamp alignment: the per-bar window uses (prev_ts, cur_ts] on ts_event/ts_init — confirm liquidation timestamps are in the same nanosecond epoch as the bars so events actually fall inside bar windows. If liquidation history genuinely only exists from ~2026 (a known limitation of Binance liquidation history), this hypothesis is structurally unbacktestable over the historical period — report that and it should be abandoned or re-scoped to the available window rather than re-run. If instead it's a key/alignment bug and the data is present, fix it and re-backtest; only then is optimization meaningful.

Outcome Summary

This strategy aimed to exploit liquidation-cascade feedback on BTC 1H futures, entering in the direction of forced flow when the liquidation feed showed a dominant-side volume spike, and deliberately kept to 4 parameters with no price-only fallback to avoid frozen-signal bugs. The engineering was clean — robust timestamp-unit normalization and correct data hygiene — but the liquidation supplementary data only covered a recent window, so despite 56,830 bars over 2019-2026 the strategy could only trade a ~7-day Apr-Jun 2026 slice, producing 10 trades against a stated 150-300/year target. In that tiny sample the edge was strongly negative (profit factor 0.57, expectancy -$82/trade, Sharpe -5.07) and fees ate 44.99% of gross, so the analyst abandoned it at the pre-optimization backtest-review gate. The binding constraint was sparse historical liquidation coverage — a data-engineering problem no parameter sweep could fix — matching the failure pattern of its already-abandoned ETH liquidation-cascade sibling; it never reached optimization, risk review, or paper trading.

Outcome Summary

An event-gated strategy is only testable where its event history exists; when the liquidation feed is recent-only, a huge bars_processed count masks a tiny effective sample, and a 1H strategy with multi-hour holds is fee-trapped (~45% of gross) at ~0.10% round-trip cost.

Outcome Summary

The backtest-review gate returned an 'abandon' verdict before optimization: the liquidation supplementary data covers only a recent window (funding_events_available 11), so the correctly data-hygienic 'no price-only fallback' strategy was effectively tested on ~7 days and 10 trades — too sparse to optimize — while the net edge was strongly negative and fee-dominated.

Outcome Summary

A crypto-native momentum strategy on BTCUSDT 1H futures that reads the liquidation feed and enters long-or-short in the direction of a liquidation cascade when per-bar liquidation volume spikes above its rolling baseline and one side dominates, riding the forced flow with a time-based exit.

Outcome Summary

Although 56,830 bars spanning 2019-2026 were processed, it produced only 10 trades — all clustered in a ~7-day Apr-Jun 2026 window (data_days 7, exposure 3.83%) — with a 40% win rate, profit factor 0.57, expectancy -$82/trade, avg_win $276 below avg_loss $321, Sharpe -5.07 (metrics_reliable=false), and commissions at 44.99% of gross.
Strategy report

Backtest and paper results are hypothetical. Trading involves risk of loss.