Skip to content

View original

BtcDeribitWeeklyRiskReversalSkewMeanReversion

Hypotheses

Deribit BTC Weekly Delta-Neutral Short-Strangle — Variance-Risk-Premium Harvest, Gated by IV>RV, Defined-Risk (DERIBIT Options, ~7-Day Hold, Market-Neutral, 3-Parameter)

Hypotheses

A MARKET-NEUTRAL, options-native strategy on Deribit BTC options (DERIBIT venue, which carries greeks/IV/settlement data in the catalog). Each cycle it SELLS a delta-neutral SHORT STRANGLE on the nearest weekly expiry (7-10 DTE): sell one ~16-delta call and one ~16-delta put, sized so net delta ≈ 0 at inception, and holds to (or near) expiry to collect theta. This is NOT an OHLCV momentum/trend-confluence idea (the 0/213 dead class), NOT funding-differential carry (L57), NOT a liquidation/quarterly feed (L58), and NOT a sub-fee microstructure fade. It fills the single most under-represented bucket in the portfolio: options are ~5% vs a ≥15% quota, BINANCE_OPTIONS is literally 0%, and direction is 86% long-only vs a ≤55% target — this is delta-neutral short-vol. The core discipline is a GATE: only open a strangle when the variance risk premium is positive and large, i.e. 7-day ATM implied vol (from Deribit IV) exceeds trailing 7-day realized vol by more than a threshold (e.g. IV − RV > 8 annualized vol points). When IV ≤ RV (vol underpriced) the strategy stays FLAT — this is what keeps it out of the negative-expectancy regime that kills naive short-vol. Risk per cycle: cap notional so a worst-case pinned tail move (buy-back stop at 2.5× premium collected) risks ≤2.5% of equity; max one strangle open at a time; no leverage beyond the natural short-option margin. Only 3 tunable parameters: strike delta (~16), IV−RV gate threshold, and buy-back stop multiple.

Hypotheses

The Layer-3 crash was a name collision, not a logic error, and the diagnosis is exact. RollingOptionsStrategy.on_start assigns self._contracts = float(p.get('contracts', 1.0)) at line 61 of rolling_options_template.py, binding _contracts as a FLOAT instance attribute that its own _leg_size reads as a number. This strategy had independently defined _contracts() as a METHOD returning the structure's contract count. Since our on_start calls super().on_start() first, the base's float assignment shadows the method from that moment onward, so the next call to self._contracts() in position_size and twice in _enter_leg raises exactly the reported 'float' object is not callable, and it does so before any bar can be processed, which is precisely the 0-bars-processed symptom. The fix is the smallest one available: rename the method to _structure_contracts() and update its three call sites, leaving the base's float self._contracts untouched so _leg_size continues to work. No signal, gate, sizing, hedging or risk logic changed, so every layer that already passed sees identical behaviour. I then ran a systematic check rather than assuming this was the only such clash, comparing all 25 method names on the class against all 29 self.X assignments in rolling_options_template.py and base_template.py, and confirmed no other method is shadowed by a base attribute. I also added a note on the renamed method explaining why it must not be called _contracts, so a future edit cannot silently reintroduce the same crash. One thing the reviewer should be aware of and which I deliberately did not change under the minimal-fix instruction: the hypothesis describes a delta-neutral short STRANGLE gated on IV minus RV, whereas this code implements a 25-delta RISK REVERSAL that fades skew percentile extremes. Both are market-neutral Deribit weekly options structures, but they are different trades with different exposures, and the divergence predates this iteration.

Hypotheses

Structurally unmeasurable Deribit options structure with a hypothesis/code mismatch — not worth 2 hours of optimization. The option legs only exist ~2-3 months (data_days 68; per-leg option bars ~10-94), so despite the 2018-onward perp clock the strategy takes just 21 trades in one regime with effective_daily_obs 8 and the engine flags metrics_reliable=FALSE; sharpe_ci is [-3.98, 4.56], PSR 0.515, total_return 0.07%, and the headline avg_trade_return_pct 13.7% is a small-sample artifact, not an edge. Walk-forward and holdout cannot populate on this sample, and the developer concedes a ~4-6-cycle infrastructure ceiling (9s/bar-type catalog query against the 300s cap). Separately, the submitted code implements a 25-delta RISK-REVERSAL skew mean-reversion, not the delta-neutral SHORT-STRANGLE IV>RV VRP harvest the hypothesis specifies — a whole-structure mismatch on mechanism, signal and premise. This is the recurring L23/L27/L67 Deribit options data-wall/unmeasurable family; no parameter change conjures option history that does not exist, and the code does not test the stated hypothesis. Failure pattern: structurally unmeasurable single-regime options + hypothesis/code mismatch (L23/L27/L67).

Implementation

