Skip to content

View translation

BtcWeeklyBearCallSpreadCallSkewHarvest

Hypotheses

BTC Weekly Bear-Call-Spread Call-Skew/VRP Harvest on Binance Options (Defined-Risk, Single-Expiry, Held-to-Expiry, Sell Overpriced Upside Convexity ONLY in Overbought + IV-Rich Regimes, 3-Parameter)

Hypotheses

A DEFINED-RISK, short-upside-convexity structure on BINANCE_OPTIONS BTC weekly European options — deliberately filling the single emptiest bucket in the portfolio (BINANCE_OPTIONS = 0.0% / 1 experiment; options combined 5.2% vs the 15% quota) while dodging every known options-failure mode. It is NOT a put-side structure (the two pending options ideas are a bull-put-spread skew harvest and an ATM iron-fly) and NOT an iron condor/fly (the abandoned Deribit VRP idea), so it is materially differentiated by both venue and mechanism. Each week the strategy sells a ~20-25 delta out-of-the-money weekly CALL and simultaneously buys a ~10 delta higher-strike weekly CALL as a hard wing (a bear-call vertical), collecting net credit and harvesting the structurally OVERPRICED upside convexity that crypto retail upside-leverage demand bids into short-dated call IV. Max loss is capped at (strike_width - net_credit), so it cannot blow through a drawdown floor the way naked short-vol or long-only spot baskets (L48) do. CRITICALLY engineered against the recurring options failure modes: (1) NO per-bar full-history rescan — the only decisions happen once per weekly expiry roll, and the IV-rank filter reads from a fixed-length rolling deque (O(1) update), so it cannot hit the 300s Layer-3 wall-clock timeout that killed the Deribit iron condor; (2) SINGLE expiry, HELD TO EXPIRY (cash-settled) — no mid-week exit fills, no calendar/second-expiry data dependency, minimizing the data-span and liquidity risk that abandons most options ideas; (3) the credit clears fees with room to spare (see expected_edge). This is short/neutral-vol (not long_only), single-instrument, single-venue.

Hypotheses

ITERATION 3 — ONE FINDING FIXED, TWO ARE STRUCTURAL, AND MY RECOMMENDATION IS ABANDON. Of QA's four findings, exactly one is addressable in strategy code and I fixed it; the other three are either outside strategy scope or are the hypothesis's own premise failing, and no further iteration changes that. FIXED — DELTA DRIFT. QA is right that 5% OTM resolved to ~0.276 delta, above the specified 20-25 band. The resolver picks strikes by moneyness, so I measured the mapping across 279 weekly cycles at DVOL: +5.0% = 0.276, +6.0% = 0.237, +7.0% = 0.203. The short leg is now +6% OTM (0.237, mid-band) with the wing at +10% (~0.12 delta, matching the ~10 delta spec). Cost: slightly smaller credit (+0.114%/week vs +0.147% unconditional) for a tighter worst case (-3.75% vs -4.61%). Both legs stay inside the depth where weekly contracts reliably have candles — a wing that fails to resolve is exactly how this degenerates into a naked short. This is the only code/config change; all logic that passed Layers 1-3 is untouched. ONE CORRECTION TO THE REVIEW, offered precisely because it removes an argument against the override: the venue swap is FEE-NEUTRAL. venue_configs.py prices BINANCE_OPTIONS at 0.0300% maker / 0.0300% taker and DERIBIT at 0.0300% / 0.0300% — identical. The hypothesis's fee argument holds unchanged on Deribit. What the override genuinely cannot deliver is the PORTFOLIO-BUCKET goal, and QA is right that this is material: filling BINANCE_OPTIONS requires a Binance chain resolver plus historical option klines (a data-engineer task), because the API serves only currently-listed contracts. That is not fixable by me at any iteration count. NOT FIXABLE — TRADE COUNT, AND HERE IS THE ARITHMETIC THAT SETTLES IT. At the measured ~7.3s per option instrument (BacktestRunner loads extras one at a time; 20 instruments = 145s) and 2 legs per cycle: reaching 30 trades at the measured 29% gate-pass rate needs ~104 cycles = 208 legs = ~1,510s, five times the 300s cap. Reaching 30 trades with the gates REMOVED ENTIRELY still needs 30 cycles = 60 legs = ~436s — still over. The 300s budget buys ~25 legs = ~13 cycles = ~4 trades, which is what the sandbox reported. So the ~30-trade measurability floor and the wall clock are mutually exclusive here regardless of gates, strikes or tenor; loosening the gate to buy trades would trade away the hypothesis without reaching the floor anyway. The single unblock is batching the loader — the same 20 instruments load in 7.8s (0.39s each, 18.6x faster) when passed to catalog.bars() in ONE call, which puts 60 legs at ~23s and makes the floor easy. NOT FIXABLE — THE EDGE ITSELF. QA correctly reads my own event study: the gated form the hypothesis specifies measures negative and insignificant (IV-rank>=0.3 AND overbought >5%: n=35, -0.078%/week, t=-0.23), while both the unconditional structure (+0.195%, t=+2.07) and IV-rank-only (+0.298%, t=+1.73) beat it. Selling upside convexity into strength is when BTC runs through the short strike. I implemented the gate faithfully rather than inverting it, because turning it into an IV-rank-only or contrarian structure would be smuggling in an uncommissioned strategy — that call belongs to the Research Lead. RECOMMENDATION: abandon this hypothesis. Its premise is falsified in gated form, its named venue cannot be validated, and its sample cannot reach measurability under the current loader. If the underlying observation is worth pursuing, the two productive follow-ups are (1) commission the loader fix, which unblocks every options strategy in the factory and is a prerequisite for the 15% options quota the portfolio wants, and (2) a NEW Research-Lead-owned hypothesis for IV-rank-only short call spreads with no overbought condition, which is the variant my data actually supports.

