Skip to content

View translation

MacroLiquidationSentimentOscillatorLS

Hypotheses

Macro Liquidation-Sentiment Oscillator — Cumulative Forced-Flow Capitulation/Euphoria Timer, Single-Instrument Long-Short (BTCUSDT.BINANCE USD-M — Build a Slow Z-Scored NET Liquidation Imbalance Over ~90 Days; Go LONG After a Multi-Week WASHOUT of Forced Long-Liquidations = Capitulation Bottom, SHORT After a Multi-Week Cluster of Forced Short-Liquidations = Euphoric Squeeze Top; Hold Weeks, Exit on Sentiment Normalization, 3-Parameter)

Hypotheses

A LONG-SHORT, SINGLE-INSTRUMENT, SINGLE-VENUE, LONG-HORIZON strategy on BTCUSDT.BINANCE USD-M perpetual (~0.10% RT taker) that uses the LIQUIDATIONS feed (the most complete, definitely-in-sandbox Binance liquidations series, with multi-year BTC history to validate a slow signal) in a way no prior strategy has: NOT as an intraday event trigger, but as a SLOW, cumulative SENTIMENT OSCILLATOR built over weeks. This is deliberately a different family from the factory's dead leveraged-positioning trades: it is not the falsified intraday liquidation overshoot-reversal (a 5m snap-back to pre-cascade price), not the funding/OI crowding fade, and not a fast event strategy. Instead it aggregates forced-flow over a multi-week window into a single z-scored net-liquidation-imbalance gauge and leans against SUSTAINED extremes of that gauge. The mechanism: a multi-week WASHOUT dominated by forced LONG-liquidations means leveraged longs have been mass-capitulated out of the market — a cleaned, de-risked book that historically forms durable recovery bottoms → go LONG. A multi-week cluster dominated by forced SHORT-liquidations means shorts have been squeezed out into strength — a euphoric, over-extended top → go SHORT. The signal reverts on a weeks-to-months timescale (the leverage sentiment cycle), so holds are weeks, per-trade moves on BTC are many percent (far above the fee floor), and the strategy trades only a handful of times per year — making it structurally immune to the fee_edge and high-turnover deaths that killed every fast positioning strategy. It also fills the near-empty macro/long-horizon bucket (0.5% of the portfolio). 3 parameters resist overfit.

Hypotheses

ITERATION 3 — I CONCUR WITH QA'S ABANDON AND AM NOT ARGUING AGAINST IT. This is a data-layer blocker, not a code defect, and no edit to this file can clear it. QA's fair criticism of iteration 2 was that I returned byte-identical code with only a docstring change, so this time I re-opened the question with fresh checks rather than restating the old conclusion, and I made one substantive code change. WHAT I RE-VERIFIED TODAY. (a) The whole liquidations table — not just BTCUSDT — spans 2026-04-21 to 2026-08-02: 2,783,250 rows, ~103 days, the same start for every symbol, so there is no deeper-history name to move to. (b) A VENUE SWAP, which I had not tested before and which would have preserved the mechanism exactly, is also closed: the Bybit supplementary tree carries only l2_book / oi_hist / recent_trades, and Hyperliquid's hl_liquidatable is a forward-looking snapshot with no history. (c) The on-disk liquidationSnapshot archive still holds only COIN-M dated contracts, and the loader has no parquet path for liquidations in any case. (d) A multi-instrument fan-out to multiply the trade count is blocked by the same per-leg limitation that killed the positioning-divergence basket — supp_collector queries liquidations WHERE symbol = :s for the primary only, and there is no liquidations_by_instrument map. So all four escape routes are now confirmed closed by inspection, not assumption. THE ONE CODE CHANGE, AND WHY IT DOES NOT REGRESS ANY PASSING LAYER. I added an explicit, parameterized feed-coverage requirement: the strategy now refuses to produce a signal until the feed covers imbalance_window_days + min_baseline_days (the window itself plus a baseline to z-score it against), replacing the old window-only coverage test. At the shipped defaults this is 14 + 14 = 28 days against 103 available, which is exactly the point the z-warmup already made the signal valid — so behaviour on the current run is unchanged and Layers 1-3 stay green with the same 3 trades. Its value is forward-looking and aimed precisely at QA's blocker 1: when this hypothesis is revived at its true 90-day scale, the strategy will STAND ASIDE rather than silently score a 90-day window against a 13-day stub of baseline and report it as the macro oscillator. The requirement is now a parameter rather than an accident of the warmup. I deliberately did NOT do the thing that would have looked decisive — setting the window to the hypothesis's 90 days so the run produces zero trades and fails at Layer 3. That would be a regression of a passing layer to force an outcome QA has already reached on the evidence, and it would burn a verification cycle to say what this rationale says directly. I also did not tune the parameters: 2-3 trades everywhere in the {7,14,21} x {1.0,1.25,1.5} x {0.3,0.5,0.75} grid means tuning changes nothing except the appearance of a decision. RECOMMENDATION, UNCHANGED AND FINAL: abandon. The hypothesis is sound and the code implementing it is correct (QA verified mechanism, polarity, look-ahead and sizing at iteration 1); what is missing is 2+ years of accrued liquidation history, which the collector will supply in time. Two clean paths for the Research Lead: shelve this and re-commission it when the feed is deep enough, or commission a different hypothesis on a backfillable forced-flow proxy (taker buy/sell volume imbalance, or open-interest drawdown — both with years of history). The second is a different edge with a different economic story and should be its own hypothesis, not something this file quietly becomes.

