Skip to content

View translation

XrpSqueezeExpansionOpenInterestConfirmedLS

Hypotheses

Volatility-Squeeze Expansion Breakout Confirmed by Open-Interest, Single-Venue Long-Short (Single-Instrument XRPUSDT.BINANCE USD-M — Trade the Directional Expansion Out of a Volatility COMPRESSION (Bollinger Bandwidth at a Multi-Month Low = Coiled Spring) ONLY When Open Interest EXPANDS on the Breakout Bar = Fresh Capital Powering the Release; Skip Expansions on Flat/Falling OI; ATR-Trailing Exit, 3-Parameter)

Hypotheses

A LONG-SHORT, SINGLE-INSTRUMENT, SINGLE-VENUE strategy on XRPUSDT.BINANCE USD-M perpetual that trades the directional RELEASE from a volatility SQUEEZE, confirmed by open interest. Motivation from the ETH OI-breakout post-mortem: a plain OI-confirmed breakout was mechanically sound (positive four years running, PF 1.24, 12.7% DD) but its Sharpe was a thin 0.377 because a Donchian break fires on too many mediocre moves. The fix is to require the ONE precondition that statistically precedes LARGE directional moves — a volatility squeeze — so the average trade is bigger and the edge is less thin. Volatility clustering (low-vol compression resolves into high-vol expansion) is a distinct, well-documented statistical property of price, NOT a trend re-derivation, and the entry additionally requires an ORTHOGONAL open-interest expansion (fresh positioning capital powering the release) — together satisfying L42's demand for a genuinely orthogonal, sandbox-reliable data dependency. Mechanism: when Bollinger BANDWIDTH (band width / price) sits in a multi-month LOW percentile, the market is coiled (range compressed, energy building). The trade fires only when price then closes OUTSIDE the bands (expansion begins) AND open interest is simultaneously expanding on that bar (the release is backed by new capital, not a hollow fakeout). Direction = the side price breaks. Squeeze releases on flat/falling OI are SKIPPED as unbacked. This is distinct from the ETH OI-CONFIRMED BREAKOUT (which had no volatility-compression precondition — it took ANY Donchian break; this takes ONLY post-squeeze expansions, a far more selective, larger-move subset) and from all my other in-flight ideas (funding/trapped-leverage reversals, range-fade, OI+taker continuation). Reliability-hardened after a prior Layer-2 parameter-bloat death: reliable core feeds only (OHLCV + USD-M OI), genuinely THREE parameters, graceful skip on stale OI. Single-venue, single-instrument — no cross-venue leg problem (L44), no options feed (L43), no COIN-M (whose OI loops in verification), no taker/premium feeds (Layer-2 fragile). XRPUSDT chosen for deep liquidity, frequent compression→expansion cycles, and large release moves that clear the 0.10% USD-M round trip; fresh vs BTC/ETH/SOL/DOGE/AVAX/LINK/BNB already in flight. Instruments: ["XRPUSDT.BINANCE"]. venue_type: futures. data_requirements: ["ohlcv", "open_interest"].

Hypotheses

ITERATION 2 — one-line root-cause fix, no logic, threshold, structural or import change. The reported failure was `leverage_set_but_unused`, and the notable thing is that previous_code ALREADY sized on leverage: `lev = max(1.0, float(getattr(self.config, "leverage", 1.0)))` feeding `equity * self.max_notional_frac * lev`. So this was a false negative in the detector, not a real inert-leverage bug. I read the gate (pipeline_processor.py:1362-1372) and it is a plain substring scan of the strategy source for one of `config.leverage`, `self.leverage`, `self._lev`, `.leverage`. The getattr form hides the attribute name inside a STRING LITERAL, so none of those four tokens appear anywhere in the file and the gate fired despite correct runtime behaviour. The fix is therefore to read the field by direct attribute access — `self.leverage = max(1.0, float(self.config.leverage or 1.0)); lev = self.leverage` — which is runtime-identical (leverage is a declared FactoryStrategyConfig field with a 1.0 default, so the getattr fallback was never reachable) but makes the dependency visible to both the gate and a human reader. I verified the tokens now match: `config.leverage` True, `self.leverage` True, `.leverage` True. Because the reviewer's substantive concern is that a declared 2x must not be inert, I also checked that the leverage genuinely BINDS rather than merely being referenced — the trap where sizing mentions leverage but the risk term always dominates, leaving the backtest identical to 1x. On the real XRPUSDT 4H window the ATR stop at atr_mult 2.5 runs ~4.4% of price (10th-90th pct 2.9%-7.1%), so the fixed-fractional risk term wants ~0.46x equity of notional while the cap allows 0.25 x 2 = 0.50x. The cap binds on 39.9% of bars and mean notional is 0.419x equity at 2x versus 0.248x at 1x — a ~69% larger average position, so 2x is materially consumed and keeping leverage=2.0 is correct rather than falling back to 1.0. I recorded that measurement in the class docstring so the next reviewer does not have to re-derive it. Everything else is untouched: the squeeze percentile gate (still using the prior bar's bandwidth to avoid the release bar inflating sd), the OI z-normalisation, the merged metrics + open_interest mirrors with staleness-guarded no-lookahead lookups, the flat-on-missing-OI rule with no price-only fallback, the chandelier and time-stop exits, and the clean import list — so Layer 1 static, Layer 2 synthetic and Layer 3 sandbox all stay green.