Hypotheses

Structurally unmeasurable, negative per-notional, and premise-refuted by the developer's own analysis — not worth 2 hours of optimization. The Deribit option legs only exist ~3 months, so despite the 8-year BTC-perp clock the effective option history is data_days 78 with just 8 trades and effective_daily_obs 4; the engine sets metrics_reliable=false and notes 'only 4 days moved the equity curve,' so the Sharpe 2.99 is noise on a tiny single-regime sample. This is the L67 defined-risk Deribit options family: avg_trade_return_pct is -5.12% (negative per defined-risk wing notional), the structural negative-per-notional edge masked by a flattering headline. The developer's docstring pre-registers the kill: the overbought gate 'measures NEGATIVE' (the weeks it discards outperform the weeks it keeps — selling calls into strength is when BTC runs through the short strike), the premise is refuted at every threshold, the 30-trade floor is unreachable under the current loader (can't load enough legs inside 300s even ungated), and the named BINANCE_OPTIONS venue cannot run at all (Deribit override that doesn't fill the intended bucket). No parameter change fixes a backwards premise, a negative-per-notional structure, a ~3-month option sample, and an unreachable trade floor, and the 3-phase walk-forward/holdout cannot populate on 8 trades. Failure pattern: structurally unmeasurable single-regime option history + L67 defined-risk Deribit VRP (negative per-notional), premise refuted.

Implementation

Weekly defined-risk bear call credit spread on BTC options. Each weekly cycle the chain resolver supplies two front-week (7 DTE) calls: the ~6% OTM call (~0.24 delta, mid-band for the specified 20-25 delta) is SOLD and the ~10% OTM call (~0.12 delta) is BOUGHT as a wing, capping maximum loss at the strike width less the credit. The structure is established only when BOTH gates pass — DVOL's percentile rank within its trailing 365-day history >= 0.30 (IV-rich) AND the underlying trading above its 168-bar (7-day) mean (overbought) — otherwise the week is skipped. Held to 2 hours before expiry, then closed; no mid-week exit logic and no second expiry. Leg roles come from strike order and a week trades ONLY if both legs resolved, so an unpaired short call is dropped rather than sold naked. Gate decisions are made once per expiry and cached; the IV-rank lookup is a binary search into arrays built once, so per-bar cost is O(1). Sizing is one contract with a capital-relative floor. Three tunable parameters: iv_rank_min, overbought_min, trend_lookback_bars.

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

Cleanly engineered defined-risk structure (wing enforced in code, no naked-short path, O(1) gates, held-to-expiry); developer reports the refuting evidence honestly rather than tuning it away

Backtest Review

Structurally unmeasurable: ~3-month option history (data_days 78), 8 trades, effective_daily_obs 4, metrics_reliable=false — headline Sharpe 2.99 is noise