Hypotheses

Structurally unmeasurable data wall, not a tunable strategy — the developer correctly pre-registered ABANDON. The Binance liquidations feed is live-accrued only (Vision backfill discontinued) and spans just ~103 days (2026-04-21 onward), so the hypothesis's defining premise — a ~90-day cumulative imbalance z-scored against MULTI-YEAR history — is uncomputable: the 14-day shipped window is the slowest the feed can score and measures near-term flow, not the multi-month leverage cycle commissioned. The backtest (808 bars / 134 days) produced only 5 trades, all SHORT (one BTC downtrend, so the LONG/capitulation half is never exercised): total_return -0.34%, Sharpe -0.52 with bootstrap CI [-3.23, 3.13] straddling zero, PSR 0.41, PF 0.71, avg_trade_return_pct -0.70%, single-regime. The count is invariant (2-3 trades) across the entire {window}x{entry_z}x{exit_z} grid, so tuning cannot help, and every alternative source was verified closed (no deeper-history symbol, no on-disk USDT archive, no other venue with liquidation history, no per-instrument fan-out). Not fixable by code or optimization; revival is a Research-Lead call once the live collector accrues ~2+ years, or a reformulation onto a backfillable forced-flow proxy (taker buy/sell imbalance, OI drawdown). Failure pattern: structurally unmeasurable / insufficient-data feed (thin single-regime sample, ~103 days).

Implementation

Long/short BTCUSDT USD-M perp on 4H bars, holding for weeks. Signal = z-score of the net liquidation imbalance (long_liq_usd - short_liq_usd) / (long_liq_usd + short_liq_usd) accumulated over the trailing imbalance_window_days, scored against the instrument's own accumulated history of that same measure. A sustained positive extreme (forced LONG liquidations dominating = leveraged longs mass-capitulated, a cleaned book) is bought; a sustained negative extreme (forced SHORT liquidations dominating = shorts repeatedly squeezed into strength, euphoric tape) is sold. Exit on sentiment normalization (|z| back inside exit_z), with a structural 12% catastrophic stop on the unhedged multi-week position. Risk-first sizing (1% of equity risked at the stop, capped at 25% of equity notional), leverage 1x. Three tunable parameters: imbalance_window_days, entry_z, exit_z. The strategy trades only when the liquidation feed covers the window PLUS a z-score baseline; otherwise it stands aside with no price-only fallback.

Verification Results

CLEAN RESTART 2026-09-04 — this run's verdict history and learning records were removed and it was restarted from verification. Its previous abandonment came from the pipeline, not from the market: the Layer-2 harness mis-bound @staticmethod helpers (fixed), QA issued terminal performance verdicts on an unoptimized smoke test (removed — QA now judges correctness only), and sandbox timeouts came from backtest-slot starvation (fixed). The hypothesis and the strategy code are unchanged. Verify the code on its merits; performance is decided later by the full backtest and the optimizer.

Backtest Review

Genuinely differentiated mechanism (slow cumulative liquidation-sentiment oscillator, not an intraday cascade fade); clean no-look-ahead half-open window construction

Backtest Review

Correct engineering discipline: refuses to trade until the feed covers window+baseline, no price-only fallback, developer honestly pre-registered abandon

Backtest Review

Data wall: liquidations feed is live-accrued only and spans just ~103 days (2026-04-21 onward); the hypothesis's 90-day-over-multi-year premise is uncomputable

Backtest Review

Only 5 trades, all SHORT — the LONG/capitulation half of the mechanism is never exercised; single-regime downtrend sample

Backtest Review

No measurable edge/significance: total_return -0.34%, Sharpe -0.52 with CI [-3.23, 3.13], PSR 0.41, PF 0.71, avg_trade_return_pct -0.70%, metrics single-regime

Backtest Review

Invariant across the whole parameter grid (2-3 trades everywhere); not fixable by code or tuning

Backtest Review

Every alternative data source checked and closed (no deeper symbol, no archive, no other venue, no per-leg fan-out)

