BtcForcedLiquidationOvershootReversalLS
Hypotheses
Forced-Liquidation Overshoot Reversal, Multi-Instrument Long-Short (3 Liquid BINANCE USD-M Perps BTC/ETH/SOL, 5m Bars + LIQUIDATIONS Feed — Fade Only STATISTICALLY EXTREME One-Sided Cascades Back Toward Pre-Cascade Price; Buy After Forced Long-Liquidation Flush, Short After Forced Short-Squeeze, Reversion TP + Time/ATR Stop, 3-Parameter)
Hypotheses
A LONG-SHORT, MULTI-INSTRUMENT, SINGLE-VENUE event-driven reversal on the three most liquid Binance USD-M perpetuals (BTCUSDT, ETHUSDT, SOLUSDT) on 5-minute bars. The edge is NOT price direction (which is why single-instrument OHLCV-only directional strategies keep dying overfit per L42) — it is the mechanical OVERSHOOT created by FORCED, price-insensitive liquidation flow. When a one-sided cascade of forced closes hits the tape, the exchange liquidation engine sells (or buys) at market regardless of fair value, pushing price past where willing participants would trade; that dislocation mean-reverts within minutes-to-hours as passive liquidity refills. The strategy is deliberately orthogonal to trend and uses ONLY sandbox-available supplementary data (the liquidations feed, confirmed present in the Layer-2/Layer-3 injection set alongside funding/OI), avoiding cross-venue legs (L44) and options/IV feeds (L43) that loop to abandon. Multi-instrument basket is chosen to raise trade count above the measurability floor (the single-instrument Donchian/gap variants died on ~4-47 trades) while keeping data density high — these three names have the deepest, most reliably-recorded liquidation history. Only 3 parameters to resist overfit. venue_type futures for the short leg and low fees (~0.10% RT), which cascade-overshoot moves (typically 0.8%-3%) clear comfortably.
Hypotheses
Iteration 3 addresses the Layer-4 fee_edge verdict (avg_trade_return_pct +0.055% over 141 trades, avg_loss 1.8x avg_win, trades dying at the stop) with three changes, each closing a gap between the code and the hypothesis text rather than tuning parameters. (1) The previous version never measured price displacement at all — it faded every extreme cascade, including those where nothing dislocated, which is pure fee bleed on a 141-trade/97-turnover book. The hypothesis is explicitly 'back toward pre-cascade price', so entry now requires an ALIGNED overshoot from the close anchor_bars (30 min) earlier of at least min_overshoot_atr x ATR (scale-invariant, per L5 — no absolute USD/pct constant). (2) The fixed 0.4% take-profit is replaced by tp_retrace x the measured overshoot, so the hypothesis's 0.8%-3% cascade moves get proportionally larger targets, and the entry is additionally gated on that target clearing min_tp_pct (0.35%, ~3.5x the 0.10% round trip) — a trade that cannot pay for its own round trip is not taken. This is what turns avg trade return from +0.055% toward the 0.15% floor: fewer, larger, economically-screened events instead of high-turnover noise. (3) The stop previously used LIVE ATR, which widens exactly as a cascade extends — the direct cause of avg_loss = 1.8x avg_win. It is now frozen at entry and capped at max_loss_ratio (1.0) x the take-profit, so the payoff ratio cannot invert; sizing risks 1% of equity against that frozen stop (unchanged, still capped at 50% notional per L15). Signal formula, polarity, liquidation indexing/windowing, and all Layer-1/2 structure are untouched — QA confirmed those correct, so earlier layers stay green. Instrument set: I verified in src/backtesting/supp_collector.py that load_for_subprocess/_load_supp_with_per_leg_funding load supplementary keys for the PRIMARY instrument only (only funding is fanned out per leg), and liquidation rows carry no symbol field — adding ETH/SOL legs would give them zero liquidation events and zero trades, so BTC-only is retained and this remains a Research Lead / data-engineer call, not something code can fix. One caveat, stated once as requested: this factory's liquidation-fade track record (BTC 1m -12.80, 15m -7.39, this -7.6%) suggests the raw cascade-fade edge may be absent rather than mis-specified; the overshoot+economic gating above is the strongest remaining version of the stated mechanism, and if it still shows sub-fee avg trade return the hypothesis should be abandoned rather than iterated again.
Hypotheses
Not worth 2 hours of optimization — the strategy loses money outright, it is not a tuning-distance-away edge. profit_factor 0.43, avg_trade_return_pct -0.106% (negative, below the 0.15% USD-M floor), total_return -7.8% over 134 days, Sharpe -4.49 with the entire bootstrap CI below zero (PSR 0.076). Optimization fits parameters toward a viable region; here there is none — the mechanism loses in every regime (calm/normal/stressed all negative) and every month, with an inverted payoff (avg_loss $368 > avg_win $224, win_rate 41%, tail_ratio 0.19) that the iteration-3 'frozen capped stop' fix failed to correct, because liquidation cascades continue past the fade more often than they revert. Despite the 3-name-basket hypothesis this ran single-name BTCUSDT (liquidations are collected for the primary instrument only), placing it squarely in the L55 single-name mean-reversion graveyard (0/174 survivors) — three iterations of re-tuning entry/exit thresholds have never lifted this class over fees, and the current result is not marginal but decisively negative. Code is clean (63 entries, 0 dropped), so this is an economics failure, not a bug. Failure pattern: no_edge/fee_edge single-name liquidation-fade reversion, negative expectancy (L55/L22).
Implementation
Fades statistically extreme, one-sided forced-liquidation cascades on BTCUSDT USD-M perp (5-minute bars) that have ACTUALLY dislocated price away from a pre-cascade anchor. Signal = (bar liquidation USD / rolling 99th-percentile flow) x sidedness, sign = fade direction. Entry requires the cascade to be above the rolling extremity quantile, one-sided, AND to have displaced price >= 1.5 ATR in the direction the forced flow pushed, with a reversion target (50% of the measured overshoot) that clears 0.35% — 3.5x the taker round trip. Exits at that overshoot-scaled take-profit, at an ATR stop frozen at entry and capped at 1.0x the target, or at a 3-hour time stop.
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 (forced-liquidation overshoot fade) using only sandbox-available liquidations feed — orthogonal to the dead single-name directional class
Backtest Review
Clean, well-instrumented code: pre-cascade anchor, reversion-scaled TP, frozen capped stop, economic entry gate. Not a code defect — 63 entries signaled and submitted, 0 dropped
Backtest Review
Deeply negative expectancy — this is a LOSING strategy, not a marginal one. profit_factor 0.43, avg_trade_return_pct -0.106% (negative, below the 0.15% USD-M floor), total_return -7.8% over 134 days, expectancy -$123.65/trade
Backtest Review
Sharpe -4.49 (CI [-6.96, -1.55], entirely below zero), Sortino -3.10, PSR 0.076 — no edge in any direction
Backtest Review
Payoff inverted despite the iteration-3 'frozen capped stop' fix: avg_loss $368 vs avg_win $224 (1.6x), win_rate 41%, tail_ratio 0.19, omega 0.23 — the fade keeps getting run over by cascades that continue rather than revert
Backtest Review
Loses in every regime (calm -1.16 / normal -9.52 / stressed -3.50 Sharpe) and every month (May..Aug all negative)
Backtest Review
Not the hypothesized 3-name basket — supplementary liquidations are collected for the primary instrument only, so it is a single-name BTCUSDT fade. This is the L55 single-name reversion family (0/174 survivors); the mechanism has been faded and re-tuned across three iterations without ever crossing fees
Iteration History
Verification failed (Layer 2 — synthetic scenarios):
Parameters used: ['tp_pct', 'flow_pct', 'side_min', 'atr_period', 'flow_window', 'min_notional', 'max_hold_bars', 'stop_atr_mult', 'risk_per_trade', 'flow_min_samples', 'max_notional_frac']
Check that __init__ sets all attributes from self.parameters.get().
- steady_uptrend: TypeError: BtcForcedLiquidationOvershootReversalLS._bar_ts() takes 1 positional argument but 2 were given (bar timestamp: 1735706940000)
- steady_downtrend: TypeError: BtcForcedLiquidationOvershootReversalLS._bar_ts() takes 1 positional argument but 2 were given (bar timestamp: 1735706940000)
- flat_ranging: TypeError: BtcForcedLiquidationOvershootReversalLS._bar_ts() takes 1 positional argument but 2 were given (bar timestamp: 1735706940000)
- volatility_spike: TypeError: BtcForcedLiquidationOvershootReversalLS._bar_ts() takes 1 positional argument but 2 were given (bar timestamp: 1735706940000)
- zero_volume: TypeError: BtcForcedLiquidationOvershootReversalLS._bar_ts() takes 1 positional argument but 2 were given (bar timestamp: 1735706940000)
- price_gap: TypeError: BtcForcedLiquidationOvershootReversalLS._bar_ts() takes 1 positional argument but 2 were given (bar timestamp: 1735706940000)
Iteration History
Verification failed (Layer 4 — QA review):
- EDGE IS NEGATIVE AND SUB-FEE IN THE MEASURABLE SANDBOX — decisively. total_return -7.6%, Sharpe -2.24 with CI [-3.16,-1.28] ENTIRELY below zero (probabilistic_sharpe 0.0), PF 0.59, win_rate 0.51 but avg_loss 265 ~= 1.8x avg_win 149, and avg_trade_return_pct +0.055% over 141 trades — far below the ~0.10% round trip. The hypothesized 0.8-3% overshoot reversion is not materializing (trades die at the ATR/time stop, not the 0.4% TP). NOT the L17 code-defect signature (win 0.51, PF 0.59) and polarity/exits correct, so it is a genuinely negative/absent edge, not a bug — a fee_edge outcome on a high-turnover strategy (141 trades, turnover 97) with a poor factory track record (L17: BTC 1m liq fade -12.80, 15m liq reversal -7.39). CI entirely below zero means the edge looks absent, not merely regime-weak.
- INSTRUMENT MISMATCH — hypothesis is a 3-name basket (BTC/ETH/SOL), code trades BTCUSDT only. The hypothesis chose the basket explicitly 'to raise trade count above the measurability floor'. The developer discloses the reason: liquidation rows carry no symbol field and are collected for the primary instrument only, so ETH/SOL legs get zero events. A genuine data constraint, milder than a venue/contract swap (edge/venue/direction and measurability all preserved: BTC alone = 141 trades), but still a unilateral change to the hypothesis-fixed instrument set = a Research Lead / data-engineer decision.
- Code correctness verified — clean, iteration-2 Layer-2 fix correct. Staticmethod->instance-method resolved the proxy TypeError (all 6 synthetic scenarios pass; 'frozen 0.0' warnings are correct no-liquidation behavior). Signal polarity matches hypothesis (longs flushed -> BUY the down-overshoot; shorts squeezed -> SELL). No look-ahead: per-bar liquidation flow windowed to (ts-bar_ns, ts] via searchsorted on prefix sums; rolling quantile uses only history. Entry gate, exits (TP/ATR/time), and _bars_in_trade management correct. Divisions guarded (price, thr, total); _flow_hist IS trimmed to flow_window (the 'unbounded' warning is a false positive). Capital-relative sizing capped 50%. No code action required.
Iteration History
Verification failed (Layer 4 — QA review):
- EDGE IS ABSENT — the overshoot-reversion premise is empirically falsified across three iterations, and the developer's OWN stated abandon criterion is now met. Despite iteration 3's economic gating (pre-cascade anchor + >=1.5-ATR overshoot requirement, reversion-scaled target gated to clear 3.5x the round trip, frozen/capped stop), the sandbox got WORSE: avg_trade_return_pct moved from +0.055% (iter 2) to -0.063% (iter 3) — still sub-fee and now negative. total_return -5.2%, Sharpe -1.99 with CI [-3.05,-0.46] ENTIRELY below zero (probabilistic_sharpe 0.0005), PF 0.48, win_rate 0.43, avg_loss 356 > avg_win 229. The gating cut turnover (141 -> 49) but did not create edge. NOT the L17 code-defect signature (win 0.43, PF 0.48) and polarity/exits correct — the overshoot simply does not revert far enough to pay its round trip on BTC. The developer wrote the abandon criterion into the rationale verbatim ('if it still shows sub-fee avg trade return the hypothesis should be abandoned rather than iterated again'), and it is met. Matches the factory's uniformly negative liquidation-fade record (BTC 1m -12.80, 15m -7.39, this family -7.6% then -5.2%).
- INSTRUMENT MISMATCH (unchanged, still unresolved) — hypothesis is a 3-name BTC/ETH/SOL basket, code trades BTCUSDT only. The developer re-confirmed the cause from supp_collector.py (per-leg FUNDING only; liquidation rows carry no symbol field, so ETH/SOL legs get zero events) and correctly flags it as a Research Lead / data-engineer decision. Moot given the abandon recommendation, but noting even the specified basket could not be built without per-symbol liquidation data.
- Code correctness verified — the iteration-3 fixes are implemented correctly; NOT a code-quality rejection. _overshoot_pct measures aligned dislocation from the anchor close (0 if misaligned); the entry gate correctly requires intensity>1, |sidedness|>side_min, overshoot/atr_pct >= min_overshoot_atr, AND tp_retrace*overshoot >= min_tp_pct (a genuine economic screen); tp/stop frozen at entry in position_size and used in should_exit, stop capped at tp*max_loss_ratio so payoff cannot invert. Polarity correct. No look-ahead (flow windowed to (ts-bar_ns, ts]; anchor uses a past close). Divisions guarded (anchor, price, thr, total, atr_pct, stop); _flow_hist trimmed (the 'unbounded' warning is a false positive). Layer-2 fix holds (synthetic scenarios pass). No code action required.
Backtest and paper results are hypothetical. Trading involves risk of loss.