Skip to content

View original

EthSpotDeribitWeeklyCoveredCallVrpOverlay

Hypotheses

ETH Weekly Covered-Call Overwrite, Cross-Venue Income Overlay (Long ETHUSDT.BINANCE_SPOT + Short ~20-Delta Weekly OTM ETH Call on DERIBIT, Harvest Call VRP + Theta, Roll Weekly, 2-Parameter)

Hypotheses

A structural INCOME-OVERLAY strategy that harvests the persistent crypto call-option volatility risk premium and time decay, distinct from the naked OTM-put VRP harvest already in the pipeline (different Greeks profile: this is long-underlying + short-call, retaining spot upside to the strike rather than selling downside insurance). Hold a strategic long in ETH on BINANCE_SPOT and each week SELL one weekly out-of-the-money ETH call on DERIBIT at ~20-delta, collecting the premium. If ETH stays below the strike, the call expires worthless and the full premium is kept; if ETH rallies through the strike, the spot gains offset the assigned call up to the cap (the position simply realizes a bounded, positive outcome). The edge is that weekly crypto call IV is systematically richer than subsequent realized vol, so repeatedly selling and rolling the call adds a steady yield on top of the spot hold. Deliberately low-parameter (strike delta + roll cadence), no price-prediction, no momentum — it does NOT belong to the exhausted OHLCV-momentum classes (L9/L38/L41) that have zero survivors. Fills the single most under-represented portfolio buckets at once: options (BINANCE_OPTIONS 0.0% + DERIBIT 5.0% vs 15% target) AND cross-venue (6.8% vs 15% target), using ETH rather than the over-mined BTC.

Hypotheses

Iteration-3 fix for the Layer-3 300s wall-clock failure. The feedback's suggested cause (per-bar work scaling with history) was already eliminated in iteration 2 — realized vol is incremental O(1), the period lookup is a forward-only pointer, the cover instrument is cached — and iteration 2 additionally cut bar volume 4x by moving 1-HOUR -> 4-HOUR, yet the sandbox still timed out. So I profiled the actual cost path instead of guessing: a single windowed `ParquetDataCatalog.bars()` call for ONE Deribit option leg measures ~9-10s of fixed catalog-resolution time, and that cost is independent of both the number of bars returned (9 bars cost the same as 105) and the timeframe — which is exactly why the 1-HOUR -> 4-HOUR change produced no improvement. `BacktestRunner` issues one such query per extra bar type, so a 365-day weekly chain (52 legs, as the run log confirms: 'Layer 3 expanded rolling options legs=52') burns ~520s in data loading before a single bar is processed. The only lever that moves that cost is the number of legs. Therefore the change is CONFIG-ONLY: `rolling_options.lookback_days` 365 -> 120, which yields ~17 weekly expiries (~170s of leg loading + ~21s for the perp and spot legs + engine/startup), comfortably inside the 300s cap. Not one line of Python behaviour changed — the module docstring gained an iteration-3 note and nothing else — so Layer 1 (imports/structure, no banned imports added) and Layer 2 (the cushion signal, `ln(K/S)/sigma_week`, computed identically every bar) stay exactly as they passed. The mechanism, the weekly roll cadence, the ~7% OTM strike, the leg sides, the cover maintenance and the sizing are all untouched; only the chain span is shorter, giving ~17 weekly write-and-roll cycles in the backtest. One honest caveat for the Analyst: 120 days of history is a thin sample for a structural income overlay, but it is the largest span that fits the sandbox's per-leg data-loading budget, and there is no strategy-side change that can reduce that per-leg catalog cost.

Hypotheses

data_wall / unmeasurable: the Deribit weekly-ETH option chain provides only ~18 weekly expiries over ~122 days of history, so the VRP-overwrite edge cannot be tested with any statistical meaning. The claimed call-VRP edge is actually net negative on the available sample (option legs sum to ~-$1,916; a single rally week -$8,896 wipes out 17 premium wins), and the book's +2.37%/CAGR 7.3% is entirely long-ETH spot beta, not the overlay. With only 18 expiries a 3-window walk-forward + holdout is noise, and options cadence means iteration cannot raise the trade count (L27). This is a DATA limitation, not a code or premise-falsification flaw: revive and re-run the same mechanism once the Deribit weekly-ETH chain accumulates 1.5-2+ years of history so a full walk-forward and holdout have an adequate sample. Not worth 2 hours of optimization on 18 expiries dominated by one tail loss.

Implementation

ETH weekly covered-call overwrite: hold a long ETHUSDT position on BINANCE_SPOT as cover and, each weekly cycle, SELL one ~7%-OTM weekly ETH call on DERIBIT resolved from the historical option chain, buying it back 6h before expiry and rolling into the next week. Income overlay harvesting the call volatility risk premium plus theta; the spot leg caps assignment risk. Runs on 4-HOUR bars off the ETH-PERPETUAL.DERIBIT roll clock; the spot cover is kept matched 1:1 to the open short-call contracts with a 10% rebalance band. Sizing is a fixed 50% of equity (never a compounding multiple), leverage 1.

Verification Results

