Skip to content

View translation

EthBtcRatioReversionFundingSkewLS

Hypotheses

ETH/BTC Ratio Reversion Confirmed by Funding-Skew Divergence, Long-Short Pair (BINANCE USD-M, Same-Venue 2-Leg, 4H Bars — Fade Stretched ETH-vs-BTC Ratio ONLY When the Funding Differential Agrees the Stretched Leg Is Crowded, 3-Parameter)

Hypotheses

A LONG-SHORT, dollar-neutral FIXED-PAIR relative-value strategy on the two deepest crypto perps — ETHUSDT.BINANCE and BTCUSDT.BINANCE (both USD-M, same venue) — that fades extremes in the ETH/BTC price RATIO, but only when a genuine NON-PRICE feed confirms the extreme is crowd-driven: the ETH-minus-BTC 8h FUNDING differential. Deliberately structured to dodge the graveyards this session: it is NOT a cross-sectional N-name rotation (L12 — those pay 2N fills and die fee_edge; this is a single fixed pair, 4 fills/cycle, and I state the arithmetic below), NOT a cross-venue/cross-margin delta-neutral funding-spread arb (L1/L28 — this is same-venue directional ratio reversion, funding is a CONFIRMATION filter, not the return source), NOT a funding-EXTREME direction bet on a single major (L13 — the return comes from ratio mean-reversion, not from the funding level itself), and NOT pure-OHLCV (L30 — the entry REQUIRES the funding-differential feed as a mandatory gate). It combines two mechanisms that have survived to paper in this factory — mean-reversion (the deployed SOL VWAP reversion) and a funding-based non-price signal (the deployed negative-funding carry basket) — in a fixed-pair form that fills THREE under-represented buckets at once: long-short direction (14.3% vs push), pairs scope (13.5% vs 15% target), and a genuine relative-value mechanism the single-name-heavy portfolio (68%) lacks. Economic thesis: the ETH/BTC ratio mean-reverts, but naked ratio-fades get run over when a real regime rotation is underway; requiring the funding differential to confirm the stretched leg is over-crowded (rich funding on the expensive leg / deep-negative funding on the cheap leg) filters ratio moves driven by leveraged positioning (which revert) from those driven by genuine spot-led rotation (which persist). 3 parameters only, to fight overfit (#1 killer, 229x) and verification_loop drift (the mechanism is unambiguous: ratio z-score + funding-diff sign gate).

Hypotheses

I traced the zero-trade failure to the data plumbing rather than guessing at thresholds, and confirmed the entry logic was never the problem. Root cause: the strategy read the funding differential only from funding_rates_by_instrument, which is built exclusively on the supp_spec path (supp_collector.load_for_subprocess). backtest_agent.py passes supp_spec at lines 222 and 359, so the FULL backtest gets it — but the Layer-3 sandbox call at pipeline_processor.py:2892 passes supplementary_data=merged_supp with NO supp_spec, and the key appears in neither PipelineProcessor.SUPP_KEYS nor generate_synthetic_supplementary. merged_supp was therefore empty, _resolve_supp returned {}, fd was None on every bar, and the mandatory gate rejected all 14,387 entries. The strategy could pass the real backtest but never Layer 3. The fix keeps the differential as the preferred source and adds the flat funding_rates series — which IS in SUPP_KEYS and does have a synthetic generator — as the primary leg's backfill, with two explicitly labelled modes: PAIRED (eth - btc, the true differential, used whenever both legs are wired) and SINGLE-LEG (eth minus the causal mean of its last fund_mean_n prints) when only the primary series exists. The single-leg form is the hypothesis's own parenthetical statement of the gate, 'rich funding on the expensive leg / deep-negative funding on the cheap leg', measured against ETH's own norm; the sign semantics and the crowding meaning are identical, the return source stays ratio mean-reversion, and self._fd_mode records which mode is active so the degradation is visible rather than silent. With no funding at all fd is still None and nothing trades — the gate remains mandatory, with no price-only fallback. I validated both gate forms on the real aligned series (14,628 four-hour bars, 2019-12 to 2026-09, ETH/BTC funding from data/supplementary/fundingRate): the true differential yields 1,633 entry-eligible bars at entry_z=1.6 (914 at 2.0) and the single-leg form 2,165 (1,155), so trades will fire under either. Everything that already passed is untouched: imports unchanged, the continuous z signal, the causal searchsorted lookups with no abs() matching, the dollar-matched hedge leg and paired exit. I also added clamps with a matching _param_bounds block. NOTE for the operator: this is the second strategy this session blocked by the same gap — the sandbox cannot see any per-leg supplementary map. Routing verification through supp_spec, or adding funding_rates_by_instrument to SUPP_KEYS, would unblock every multi-leg funding strategy at once.

Hypotheses

Negative-expectancy funding-gated ETH/BTC ratio-reversion pair — not worth 2 hours of optimization. Over 690 trades in 6 years: avg_trade_return_pct -0.076% (negative), profit_factor 0.90, expectancy -$52/trade, total_return -41.1% (CAGR -6.5%), losing in five of seven years (2020 -22.6%, 2021 -8.8%, 2022 -3.1%, 2023 -8.0%, 2024 -7.9%) with only 2025/2026 positive. It is decisively poor: Sharpe -0.22 (CI [-0.96, 0.44]), PSR 0.335, and a 49.5% drawdown (CI to 77.5%) on a supposedly market-neutral book, with negative Sharpe in the calm and normal vol terciles. The book is cleanly built and the funding gate works (7,981 events resolved, not a data defect), but the mechanism — fading the ETH/BTC ratio with funding confirmation — simply loses net of the four-fill round trip (commission 4.97% of gross), and the funding gate does not turn it positive. This is the L55/L57 pairs/ratio mean-reversion family; benchmark_meaningful is correctly false. No tuning of z-thresholds converts a negative per-trade edge that loses in most regimes into an edge. Failure pattern: no_edge/fee_edge ratio-reversion pair, negative per-trade and negative most years (L55/L57).

Implementation

Dollar-neutral long-short relative-value pair on the two deepest USD-M perps, ETHUSDT.BINANCE and BTCUSDT.BINANCE, on 4-hour bars. The signal is the z-score of log(ETH/BTC) over a rolling lookback. When the ratio is stretched high (z >= entry_z) AND the funding gate confirms ETH is the crowded long (funding differential > 0), it shorts ETH and buys an equal USD notional of BTC; when stretched low (z <= -entry_z) with the differential negative (crowded ETH shorts), it does the reverse. The funding confirmation is mandatory — it separates positioning-driven stretches, which revert, from spot-led rotations, which persist — and the strategy stands aside entirely when no funding data is available. Both legs carry matched USD notional so the book is dollar-neutral, and the pair exits together on mean reversion (|z| <= exit_z) or a z-blowout stop (|z| >= stop_z).

Verification Results

Verification failed (Layer 3 — sandbox backtest): No trades produced Bar type used: ETHUSDT.BINANCE-4-HOUR-LAST-EXTERNAL, Bars processed: 14391 Diagnostics: should_enter() returned a side 0 times over 14387 evaluated bars -> your ENTRY CONDITION never triggered. Loosen the entry logic / thresholds. Ensure your strategy produces trades with the given data and parameters.

Backtest Review

Clean, genuinely dollar-neutral same-venue 2-leg construction with a mandatory funding-differential gate (not pure OHLCV); adequate sample (690 trades) and funding correctly resolved (7,981 events)

Backtest Review

Recent two years turned positive (2025 +4.6%, 2026 +5.3%)

Backtest Review

Negative expectancy: avg_trade_return_pct -0.076% (net negative), profit_factor 0.90, expectancy -$52/trade

Backtest Review

Loses across the full sample: total_return -41.1% (CAGR -6.5%), negative in 2020 (-22.6%), 2021 (-8.8%), 2022 (-3.1%), 2023 (-8.0%), 2024 (-7.9%) — only the last two years positive

Backtest Review

Not significant / decisively poor: Sharpe -0.22 (CI [-0.96, 0.44]), PSR 0.335, max_drawdown 49.5% (CI to 77.5%) on a supposedly market-neutral book; negative Sharpe in calm and normal vol terciles

Backtest Review

L55/L57 ratio/pairs mean-reversion family — the funding gate does not rescue a negative net-of-cost edge (commission 4.97% of gross)

Iteration History

Verification failed (Layer 2 — synthetic scenarios): Parameters used: ['exit_z', 'stop_z', 'entry_z', 'leg_frac', 'lookback', 'min_notional'] Check that __init__ sets all attributes from self.parameters.get(). - steady_uptrend: TypeError: FactoryStrategy._bar_ts() takes 1 positional argument but 2 were given (bar timestamp: 1735689840000) - steady_downtrend: TypeError: FactoryStrategy._bar_ts() takes 1 positional argument but 2 were given (bar timestamp: 1735689840000) - flat_ranging: TypeError: FactoryStrategy._bar_ts() takes 1 positional argument but 2 were given (bar timestamp: 1735689840000) - volatility_spike: TypeError: FactoryStrategy._bar_ts() takes 1 positional argument but 2 were given (bar timestamp: 1735689840000) - zero_volume: TypeError: FactoryStrategy._bar_ts() takes 1 positional argument but 2 were given (bar timestamp: 1735689840000) - price_gap: TypeError: FactoryStrategy._bar_ts() takes 1 positional argument but 2 were given (bar timestamp: 1735689840000)

Iteration History

Verification failed (Layer 2 — synthetic scenarios): Parameters used: ['exit_z', 'stop_z', 'entry_z', 'leg_frac', 'lookback', 'min_notional'] Check that __init__ sets all attributes from self.parameters.get(). - steady_uptrend: TypeError: EthBtcRatioReversionFundingSkewLS._sorted_series() takes 1 positional argument but 2 were given (bar timestamp: 1735689840000) - steady_downtrend: TypeError: EthBtcRatioReversionFundingSkewLS._sorted_series() takes 1 positional argument but 2 were given (bar timestamp: 1735689840000) - flat_ranging: TypeError: EthBtcRatioReversionFundingSkewLS._sorted_series() takes 1 positional argument but 2 were given (bar timestamp: 1735689840000) - volatility_spike: TypeError: EthBtcRatioReversionFundingSkewLS._sorted_series() takes 1 positional argument but 2 were given (bar timestamp: 1735689840000) - zero_volume: TypeError: EthBtcRatioReversionFundingSkewLS._sorted_series() takes 1 positional argument but 2 were given (bar timestamp: 1735689840000) - price_gap: TypeError: EthBtcRatioReversionFundingSkewLS._sorted_series() takes 1 positional argument but 2 were given (bar timestamp: 1735689840000)
Strategy report

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