Skip to content

View translation

EthBtcRelativeStrengthMomentumPair

Hypotheses

ETH-vs-BTC Relative-Strength Momentum Pair — Dollar-Neutral Long-Short on the ETH/BTC RATIO: Ride the CONTINUATION of Relative-Strength Trends (LONG ETH / SHORT BTC When ETH Is Out-Trending BTC, Reverse When It Is Under-Trending, Flat in the Neutral Band), Held Days-to-Weeks (Multi-Instrument, OHLCV-Only, Market-Neutral)

Hypotheses

A DOLLAR-NEUTRAL, 2-LEG LONG-SHORT strategy that trades TIME-SERIES MOMENTUM of the ETH/BTC price ratio, directly exploiting an empirically CONFIRMED finding from this factory's own failure log: the beta-hedged BTC/ETH spread was abandoned because it CONTINUES rather than mean-reverts (the residual had continuation sign, not reversion). If the spread continues, then relative-strength momentum on the ratio is the correct-sign trade. The strategy computes the ETH/BTC ratio from the two perps' closes and takes a market-neutral position aligned with the ratio's own trend: LONG ETHUSDT.BINANCE + SHORT BTCUSDT.BINANCE (equal dollar notional) when ETH is out-trending BTC, and the REVERSE (SHORT ETH + LONG BTC) when ETH is under-trending BTC; flat in a neutral dead-band to avoid chop. Because the two legs are equal dollar notional the aggregate crypto-market beta is ≈0 — the PnL is the relative performance of ETH vs BTC, not market direction. This is NOT the single-name dual-TF momentum strategy (that bets on one asset's absolute direction) and NOT the 9-name cross-sectional factor (that ranks a basket); it is a single, focused, most-liquid relative-value pair. Uses ONLY OHLCV bars for the two most liquid crypto perps (deep multi-year history, zero data fragility, no funding/tick/liquidation/options feeds).

Hypotheses

ITERATION 3 IS A CONFIG-ONLY FIX. Layer 1 rejected the previous submission with "config.instrument_id and config.bar_type are REQUIRED (got instrument_id=None, bar_type=None)" - the strategy code was never the problem (iteration 2 had already cleared static analysis and the synthetic layer and reached the sandbox, which is what its O(1) rolling-stats / cached-book / scheduled-rehedge performance rewrite was for), the accompanying config block simply arrived without its two required fields so nothing could be instantiated. I made the SMALLEST change that fixes exactly that: the config below now carries an explicit primary instrument (ETHUSDT.BINANCE), an explicit primary bar type (ETHUSDT.BINANCE-4-HOUR-LAST-EXTERNAL), BTCUSDT.BINANCE as the single extra leg on the SAME 4-HOUR bar type - so the base templates cross-leg alignment barrier guarantees both legs are contemporaneous at every decision, never a stale T-1 hedge - and every tunable with its _param_bounds mirroring the clamps the code applies, so the optimizer never searches values the code silently rewrites. Both symbols have continuous 4-HOUR catalog history from 2019-12-31, so neither leg can go data_unavailable. The only code edit is the docstring, which records this cause and fix and clarifies that mom_days/vol_window are counts of PRIMARY BARS (on 4-HOUR bars the defaults are a 5-day trend measured against 10 days of ratio volatility, giving the days-to-weeks holds the hypothesis specifies); no signal, entry, exit, sizing or performance logic was touched, so the layers that already passed stay passing. HYPOTHESIS FIDELITY: the mechanism is momentum (continuation) on the ratio, the correct-sign trade implied by this factorys own finding that the beta-hedged BTC/ETH spread continues rather than mean-reverts; equal DOLLAR notional per leg (not equal base quantity) is what makes aggregate market beta ~0, so the PnL is ETH-vs-BTC relative performance rather than market direction. BINANCE futures is the correct venue because the strategy genuinely shorts; leverage stays 1.0 because gross exposure is 0.70 of equity (0.35 per leg) with net delta ~0, so no margin amplification is used or claimed.

Hypotheses

Not worth 2 hours of optimization. The relative-strength continuation edge is present only in 2020-2021 (which supplies the entire +44.7% headline) and is measurably absent on the recent adequate sample: 2022-2026 nets ~-1.7% across ~4.5 years. Full-sample Sharpe is 0.23 with a bootstrap CI [-0.48, 0.99] straddling zero and PSR 0.69, i.e. indistinguishable from no-skill; PF is 1.046 (weak signal, not a fee problem — commissions are only 4.56% of gross). The edge also lives in a single vol regime (only 'normal' tercile positive; calm and stressed both negative). Optimizing over the full window would curve-fit to the dead 2020-2021 regime and walk-forward OOS on recent windows would be negative. This is not a code bug (so not iterate) and the most-liquid pair is already the best target for this mechanism (so not revise_hypothesis).

