Skip to content

View translation

LinkTrappedLeverageExhaustionReversalLS

Hypotheses

Trapped-Leverage Exhaustion Reversal, Single-Venue Long-Short (Single-Instrument LINKUSDT.BINANCE USD-M — Fade the Crowded Side When OPEN INTEREST Rises Sharply AND FUNDING Hits a Crowding EXTREME BUT Price Fails to Make Progress = New Leverage Piling In With No Follow-Through, So It Is Trapped and Primed to Unwind; Two Non-Price Feeds + a Price-NON-Progress Filter, ATR Stop, 3-Parameter)

Hypotheses

A LONG-SHORT, SINGLE-INSTRUMENT, SINGLE-VENUE strategy on LINKUSDT.BINANCE USD-M perpetual. It combines TWO orthogonal, sandbox-reliable feeds — open-interest change and funding rate — with a price-NON-PROGRESS filter to detect TRAPPED LEVERAGE. Mechanism: when open interest rises sharply (new leveraged positions are being opened) AND funding is simultaneously at a one-sided crowding extreme (that new leverage is lopsided — longs paying dearly, or shorts paying dearly) BUT price has NOT advanced in the direction the crowd is positioned (no follow-through despite the leverage inflow), the crowded cohort is TRAPPED: they have committed leverage and are bleeding funding with nothing to show for it, which forces an unwind that pushes price AGAINST them. The strategy fades the crowd: OI-up + extreme-POSITIVE-funding + price-flat/failing → SHORT (trapped longs unwind down); OI-up + extreme-NEGATIVE-funding + price-flat/failing → LONG (trapped shorts unwind up). This is materially different from every in-flight idea: unlike the funding+PRICE-OVEREXTENSION reversal it requires price NON-progress (the OPPOSITE price condition — leverage without a move, not leverage after a big move); unlike the OI+price-breakout it has no breakout trigger; unlike the OI+taker CONTINUATION it is a reversal that fades crowding rather than riding flow; unlike the taker-exhaustion fade it uses funding+OI, not taker prints. The two crowding feeds (funding = cost of crowding, OI = size of crowding) cross-confirm the same imbalance from independent angles, and price enters only as a non-directional 'no-progress' gate — so the signal is not a re-derivation of trend (satisfies L42). Single-venue, single-instrument — no cross-venue leg problem (L44), no options feed (L43). LINKUSDT chosen for liquid, high-volatility perp with active funding/OI (unwinds are sharp, clearing the 0.10% USD-M round trip) and to diversify away from BTC/ETH/SOL/DOGE/AVAX already in flight. 3 parameters. Instruments: ["LINKUSDT.BINANCE"]. venue_type: futures. data_requirements: ["ohlcv", "open_interest", "funding_rate"].

Hypotheses