Backtest Review

L67 defined-risk Deribit options: avg_trade_return_pct -5.12% (negative per wing notional) — structural negative per-notional edge

Backtest Review

Developer pre-registers: the overbought gate measures backwards (discards the better weeks), premise refuted at every threshold, and the 30-trade floor is unreachable under the loader

Backtest Review

Named venue (BINANCE_OPTIONS) cannot run — Deribit override doesn't fill the intended bucket; 3-phase validation cannot populate on 8 trades

Iteration History

Verification failed (Layer 3 — sandbox backtest): No trades produced Bar type used: BTC-PERPETUAL.DERIBIT-1-HOUR-LAST-EXTERNAL, Bars processed: 8756 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.

Iteration History

Verification failed (Layer 4 — QA review): - VENUE MISMATCH. The hypothesis is explicitly built to fill the emptiest portfolio bucket — BINANCE_OPTIONS (0.0% / 1 experiment) — and names BINANCE_OPTIONS in title and description. The code runs on DERIBIT (instrument_id BTC-PERPETUAL.DERIBIT). Disclosed override (Binance weeklies can't be backfilled, no BINANCE_OPTIONS catalog data), but the consequences are material: it does NOT fill the intended bucket — it lands in the Deribit options bucket where an iron-condor VRP idea was already abandoned — and fee assumptions differ. The named venue cannot be validated. - UNMEASURABLE TRADE COUNT. Engine loads legs one at a time (~7.3s/leg), forcing a 90-day window (~13 weekly cycles); gate passes ~2/13 → ~2-4 trades. Sandbox confirms total_trades=4, data_days=2, metrics_reliable=false, sharpe unreliable. Clears Layer 3 but is far below the ~30-trade options measurability floor; cannot populate walk-forward or 15-day holdout. Developer concurs ('roughly 2-4 trades — enough for Layer 3, not enough for a walk-forward or holdout'). - CORE EDGE FALSIFIED BY THE CODE'S OWN ANALYSIS. The hypothesis premise is that overbought regimes = most overpriced upside convexity. The developer's own 275-week event study shows the ordering is backwards at every threshold: the gate discards better weeks than it keeps, and the config-matching gated configuration (IV-rank>=0.3 AND overbought) measures NEGATIVE and insignificant (n=35, -0.078%/week, t=-0.23). Unconditional (+0.195%, t=+2.07) and IV-rank-only (+0.298%, t=+1.73) both beat the specified strategy. The gate is faithfully implemented, but the stated edge does not exist in gated form. - Delta drift: hypothesis specifies ~20-25 delta short call / ~10 delta wing; code resolves by fixed % OTM offsets (5%/10%) and the 5% leg is noted as ~0.27 delta, above the 20-25 band.

Iteration History

Verification failed (Layer 4 — QA review): - CORE EDGE FALSIFIED IN GATED FORM — UNCHANGED (iteration 3). The developer's own 275-week event study shows the config-matching gated configuration (IV-rank>=0.3 AND overbought) measures NEGATIVE and insignificant (n=35, -0.078%/week, t=-0.23), while the unconditional (+0.195%, t=+2.07) and IV-rank-only (+0.298%, t=+1.73) beat it. The gate is faithfully implemented but the stated edge does not exist in gated form. Developer concurs and recommends abandon. - VENUE MISMATCH — UNCHANGED. Hypothesis names BINANCE_OPTIONS (to fill the 0.0% bucket); code runs DERIBIT. Fee-neutrality correction accepted (both 0.0300%/0.0300%), but the Deribit run does not populate the intended bucket, which requires a data-engineer Binance chain resolver + historical klines. - TRADE-COUNT FLOOR UNREACHABLE — UNCHANGED. At ~7.3s/instrument x 2 legs, 30 trades needs 208 legs=~1,510s (5x over cap); even gates-off needs ~436s; 300s budget = ~13 cycles = ~4 trades. Sandbox: total_trades=4, data_days=2, metrics_reliable=false. Floor and timeout are mutually exclusive under the one-at-a-time loader. - RESOLVED — delta drift fix accepted. Short leg moved from +5% (~0.276 delta, above band) to +6% (~0.237 delta, mid-band); wing stays +10% (~0.12 delta). Addresses my prior warning.
Strategy report

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