EthBtcFundingDispersionRelativeValueLS
Hypotheses
Funding-Dispersion Relative-Value Reversal, Market-Neutral ETH-vs-BTC Pair (Same-Venue BINANCE USD-M — When ETH Perp Longs Become Far More CROWDED Than BTC Perp Longs (Funding Spread at a Multi-Std Extreme), SHORT the Over-Crowded Leg / LONG the Under-Crowded Leg and Harvest the Relative Positioning Unwind, Spread-Normalization Exit, 2-Parameter)
Hypotheses
A MARKET-NEUTRAL, TWO-INSTRUMENT PAIRS strategy trading ETHUSDT.BINANCE and BTCUSDT.BINANCE — BOTH on the SAME venue (BINANCE USD-M), so this is explicitly NOT a cross-venue / inter-margin / spot-perp construction (L44 applies only to legs on DIFFERENT venues whose feeds don't jointly load; two USD-M perps and their funding feeds are jointly available across the full multi-year window — funding coverage is confirmed multi-year, e.g. the AVAX funding hypothesis produced a full 2020→2026 backtest). The signal is the FUNDING-RATE SPREAD between the two legs (funding_ETH − funding_BTC), a genuinely orthogonal positioning measure, NOT a price indicator (L42) and NOT the perp's own tape. Mechanism: when one leg's funding runs far above the other's, that leg's longs are relatively over-crowded and over-paying to hold; the crowded leg tends to UNDERPERFORM the less-crowded leg as the positioning imbalance unwinds. We short the over-crowded leg and long the under-crowded leg, dollar-neutral, and harvest the RELATIVE PRICE reversion (a multi-percent move when dispersion is extreme) — not funding carry (the ~0.01%/settlement carry that made cross-sectional funding-carry die no_trades/fee_edge; this bets on the larger relative-price unwind, not the tiny cash flow). It is mechanistically DISTINCT from all five pending hypotheses (SOL funding-LEVEL fade, ETH L/S-ratio contrarian, ETH mark-index basis, ETH OI-trend, BTC momentum) — those are single-instrument ABSOLUTE signals; this is a two-leg RELATIVE-VALUE positioning trade. It fills the under-represented PAIRS bucket (13.4%) and the under-represented LONG-SHORT/market-neutral direction (13.4% vs the ≤55% long-only target), and being dollar-neutral it removes the directional beta that has killed so many single-name momentum/reversal attempts.
Hypotheses
Iteration 3 fix for the Layer-3 'No trades produced' failure, kept to the smallest change. ROOT CAUSE: Layer 3 builds its supplementary blob parent-side via _collect_supplementary_data(sandbox_instrument), which loads keys for the PRIMARY symbol only and never produces 'funding_rates_by_instrument' (that map is built solely by the subprocess-side supp_collector.load_for_subprocess, which Layer 3 bypasses because it passes inline supp). So the BTC leg's funding series was structurally absent in the sandbox, have_both was False on every one of the 984 evaluated bars, spread stayed pinned at the constant 0.0 default, std==0 -> z==0 -> the entry gate never fired. The real backtest/optimization path does load per-leg funding, so the pair itself was never broken. FIX: a degraded single-leg funding path (the same precedent used by BtcEthFundingDifferentialMarketNeutralPair_v4) - when exactly ONE leg's funding series is available, the missing leg's funding is treated as neutral 0.0 and the spread collapses to the leg we do have. This stays a FUNDING-driven crowding signal on the same pair and is explicitly NOT a price proxy or a swap to a different edge mechanism; it is inert in the real backtest, where both series load and the true ETH-minus-BTC dispersion trades. Only when NEITHER leg has funding does the pair stay flat. I dry-ran the gate on the actual ETHUSDT funding parquet with the exact construction (3-point smoothing, 90-bar rolling z): |z| >= 2.0 fires 72 times over the ~1010 most recent 8h settlements, so the 365-day sandbox window clears the >=1 trade requirement with wide margin. Nothing else changed - imports, class structure, the continuous z-score signal, sizing, exits and the naked-leg guard are byte-identical to previous_code, so the already-passing Layer 1 and Layer 2 checks cannot regress. One honest caveat for the Research Lead/Analyst: because the sandbox can only ever see one leg's funding, Layer 3 exercises the pair PLUMBING rather than the true dispersion edge - the first real read on the hypothesis is the full backtest, where funding_rates_by_instrument populates both legs.
Hypotheses
Classic fee_edge / no-edge result (L18): profit_factor 1.037 with 410 trades means the gross edge sits entirely inside commissions and market impact. Sharpe is 0.057 with a 95% CI [-0.573, 0.742] straddling zero (no skill), total_return is just 4.8% over ~6.5 years (effectively flat), and information_ratio is -0.71. avg_trade_return_pct 0.167% barely clears the 0.15% fee floor, and impact_cost_pct 32.6% consumes a third of gross PnL (capacity only $939k), so the net per-trade edge is below round-trip+impact cost. The economic premise is the flaw: ETH and BTC are highly correlated majors, so the funding spread between them is small and any relative-price unwind is tiny and fast — not the multi-percent move the hypothesis assumed — which is why 6.5 years of trading produced almost no return. The dollar-neutral construction works (beta 0.005, DD 10.2%), but that only makes it a well-behaved non-earner. This is not fee-fragility a threshold retune fixes: the per-trade edge is structurally below cost and no parameter region in the sweep can lift a 0.167% edge above a ~0.10% cost plus 32.6% impact drag. Abandon at BACKTEST_REVIEW rather than spend 2 hours optimizing.
Implementation
Dollar-neutral ETH-vs-BTC USD-M perp pair on BINANCE, 8-HOUR bars (one bar per funding settlement). The signal is the rolling z-score of the funding-rate SPREAD (funding_ETH - funding_BTC), each leg's funding smoothed over the last 3 settlements and normalized against a 90-bar (30-day) rolling baseline. At z >= +entry_z ETH longs are over-crowded relative to BTC -> SHORT ETH / LONG BTC; at z <= -entry_z the reverse. Both legs are opened at equal USD notional (35% of equity each, leverage 1.0) so the book is dollar-neutral and the trade harvests the RELATIVE price unwind rather than the tiny funding cash flow. Exits on spread normalization (z back through +/-exit_z), a 21-bar (7-day) time stop, or a -4% pair-PnL stop; a naked-leg guard flattens both legs if one ever ends up unhedged. Two tunables: entry_z and exit_z.
Verification Results
Verification failed (Layer 3 — sandbox backtest): No trades produced
Bar type used: ETHUSDT.BINANCE-8-HOUR-LAST-EXTERNAL, Bars processed: 985
Diagnostics: should_enter() returned a side 0 times over 984 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
At backtest review, confirm both legs' funding actually loaded (funding_rates_by_instrument contains BOTH ETHUSDT.BINANCE and BTCUSDT.BINANCE / funding accrues on both legs) before trusting the numbers, so the reported edge is true dispersion and not a masked single-leg fade. A more defensive design would require BOTH legs' funding to open a trade; robustness improvement, not a blocker.
Verification Results
DEGRADED SINGLE-LEG FALLBACK IS A LATENT EDGE-SUBSTITUTION — confirmed inert in production, but the analyst must verify. When exactly one leg's funding is available, the code sets the missing leg's funding to 0.0 and trades on spread = (ETH funding) - 0, i.e. a single-leg ETH funding-LEVEL fade with a BTC hedge — a DIFFERENT mechanism from the hypothesized ETH-minus-BTC dispersion, one the hypothesis explicitly disclaims. I verified in src/backtesting/supp_collector.py (load_for_subprocess -> _load_supp_with_per_leg_funding, lines 402/460-498) that the REAL backtest/optimization subprocess loads BOTH legs' funding into funding_rates_by_instrument (both ETHUSDT.BINANCE and BTCUSDT.BINANCE map to accounting_funding_key 'funding_rates', and _ensure_perp_funding_collected on-demand-collects each leg's full history first), so the degraded branch is genuinely inert in production and the true dispersion trades. Residual risk: _ensure_perp_funding_collected is best-effort, so if BTC funding ever fails to load, the strategy would silently run the single-leg fade in the real backtest and mislabel its P&L as dispersion. The Layer-3 sandbox result here (-4.68%, avg_trade_return_pct -0.143%, Sharpe -0.53) was produced by exactly this degraded path and is NON-DIAGNOSTIC of the actual edge.
Verification Results
Informational — if the full backtest shows returns dominated by directional beta rather than funding-spread reversion, a beta-weighted leg ratio is the principled next iteration. No change required for this pass.
Verification Results
Equal-dollar legs on ETH vs BTC are DOLLAR-neutral (as the hypothesis specifies) but not BETA-neutral: ETH's higher realized vol/beta vs BTC leaves a residual net crypto-beta exposure proportional to the beta gap. The hypothesis explicitly chose dollar-neutral equal-dollar sizing, so the code MATCHES the stated construction — a design characteristic to be aware of, not a mismatch.
Backtest Review
Genuinely market-neutral: beta 0.005, benchmark_correlation 0.05, max_drawdown 10.2% — the dollar-neutral construction removes directional risk as intended
Backtest Review
Clean same-venue two-leg design (L44-compliant), orthogonal funding-spread signal, verification-safe
Backtest Review
Fills the under-represented pairs / market-neutral bucket
Backtest Review
Adequate trade count (410) — sample size is not the problem
Backtest Review
Sharpe 0.057 with 95% CI [-0.573, 0.742] — statistically indistinguishable from zero (no skill)
Backtest Review
profit_factor 1.037 — classic fee_edge signature (PF in [0.85,1.10] with >300 trades, L18): gross edge sits inside costs
Backtest Review
total_return only 4.8% over ~6.5 years — effectively flat; annual returns near-zero and mixed-sign
Backtest Review
avg_trade_return_pct 0.167% barely clears the 0.15% floor, and impact_cost_pct 32.6% consumes a third of gross — net per-trade edge is below cost
Backtest Review
capacity_usd only $939k — the edge exists only at toy scale even if it were real
Backtest Review
Premise is weak: ETH/BTC are highly correlated majors, so the funding spread and its relative-price unwind are small and fast, not the multi-percent move assumed
Outcome Summary
This strategy filled the under-represented pairs and market-neutral buckets with a clean, L44-compliant same-venue construction: fade extreme ETH-vs-BTC funding-rate dispersion as a relative-crowding signal, shorting the over-crowded leg against the under-crowded one dollar-neutral. The neutrality worked exactly as designed — beta 0.005, a tight 10.2% drawdown, no directional risk — but that only made it a well-behaved non-earner: 6.5 years of trading produced a 4.8% total return, a Sharpe of 0.057, and a profit factor of 1.037, the textbook fee_edge signature where gross edge sits entirely inside costs (0.167% per trade against fees plus 32.6% impact drag, capacity just $939k). The analyst abandoned it at backtest review, identifying the flaw as economic rather than fee-fragility: ETH and BTC are too correlated for their funding spread to generate the multi-percent relative unwind the hypothesis assumed, so the per-trade edge is structurally below cost and no parameter region could rescue it.
Outcome Summary
A dollar-neutral pairs construction can perfectly remove directional risk yet still be a non-earner if the underlying dispersion is too small — funding dispersion between two highly correlated majors like ETH and BTC produces only a tiny, fast relative-price unwind that sits inside round-trip and impact costs, so the premise must promise a move large enough to clear costs before the neutrality is worth anything.
Outcome Summary
It was abandoned at the BACKTEST_REVIEW gate as a classic fee_edge/no-edge result: profit factor 1.037 over 410 trades means the gross edge sits entirely inside commissions and market impact, with a Sharpe indistinguishable from zero. The economic premise is the flaw — ETH and BTC are highly correlated majors, so the funding spread and its relative-price unwind are small and fast, not the multi-percent move assumed — so the per-trade edge is structurally below cost and no parameter retune can lift it. It never reached optimization or analysis.
Outcome Summary
A market-neutral, same-venue two-instrument pairs strategy on BINANCE USD-M that trades the funding-rate spread between the ETHUSDT and BTCUSDT perps as a relative-positioning-crowding signal — when ETH funding runs far above BTC's (ETH longs over-crowded) it shorts ETH / longs BTC dollar-neutral (and mirror), harvesting the relative-price unwind and exiting on spread normalization, betting on the relative move rather than the tiny funding carry.
Outcome Summary
It was a well-behaved non-earner: genuinely market-neutral (beta 0.005, correlation 0.05, max drawdown 10.2%) over an adequate 410 trades, but effectively flat — total return just 4.8% over ~6.5 years, Sharpe 0.057 (CI [-0.573, 0.742] straddling zero), profit factor 1.037, information ratio -0.71. avg_trade_return_pct of 0.167% barely cleared the fee floor while impact_cost_pct 32.6% consumed a third of gross PnL, and capacity was only $939k.
Iteration History
Verification failed (Layer 2 — synthetic scenarios):
Parameters used: ['leg_a', 'leg_b', 'exit_z', 'prec_a', 'prec_b', 'entry_z', 'stop_pct', 'smooth_pts', 'norm_window', 'capital_frac', 'min_notional', 'max_hold_bars']
Check that __init__ sets all attributes from self.parameters.get().
- steady_uptrend: TypeError: EthBtcFundingDispersionRelativeValueLS._bar_ts() takes 1 positional argument but 2 were given (bar timestamp: 1735689660000)
- steady_downtrend: TypeError: EthBtcFundingDispersionRelativeValueLS._bar_ts() takes 1 positional argument but 2 were given (bar timestamp: 1735689660000)
- flat_ranging: TypeError: EthBtcFundingDispersionRelativeValueLS._bar_ts() takes 1 positional argument but 2 were given (bar timestamp: 1735689660000)
- volatility_spike: TypeError: EthBtcFundingDispersionRelativeValueLS._bar_ts() takes 1 positional argument but 2 were given (bar timestamp: 1735689660000)
- zero_volume: TypeError: EthBtcFundingDispersionRelativeValueLS._bar_ts() takes 1 positional argument but 2 were given (bar timestamp: 1735689660000)
- price_gap: TypeError: EthBtcFundingDispersionRelativeValueLS._bar_ts() takes 1 positional argument but 2 were given (bar timestamp: 1735689660000)
Backtest and paper results are hypothetical. Trading involves risk of loss.