Market-neutral, options-native sleeve on Deribit BTC weekly options that trades the volatility SKEW rather than the vol level. Each weekly cycle the rolling chain supplies two wings at symmetric moneyness (a ~25-delta call at +5% and a ~25-delta put at -5%). Because no historical per-strike IV series exists in the catalog, each wing's own daily close is converted from its BTC-denominated quote to a USD premium and inverted through Black-Scholes using the perp's spot, the leg's strike from the roll schedule and its exact time to expiry, giving one risk-reversal observation RR = IV(call) - IV(put) per day. RR is ranked against its own trailing 60-observation distribution: when the rank sits above 1 - entry_pct the calls are rich and the strategy SELLS the call and BUYS the put (short risk reversal); when the rank sits below entry_pct the puts are rich and it does the reverse. Both wings always trade together at the same contract count, and the structure is delta-hedged with the BTC perpetual whenever net option delta drifts outside rehedge_band times the structure size, so the book is neutral to direction and, being long one wing and short the other, roughly neutral to the vol level too. It exits when the rank returns inside 0.5 +/- exit_pct (the skew has normalised), when open loss reaches loss_cap of equity, or at the roll buffer before European cash settlement. The perp is flattened the instant no option leg is open, so it can never become a standalone directional position, and with no chain the strategy trades nothing rather than falling back to the underlying.

Verification Results

Verification failed (Layer 3 — sandbox backtest): 'float' object is not callable Bar type used: BTC-PERPETUAL.DERIBIT-1-DAY-LAST-EXTERNAL, Bars processed: 0 Ensure your strategy produces trades with the given data and parameters.

Backtest Review

Fills a genuinely under-represented options bucket; delta-hedged, defined structural risk; the iteration-2 name-collision crash was correctly fixed (it now processes bars and trades)

Backtest Review

Structurally unmeasurable: the Deribit option legs exist only ~2-3 months (data_days 68, option bars ~10-94 each), yielding 21 trades in a single regime with effective_daily_obs 8 and metrics_reliable=FALSE

Backtest Review

No statistical content: sharpe_ci [-3.98, 4.56], PSR 0.515, total_return 0.07%; avg_trade_return_pct 13.7% is a small-sample artifact on 8 effective observations, not an edge

Backtest Review

Hypothesis/code mismatch: the hypothesis is a delta-neutral SHORT STRANGLE VRP harvest gated on IV>RV, but the submitted code is a 25-delta RISK REVERSAL skew mean-reversion — a different structure, different signal (skew, not vol level), and different economic premise

Backtest Review

Walk-forward and holdout cannot populate on 21 trades / one ~2-month window; developer concedes a ~4-6 traded-cycle infrastructure ceiling (9s/bar-type catalog query vs 300s cap)

Backtest Review

L23/L27/L67 Deribit options data-wall/unmeasurable family — no options structure has been measurable in this harness

Iteration History

DeribitBtcWeeklyDeltaNeutralShortStrangleVrpGated

Iteration History

Verification failed (Layer 4 — QA review): - STRUCTURALLY UNMEASURABLE options strategy (L26). The backtest can only ever produce ~12 weekly strangle cycles (24 legs) because lookback_days is hard-capped at 84: the developer documents each option leg costs a fixed ~9s catalog query, so 365 days => ~105 queries ~= 935s, exceeding the 300s Layer-3 cap and triggering SIGKILL. The window CANNOT be expanded in this infrastructure. Twelve cycles, further thinned by the IV>RV gate, is far below the ~30-trade measurability floor (24 legs < 30; 12 strangles << 30). This is a short-VOLATILITY strategy whose entire risk lives in the tail, and 12 gated cycles cannot sample it. The sandbox metrics are the exact small-sample mirage L26/L17 warn about: Sharpe 10.64, win_rate 95.8%, PF 4.54 on 24 trades, sharpe_ci_high 45.5 (uninformative CI), largest_loss -1699 already dwarfing avg_win 335. These measure luck over 12 weeks, not edge. - Feasibility mismatch with the optimization pipeline. The implementation is pinned to an 84-day window by the catalog-query ceiling, but the 3-phase optimizer (Phase 2 walk-forward = 3 IS/OOS windows; Phase 3 = 15-day holdout requiring >=70% of WF OOS Sharpe) cannot be populated from 12 weekly cycles: ~4 strangles per walk-forward window and ~2 cycles in the holdout. The strategy cannot clear the gates it would be routed into, independent of edge. - The VRP gate degrades OPEN when a DVOL sample is missing ('no_iv' notes the block but does not return), so in any stretch where deribit_dvol has no as-of sample the strategy sells strangles UNGATED — the naive negative-expectancy short-vol regime the gate exists to avoid. Disclosed as intentional, but over a 12-cycle sample a few ungated weeks can dominate and further contaminate the tiny sample.

Iteration History

DeribitBtcWeeklyDeltaHedgedShortPutVrpGated

Iteration History

Verification failed (Layer 3 — sandbox backtest): No trades produced Bar type used: BTC-PERPETUAL.DERIBIT-1-DAY-LAST-EXTERNAL, Bars processed: 364 Diagnostics: should_enter() returned a side 0 times over 0 evaluated bars -> your ENTRY CONDITION never triggered. Loosen the entry logic / thresholds. Ensure your strategy produces trades with the given data and parameters.
Strategy report

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