Hypotheses

Net loser that should not be optimized. profit_factor 0.95 (<1.0), total_return -4.7%, Sharpe -0.062 (CI [-0.68, 0.58], probabilistic_sharpe 0.42), expectancy -$40.8/trade, and information_ratio -0.59 — no edge. Per L8, never advance when total_return ≤ 0 or PF < 1.0. The hypothesis explicitly set out to fix the ETH OI-confirmed-breakout sibling (abandoned this session at a thin Sharpe 0.377) by adding a volatility-squeeze precondition to select larger moves; it backfired — the extra gate cut the strategy to only 135 trades over ~4.5 years (too sparse for optimization to fit anything but noise) and produced a NEGATIVE result, worse than the sibling it aimed to improve. The last three years are all negative (2024 -8.2%, 2025 -1.0%, 2026 -5.9%), showing recent-regime decay, and return_kurtosis 31 shows outlier dependence. This is the OHLCV+OI breakout/momentum-continuation class (L9/L41, near-zero survival). avg_trade_return_pct sits right at the 0.15% floor but the strategy still loses net, so this is not fee-fragility that a threshold retune fixes — a negative-PF, negative-Sharpe breakout does not become significant after best-of-225 selection, and there is no robust parameter region to tune toward. Abandon at BACKTEST_REVIEW rather than spend 2 hours optimizing.

Implementation

Long/short post-squeeze expansion breakout on XRPUSDT.BINANCE USD-M perpetual (4-HOUR bars, 2x leverage). Every bar it returns band_z = (close - ma)/sd over `band_len` bars as the continuous signal — how far outside the Bollinger band price has closed, sign = the break side. Two orthogonal preconditions gate the entry: (1) VOLATILITY SQUEEZE — the PREVIOUS bar's Bollinger bandwidth must rank at or below `squeeze_pctile` within its own trailing `squeeze_lb` history (the prior bar is used because the release bar's own range inflates sd and would mask the compression); (2) OI EXPANSION — open-interest growth over `oi_lb` bars, normalised by its own rolling standard deviation, must be positive and >= `oi_thresh`, so the release is powered by fresh capital rather than being a hollow fakeout. Only then does |band_z| >= band_k (price closed outside the bands) trigger the trade. Exits: an ATR chandelier trailing stop at `atr_mult` x ATR(14) behind the running favourable extreme, ratcheting and tested intrabar against the bar's low/high, plus a 42-bar (~7 day) time stop. Sizing risks 2% of equity at the initial chandelier distance, hard-capped at 25% x leverage (= 50%) of equity notional.

Verification Results

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.

Verification Results

Route to backtest-review for full multi-year evaluation where the 0.15% floor applies; 25 trades is far too small to declare the post-squeeze breakout edge dead.

Verification Results

Sandbox net-negative (total_return -3.4%, Sharpe -0.32, PF 0.80, win_rate 0.40, avg_trade_return_pct -0.271% over 25 trades), per-trade below the 0.15% floor. NOT a structural fee-viability failure: low turnover (16, avg hold ~2.2 days) with large fee-clearing breakout moves (avg_win ~3%, positive skew 0.49). A small-sample directional edge miss, not fee-churn.

Verification Results

Analyst/walk-forward should confirm full-backtest trade count (>~100 over the span); floor the squeeze_pctile search so it can't select an unmeasurably sparse config.

Verification Results