ITERATION 3 — single root-cause fix, no logic or threshold changes. Feedback was Layer 3 'No trades produced: should_enter() returned a side 0 times over 2113 evaluated bars', so Layers 1 and 2 already passed and I changed nothing that affects them (imports, class structure, signal scaffolding, entry/exit/sizing logic and every threshold are byte-identical to previous_code apart from the block below). Rather than blindly loosening thresholds, I diagnosed the cause. (1) I replayed the EXACT entry gates offline against the real LINKUSDT 4-HOUR catalog bars and the real funding/OI parquet mirrors over the same 365-day sandbox window: 2191 bars, 2124 evaluated (matching the sandbox's 2179/2113 almost exactly), and the gates fire 36 entries — data_ok on 1643 bars, OI gate 628, non-progress gate 383, final funding-extreme gate 36. So the thresholds are NOT too tight; loosening them would have been the wrong fix and would have degraded the hypothesis. (2) The real defect was a data-plumbing bug in _build_series. The `funding_rates` supp value is a dual-key dict carrying each point under both an int and a str key, and my parser did `if isinstance(k, str): continue` to de-duplicate. That is correct in-process, but the Layer-3 sandbox passes the supp blob to its backtest subprocess as `supplementary_data=merged_supp` (pipeline_processor.py:1726) and the subprocess input is written with `json.dump` (subprocess_runner.py:143) — JSON has only string keys, so in the sandbox EVERY funding key arrives as a str and the int-only filter dropped the entire series. With funding empty, _fund_at returns NaN on every bar, calculate_signal returns 0.0 before ever setting _data_ok, and should_enter returns None on all 2113 bars: precisely the reported symptom. Note the full-backtest stage uses the supp_spec path (supplementary_data=None, subprocess loads it itself) where keys stay int, which is why this only bit at Layer 3. The fix is to parse BOTH key forms through the existing _to_ns (which does int(ts) and therefore accepts '1753920000000000000' as readily as the int) and let the dict de-duplicate on the normalised nanosecond stamp — three lines, plus a docstring note. I verified it directly: after a json.dumps/json.loads round trip of a dual-key funding dict, the old parser recovers 0 points and the new parser recovers all 3. Everything else — the OI/metrics list parsing (row keys are already strings, so JSON-safe), the funding staleness tolerance (12h >= the 8h publication interval), the no-lookahead at-or-before lookups, the one-time numpy series build with O(log n) per-bar search, the flat-on-missing-data rule with no price-only fallback, the double-capped sizing, and the leverage read off self.config.leverage — is unchanged and still passing.

Hypotheses

Decisive net loser with no edge and too few trades to optimize. profit_factor 0.62 (<1.0), total_return -12.6%, Sharpe -0.326 (CI [-0.94, 0.34], probabilistic_sharpe 0.157), and avg_trade_return_pct -0.522% (NEGATIVE) with expectancy -$189/trade. Win rate 44% with avg_loss ($893) exceeding avg_win ($710), and negative in 4 of 5 years (2022 -2.5%, 2023 -3.0%, 2024 -6.9%, 2025 -3.7%). Only 66 trades over ~4.5 years — the OI-expansion + extreme-funding + price-non-progress triple-gate fires too rarely for optimization to fit anything but noise. The hypothesis — that this confluence identifies trapped leverage primed to unwind against the crowd — is falsified: the fade loses in nearly every year. This is the fade/reversal family, repeatedly dead here (several funding/OI-based fade and reversion candidates abandoned this session for the same negative-edge reason). A negative avg_trade_return_pct (not merely sub-floor) means the signal is wrong-signed, so reducing frequency or retuning thresholds cannot help — there is no parameter region to tune toward, and the sparse sample makes optimization meaningless. Per L8 (never advance when total_return ≤ 0 or PF < 1.0), abandon at BACKTEST_REVIEW rather than spend 2 hours optimizing.

Implementation

Long/short mean-reversion on LINKUSDT.BINANCE USD-M perpetual (4-HOUR bars, 2x leverage) that fades trapped leverage. Every bar it computes funding_z (z-score of the funding rate over `lookback` bars) and returns -funding_z as the continuous signal, so the sign is the trade direction. Entry requires three conditions together: OI genuinely expanding (oi_change > 0 and oi_z >= oi_thresh, new leverage piling in), the crowd not paid (crowd_progress = vol-normalised return x crowd direction <= progress_thresh, no follow-through), and funding stretched to a crowding extreme (|funding_z| >= funding_thresh) with the funding LEVEL's sign agreeing with the z-score's sign so the correct cohort is identified. Extreme-positive funding + no upward progress -> SHORT the trapped longs; extreme-negative funding + no downward progress -> LONG the trapped shorts. Exits, first to fire: a hard 2x ATR(14) stop from entry (intrabar, checked before the target), a 3x ATR take-profit, a 'crowding resolved' exit when |funding_z| decays below 0.4 x funding_thresh, and a 12-bar (~2 day) time stop. Sizing risks 2% of equity at the initial ATR stop, hard-capped at 25% x leverage (= 50%) of equity notional.

Verification Results

Verification failed (Layer 3 — sandbox backtest): No trades produced Bar type used: LINKUSDT.BINANCE-4-HOUR-LAST-EXTERNAL, Bars processed: 2179 Diagnostics: should_enter() returned a side 0 times over 2113 evaluated bars -> your ENTRY CONDITION never triggered. Loosen the entry logic / thresholds. Ensure your strategy produces trades with the given data and parameters.

Verification Results

Route to backtest-review for full multi-year evaluation where the 0.15% floor applies; a 28-trade window is too small to declare the edge dead.

Verification Results

Sandbox mildly net-negative (total_return -2.08%, Sharpe -0.29, PF 0.85, win_rate 0.357, avg_trade_return_pct -0.234% over 28 trades), per-trade below the 0.15% futures floor. But NOT a structural fee-viability failure: low turnover (16, avg hold 16h) with large fee-clearing moves (avg_win ~2.6%, avg_loss ~1.7% of notional). The net loss is a low-win-rate directional edge miss over a small single window, not fee churn.

Verification Results

Confirm on the full backtest that SHORT entries fire; if the full history still yields zero shorts, revisit the SHORT-side gate for a latent asymmetry before trusting the long-short claim.

Verification Results

Direction asymmetry to verify (not a demonstrable bug): sandbox produced 28 LONG / 0 SHORT despite a symmetric hypothesis. I verified the SHORT branch is code-correct and reachable (SELL when funding_z>=funding_thresh AND funding_now>0 AND OI expanding AND no upward progress). Zero shorts is explainable — extreme-positive funding in crypto usually coincides with rallies, so the non-progress gate correctly blocks those shorts, while negative-funding trapped-shorts setups fired the longs. Most likely a window artifact, not an asymmetry defect.

Verification Results

No action required; keep as a general sandbox-vs-full-backtest supplementary-data plumbing gotcha for funding strategies.

Verification Results

Informational: the iteration-3 fix for the Layer-3 zero-trades symptom is verified effective (funding_events_available 0 -> 90). Root cause (dual-key funding dict arriving JSON-stringified in the sandbox subprocess, emptied by an int-only key filter) is correctly fixed by parsing both int and str keys through _to_ns and de-duping on the ns stamp; no look-ahead introduced; full-backtest supp_spec path unaffected.

Backtest Review

Clean, data-safe construction: single venue/instrument, two orthogonal non-price feeds (OI + funding) plus a non-directional price gate; well-controlled max_drawdown 18.6%

Backtest Review

Deliberately 3 tunables; thoughtful trapped-leverage mechanism distinct from prior fade ideas

Backtest Review

profit_factor 0.62 (< 1.0) — the strategy loses money; total_return -12.6%

Backtest Review

avg_trade_return_pct NEGATIVE (-0.522%) with expectancy -$189/trade — the signal is wrong-signed, no fee/frequency change can fix it

Backtest Review

Sharpe -0.326 (CI [-0.94, 0.34]); probabilistic_sharpe 0.157 — no skill

Backtest Review

Only 66 trades over ~4.5 years — too sparse for optimization to fit anything but noise

Backtest Review

Negative in 4 of 5 years (2022, 2023, 2024, 2025); avg_loss > avg_win

Backtest Review

Fade/reversal family (repeatedly dead here); the trapped-leverage triple-gate did not produce an edge

Outcome Summary

This strategy proposed a genuinely differentiated fade: detect trapped leverage by requiring open interest to rise sharply, funding to hit a one-sided crowding extreme, and price to make no progress in the crowd's direction — a cohort that has committed leverage and is bleeding funding with nothing to show for it, primed to unwind against itself. The construction was clean and thoughtful, using two orthogonal non-price feeds that cross-confirm the imbalance and a strictly non-directional price gate, with well-controlled drawdown. But the backtest falsified the premise: profit factor 0.62, a -12.6% return, a negative per-trade edge, and losses in 4 of 5 years, with the triple-gate firing only 66 times in 4.5 years. The analyst abandoned it at backtest review as a wrong-signed member of the repeatedly-dead fade/reversal family — the trapped-leverage confluence produced no edge — and noted the sparse sample would make optimization meaningless anyway.

Outcome Summary

Cross-confirming crowding from two orthogonal feeds (OI size + funding cost) plus a price-non-progress filter does not turn fading into an edge — the confluence still lost across nearly every year on LINK, and stacking three restrictive gates also thins the trade count so far (66 in 4.5 years) that even a real signal could not be validated.

Outcome Summary

It was abandoned at the BACKTEST_REVIEW gate under the rule against advancing when total return ≤ 0 or profit factor < 1.0: the trapped-leverage triple-gate premise was falsified (the fade lost in nearly every year), the per-trade return is negative (wrong-signed, so no threshold/frequency change can help), and the OI+funding+non-progress confluence fires too rarely (66 trades) for optimization to fit anything but noise. It never reached optimization or analysis.

Outcome Summary

A long-short, single-instrument, single-venue strategy on the LINKUSDT.BINANCE USD-M perp that fades trapped leverage — entering when open interest rises sharply (new leverage piling in) AND funding is at a one-sided crowding extreme AND price has made no progress in the crowd's direction (the leverage bought no follow-through, so it is trapped and primed to unwind), shorting trapped longs and longing trapped shorts, with an ATR stop and take-profit, using two orthogonal non-price feeds plus a price-non-progress gate.

Outcome Summary

It was a net loser with too few trades to optimize: profit factor 0.62, total return -12.6%, avg_trade_return_pct -0.522% (negative, expectancy -$189/trade), Sharpe -0.326 (CI [-0.94, 0.34], probabilistic Sharpe 0.157), max drawdown a controlled 18.6% over just 66 trades in ~4.5 years. Win rate was 44% with avg loss ($893) exceeding avg win ($710), and it was negative in 4 of 5 years (2022-2025).

Iteration History

Verification failed (leverage_set_but_unused): config sets leverage=2.0 but the strategy never references leverage in sizing. Size positions on it — notional = equity * fraction * leverage / price (read self.config.leverage) — or set leverage=1.0. As written the leverage is inert and the backtest is identical to 1x.
Strategy report

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