Verification failed (Layer 4 — QA review) [class=not_measurable]: - [edge_concern] The ~17-cycle sandbox cannot support a verdict on a structural income overlay, and its headline numbers mislead. avg_trade_return_pct -161% is NOT an L72 fee-nonviability signal here — it is a per-leg accounting artifact: on a rally week the short-call leg books a large loss vs its tiny premium notional while the matched long-spot leg books the offsetting gain, reported separately (largest_loss -$8,734 vs avg_win $778). The portfolio result is positive and low-drawdown (total_return +2.6%, PF 1.60, max_dd 4.1%, win_rate 0.95 as most OTM calls expire worthless) — the expected covered-call shape — but on 19 trades / 17 weekly cycles over a forced 120-day window it says almost nothing (Sharpe CI [-2.38, 6.38]). A covered call's real risk is the occasional deep-spot-drawdown week, which 17 cycles can't sample. Don't read either +2.6% or -161% as edge. - UNMEASURABLE SAMPLE — the same weekly-options per-leg catalog-query ceiling as the sibling short-vol options strategies. Each Deribit option leg costs ~9-10s fixed ParquetDataCatalog.bars() resolution (independent of bar count/timeframe), one query per extra bar type, so a full 52-leg weekly chain spends ~520s in loading — past the 300s cap. That forced lookback_days to 120 → ~17 weekly cycles, and the config bounds even the full backtest to that span. 17 cycles is far below the ~30+ needed to sample the tail dominating an income overlay's risk. Not fixable in strategy code (developer confirms no strategy-side change reduces the per-leg cost) — needs the platform fix (cache/reuse the globbed file list). Park pending that fix; do not optimize/promote on ~17-cycle metrics.

Backtest Review

Well-formed, low-parameter income-overlay: spot cover matched 1:1 to the written weekly OTM call; the trade ledger correctly implements the hypothesis (18 SHORT ~20-delta weekly calls rolled weekly + 1 long ETH spot cover).

Backtest Review

Book-level metrics are modest and plausible once read as percentages: total_return +2.37%, CAGR 7.3%, max_drawdown 4.18%, Sharpe 0.76, 89% win rate. No accounting artifact.

Backtest Review

Fills genuinely under-represented options + cross-venue buckets.

Backtest Review

Sample far too small to optimize/validate: only 18 weekly expiries over ~122 active days (May-Sep 2026). A 3-window walk-forward + holdout would leave ~6 / ~3 expiries per split — noise. Deribit weekly-ETH option bar history is the binding limit (developer already truncated the chain to 120d to fit the sandbox; earliest option bars are only ~months old).

Backtest Review

The claimed edge (call VRP harvest) is NET NEGATIVE on this window: the 18 option legs sum to ~-$1,916 because one rally week (ETH-21AUG-2000-C) lost -$8,896, erasing all 17 small premium wins. The positive +2.37% is entirely long ETH spot beta (+$6,650), not the overwrite.

Backtest Review

Short-call payoff (many small wins, rare large loss) means a single tail event dominates an 18-expiry sample — the VRP premise is statistically untested, not confirmed or falsified.

Backtest Review

avg_trade_return_pct -114% is the premium-notional artifact for defined-premium options and is not fee-comparable; disregarded per options guidance.

Iteration History

Verification failed (Layer 3 — sandbox backtest): smoke test exceeded the 300s wall-clock limit. This almost always means per-bar work that scales with history — e.g. rescanning the full funding/supplementary series, or rebuilding a list and calling min()/sorted() inside calculate_signal()/on_bar() on every bar. Precompute sorted timestamp arrays ONCE in __init__ and use bisect, or cache lookups keyed by timestamp, so per-bar cost is O(log n) not O(n).

Iteration History

Verification failed (Layer 4 — QA review): - STRUCTURALLY UNMEASURABLE TRADE COUNT. This is a weekly-roll Deribit options overlay whose backtest span is hard-capped at rolling_options.lookback_days=120 by the ~10s-per-leg ParquetDataCatalog loading cost the developer documents in the iteration-3 note. 120 days / 7-day weekly roll = ~17 option-write-and-roll cycles. That is far below the ~30-trade minimum needed to distinguish edge from noise, and the cap is NOT tunable — extending the chain to a measurable span (52+ weekly legs) re-triggers the 300s wall-clock timeout that already killed iterations 1-3. So the strategy is trapped: any window large enough to measure the VRP edge cannot be backtested within the time budget, and any window that fits the budget is too small to measure. The sandbox confirms the regime: data_days=18, total_trades=18, Sharpe 3.48 with a 95% CI of [-2.89, 23.86] (uselessly wide), avg_trade_return_pct 86.2% and win_rate 0.94 — none of these are statistically meaningful at n<20. This is the exact options-family failure mode (Deribit ETH/BTC weekly/monthly put-and-call writes, single-leg long options) that has repeatedly reached backtest and then died unmeasurable after burning timeout iterations. Reject now rather than spend more backtest/timeout cycles confirming an un-measurable result. - Strike-selection mismatch vs the hypothesis. The hypothesis specifies a ~20-DELTA weekly OTM call, but the implementation writes a FIXED 7% out-of-the-money strike (call_offset=0.07, and the chain spec leg offset=0.07). A fixed moneyness offset is not a fixed delta — for a weekly ETH call the delta at 7% OTM drifts with realized/implied vol (it can be anywhere from ~10-delta in calm weeks to ~35-delta in volatile weeks), so the risk/premium profile is not the ~20-delta the hypothesis names. The chain spec resolves an actually-listed strike, so this is a structural approximation rather than a wrong contract, hence warning not critical — but the delivered Greeks profile is not the stated one. - Per-trade metrics are uninterpretable for this multi-leg overlay. The short-call leg and the covering spot long are booked as SEPARATE positions, so on a rally the option leg realizes a large loss (largest_loss -$3112) while the offsetting spot gain remains unrealized on the single long leg — the reported avg_trade_return_pct=86.2%, win_rate=0.94, avg_win $388 vs avg_loss $3112 do not reflect the strategy's netted P&L. Any downstream avg_trade_return_pct fee-floor check will read a meaningless number. This compounds the measurability problem: even the 17 cycles that exist cannot be evaluated on standard per-trade stats.
Strategy report

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