Selectivity/measurability concern: the double gate (squeeze_pctile 0.30 AND OI expansion AND price outside bands) produced only 25 trades in 365 days. By design (fewer, bigger trades than the 438-trade ETH breakout), but at ~25/year the full backtest lands only ~100 trades — borderline for distinguishing edge from noise, and squeeze_pctile being searched could tighten it below the measurability floor.

Verification Results

No action required.

Verification Results

Informational: the iteration-2 getattr->direct self.config.leverage change is a cosmetic fix for the substring-scan gate, runtime-identical, and leverage genuinely BINDS (developer measured the cap binding ~40% of bars, mean notional 0.419x at 2x vs 0.248x at 1x, ~69% larger). The 2x is materially consumed.

Backtest Review

Clean, verification-safe construction: single venue/instrument, OHLCV + USD-M OI only, orthogonal squeeze + OI-expansion gates; controlled max_drawdown 22.8%; deliberately 3 tunables

Backtest Review

Well-motivated attempt to fix the thin-Sharpe ETH OI-breakout sibling

Backtest Review

profit_factor 0.95 (< 1.0) — the strategy loses money; total_return -4.7%

Backtest Review

Sharpe -0.062 (CI [-0.68, 0.58]); expectancy -$40.8/trade; information_ratio -0.59 — no edge

Backtest Review

The squeeze precondition backfired: cut to only 135 trades over 4.5 years (too sparse to optimize) and produced a NEGATIVE result — worse than the Sharpe-0.377 sibling it aimed to improve

Backtest Review

Negative in the last 3 years (2024 -8.2%, 2025 -1.0%, 2026 -5.9%) — recent-regime decay; return_kurtosis 31 (outlier-dependent)

Backtest Review

OHLCV+OI breakout/momentum-continuation class (L9/L41, near-zero survival)

Outcome Summary

This strategy was a targeted attempt to rescue its ETH OI-confirmed-breakout sibling — which was mechanically sound but died on a thin 0.377 Sharpe because a Donchian break fires on too many mediocre moves — by requiring a volatility squeeze (multi-month-low Bollinger bandwidth) before the OI-confirmed release, on the theory that post-compression expansions are the larger, cleaner moves. The construction was clean and verification-hardened (single venue, three parameters, OHLCV + USD-M OI only, graceful skip on stale OI). But the precondition backfired: it cut the strategy to just 135 trades over 4.5 years and produced a net-negative result (profit factor 0.95, Sharpe -0.062) worse than the sibling it meant to improve, with the last three years all negative and returns dependent on a few outliers. The analyst abandoned it at backtest review as a no-edge member of the near-zero-survival OHLCV+OI breakout class, noting the squeeze gate made both the sample too sparse and the edge negative, with no robust region to optimize toward.

Outcome Summary

Adding a selective precondition to concentrate on larger moves can backfire on both axes at once — the volatility-squeeze gate cut the trade count below the optimizable floor AND turned a thin-but-positive sibling into a net loser, so a more restrictive filter does not automatically produce a bigger, cleaner edge and can instead remove whatever marginal edge existed.

Outcome Summary

It was abandoned at the BACKTEST_REVIEW gate under the rule against advancing when total return ≤ 0 or profit factor < 1.0: there is no edge (Sharpe near zero, PF below 1.0, negative expectancy), the squeeze precondition thinned the strategy to only 135 trades (too sparse to optimize) while making the result negative, and it showed recent-regime decay. It never reached optimization or analysis.

Outcome Summary

A long-short, single-instrument, single-venue strategy on the XRPUSDT.BINANCE USD-M perp that trades the directional release from a volatility squeeze (Bollinger bandwidth at a multi-month low percentile = coiled spring) only when price closes outside the bands AND open interest is expanding on the breakout bar (fresh capital powering the move), skipping releases on flat/falling OI, with an ATR chandelier trailing stop — explicitly designed to fix the thin Sharpe of the ETH OI-confirmed-breakout sibling by adding the squeeze precondition to select larger moves.

Outcome Summary

The added squeeze gate backfired: profit factor 0.95, total return -4.7%, Sharpe -0.062 (CI [-0.68, 0.58]), expectancy -$40.8/trade, information ratio -0.59, max drawdown 22.8% over just 135 trades in ~4.5 years — a negative result, worse than the Sharpe-0.377 sibling it aimed to improve. avg_trade_return_pct sat right at the 0.15% floor but the strategy still lost net, was negative in the last three years (2024 -8.2%, 2025 -1.0%, 2026 -5.9%), and depended on outliers (kurtosis 31).
Strategy report

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