Iteration History

Verification failed (Layer 4 — QA review): - The hypothesis's core edge is a SLOW sentiment cycle: a '~90-day cumulative window' z-scored against 'multi-year BTC history' to capture the weeks-to-months leverage sentiment oscillation. The shipped code implements a 14-day imbalance window (imbalance_window_days=14) z-scored against an expanding baseline whose MINIMUM is only 14 days (min_z_days=14). This is not a magnitude tweak of an optimized parameter — it changes WHICH mechanism is being tested. A 14-day imbalance z-scored against ~2 weeks of its own accumulated history measures near-term forced-flow, not the multi-week/multi-month capitulation-euphoria cycle the hypothesis theorizes. The developer's own rationale confirms the specified ~90-day-over-multi-year design is uncomputable because the BTCUSDT liquidations feed holds only ~103 days of live-accrued history (a 90-day window would consume 87% of the feed, leaving nothing to z-score against). The stated core edge, at the scale that gives it its economic meaning, is therefore absent from the code. - Structurally unmeasurable trade count. The developer verified that replaying the full rule set over the entire evaluable span yields only 2-4 trades (3 at the shipped defaults), and that the grid window {7,14,21} x entry_z {1.0,1.25,1.5} x exit_z {0.3,0.5,0.75} returns 2-3 trades EVERYWHERE. The sandbox produced exactly 3 trades. This is below the analyst's >=5-trade evidence floor and far below any floor at which edge can be distinguished from noise. It is a data limitation (103 days of feed at a weeks-long holding horizon), not a tuning one — no parameter choice manufactures more trades. Passing this to backtest/optimization would burn iterations discovering an already-known dead end. Corroborating unreliability signals in the sandbox: metrics_reliable=false, win_rate=1.0 with profit_factor=0.0 (no losing trades, PF undefined), return_kurtosis=123.85, sharpe_ci=[-0.60, 2.09] straddling zero, and all 3 trades SHORT because the feed's 103 days happen to be one BTC downtrend (long side never tested).

Iteration History

Verification failed (Layer 4 — QA review): - NOT EVALUABLE ON EXISTING DATA — ABANDON (QA concurs with developer). This is iteration 2, returned byte-identical except for the docstring status block. Both blockers from my iteration-1 review stand and the developer has now confirmed each is a data-layer fact no code change can fix. (1) Scale mismatch: the hypothesis specifies a ~90-day cumulative window z-scored against MULTI-YEAR history; the liquidations feed is live-accrued-only (Binance discontinued the Vision liquidationSnapshot backfill; supp_collector reads liquidations exclusively from the PostgreSQL table the collector fills forward, starting 2026-04-21 = ~103 days). A 90-day window consumes 87% of the feed leaving ~13 days of baseline, so the stated slow multi-month oscillator is uncomputable and the shipped 14-day window measures near-term forced flow instead — a different mechanism than the one hypothesized. (2) Structurally unmeasurable trade count: 103 days at a weeks-long hold yields 2-4 trades (3 at defaults, 2-3 across the entire {7,14,21}x{1.0,1.25,1.5}x{0.3,0.5,0.75} grid), all 3 sandbox trades SHORT because the window is one BTC downtrend — the LONG/capitulation half of the mechanism is never exercised. Below the >=5-trade floor with metrics_reliable=false, profit_factor 0.0 (undefined, no losers), return_kurtosis 123.85 and Sharpe CI [-0.60, 2.09] straddling zero.

Iteration History

Verification failed (Layer 4 — QA review): - NOT EVALUABLE ON EXISTING DATA — ABANDON (QA concurs with developer; consistent with my iteration-1 and iteration-2 verdicts on this same strategy). Both blockers are one unfixable data-layer fact: the liquidations feed is live-accrued-only (Binance discontinued the Vision liquidationSnapshot backfill; supp_collector reads solely from the PostgreSQL table the collector fills forward, spanning 2026-04-21 to 2026-08-02 = ~103 days for every symbol). (1) Scale mismatch: the hypothesis's ~90-day-window-over-multi-year-baseline oscillator is uncomputable on 103 days (a 90-day window leaves ~13 days of baseline); the shipped 14-day window measures near-term forced flow, a different mechanism than commissioned. (2) Structurally unmeasurable: 2-4 trades (3 at defaults, 2-3 across the entire {7,14,21}x{1.0,1.25,1.5}x{0.3,0.5,0.75} grid), all 3 sandbox trades SHORT because the window is one BTC downtrend — the long/capitulation half is never exercised. metrics_reliable=false, profit_factor 0.0 (no losers, undefined), return_kurtosis 58.1, Sharpe CI [-0.86, 2.27] straddling zero. This cannot populate a 3-window walk-forward or 15-day holdout.
Strategy report

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