Implementation

Dollar-neutral 2-leg long/short pair that trades TIME-SERIES MOMENTUM of the ETH/BTC ratio on 4-HOUR Binance USD-M perps. Each bar it computes ratio = close(ETHUSDT)/close(BTCUSDT), then a z-score of the ratios own trend: mom = log(ratio_t / ratio_{t-30 bars}) divided by the 60-bar stdev of bar-to-bar log-ratio returns scaled to the momentum horizon. When the z-score exceeds +entry_z it goes LONG ETH / SHORT BTC at EQUAL DOLLAR notional (leg_frac of equity each, quantity = notional / that legs own price); below -entry_z it takes the reverse; it holds until |z| falls under entry_z * exit_frac (hysteresis dead-band) and flips directly on a sign crossing. Risk: a hard pair-level stop on the summed unrealized return of the two legs (the adverse ratio move since entry) with a re-entry lock until the signal cools back inside the dead-band, a naked-leg guard that flattens if only one leg is open, and a calendar-scheduled rehedge that trims the drifted leg back to dollar-neutral. OHLCV only - no funding, tick, liquidation or options feeds.

Verification Results

Verification failed (Layer 1 — config): config.instrument_id and config.bar_type are REQUIRED (got instrument_id=None, bar_type=None). Set both to the hypothesis's instrument, e.g. instrument_id='BTCUSDT.BINANCE', bar_type='BTCUSDT.BINANCE-4-HOUR-LAST-EXTERNAL'.

Verification Results

Optionally assert self._btc_ts == ts_ns before pushing the ratio to make contemporaneity explicit in-strategy.

Verification Results

BTC leg is buffered in on_extra_bar and paired with the ETH close only once the base template's same-timeframe alignment barrier confirms a contemporaneous BTC bar. Correct in practice; noted only as a data-gap robustness consideration, not a defect.

Backtest Review

Trades implement the hypothesis faithfully: balanced dollar-neutral pair (389 long / 389 short legs), avg hold 3d10h, benchmark_meaningful=false as expected for a market-neutral book.

Backtest Review

Low drawdown (14.5%) and fees are not the problem (commission_pct_of_gross only 4.56%).

Backtest Review

Positive whole-sample expectancy (+$49.7/trade) and avg_trade_return_pct 0.286% technically clears the 0.15% floor.

Backtest Review

Sharpe 0.23 with bootstrap CI [-0.48, 0.99] straddling zero and PSR 0.69 (<0.95) — over 6.7 years the edge is statistically indistinguishable from zero.

Backtest Review

Edge is entirely front-loaded: 2020 +25.7% and 2021 +12.7% carry the whole 44.7% return, while 2022-2026 (the most recent ~4.5 years) net roughly -1.7% — the ETH/BTC relative-momentum continuation edge has decayed.

Backtest Review

PF 1.046 is a very thin gross edge; this is weak signal, not fee drag.

Backtest Review

Regime-fragile: only the 'normal' vol tercile is positive (Sharpe +0.98); calm (-0.16) and stressed (-0.03) are both negative, only_one_regime=true.

Backtest Review

Beta/dollar-neutral major-perp long-short (multi_instrument/market_neutral) class has no survivors historically.

Iteration History

Verification failed (Layer 2 — synthetic scenarios): Parameters used: ['entry_z', 'leg_frac', 'mom_days', 'stop_pct', 'exit_frac', 'vol_window', 'min_notional', 'rehedge_band', '_param_bounds', 'default_qty_precision'] Check that __init__ sets all attributes from self.parameters.get(). - steady_uptrend: TypeError: EthBtcRelativeStrengthMomentumPair._symbol() takes 1 positional argument but 2 were given (bar timestamp: 1735697220000) - steady_downtrend: TypeError: EthBtcRelativeStrengthMomentumPair._symbol() takes 1 positional argument but 2 were given (bar timestamp: 1735697220000) - volatility_spike: TypeError: EthBtcRelativeStrengthMomentumPair._symbol() takes 1 positional argument but 2 were given (bar timestamp: 1735697040000) - zero_volume: TypeError: EthBtcRelativeStrengthMomentumPair._symbol() takes 1 positional argument but 2 were given (bar timestamp: 1735699500000) - price_gap: TypeError: EthBtcRelativeStrengthMomentumPair._symbol() takes 1 positional argument but 2 were given (bar timestamp: 1735697220000)

Iteration History

sandbox_timeout: Verification failed (Layer 3 — sandbox backtest): smoke test exceeded the 300s wall-clock limit on a ~20000-bar window (2400 days of ETHUSDT.BINANCE-1-DAY-LAST-EXTERNAL). 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).
Strategy report

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