Skip to content

View original

EthDailyOpenInterestPercentileLong

Hypotheses

ETH Daily Open-Interest Percentile Long with 200-SMA Regime Filter

Hypotheses

A long-only single-instrument carry-and-direction strategy on ETHUSDT perpetual futures using daily bars + open-interest data. This is a NEW mechanism class for ETH that uses a fundamentally different signal source than any existing pipeline strategy: OPEN INTEREST PERCENTILE rather than price-derived signals (EMA crosses, breakouts, vol regimes). The thesis: when ETH perp open interest is in the bottom 30% of its trailing 90-day distribution (RELATIVE percentile, NOT absolute threshold) AND ETH is above its 200-day SMA, leveraged-positioning is bearish-skewed (low OI = speculators absent, only structural holders) WHILE the long-term trend is intact. This combination historically resolves with catch-up rallies as positioning normalizes (leveraged longs re-enter, push price higher). The mechanism is structurally different from the failed ETH OI Divergence Contrarian Short (which was a SHORT strategy fading high OI buildup; this is a LONG strategy capturing low-OI bearish-positioning normalization) and from the failed BTC Negative Funding Carry (which used absolute threshold; this uses RELATIVE percentile that self-adapts to current OI regime). Importantly, this proposal directly responds to the recurring analyst recommendation across multiple BNB/SOL daily-trend abandonments: 'a fundamentally different signal mechanism (e.g., funding-rate or open-interest based, not price-only).' This proposal uses OI — exactly the recommended class. ETH-SPECIFIC empirical justification: ETH has the most dynamic OI structure of any crypto major due to (1) ETF inflows since 2024 producing cyclical leverage builds and unwinds, (2) DeFi staking demand creating non-leveraged structural holders distinct from speculative leverage, (3) Layer-2 and re-staking narratives driving leverage cycles. The relative percentile filter captures the regime extremes. Existing ETH strategies in pipeline use price-only signals (Golden Cross, 4H Volume Breakout, Spot Regime Hold). This adds an orthogonal data source. Single-dominant-filter design (OI percentile + 200-SMA), explicitly NOT a multi-condition AND-gate. Calibrated for ~10-20 entries/year via the always-firing percentile filter.

Hypotheses

Iteration 2 fixes the Layer-2 (synthetic) failure '_to_ns() takes 1 positional argument but 2 were given'. Root cause: _to_ns was declared @staticmethod, but the Layer-2 verification proxy rebinds strategy helpers as instance methods and passes self, so the 1-arg staticmethod received 2 args. The minimal fix converts _to_ns from a staticmethod to an instance method (drop @staticmethod, add self); both call sites already invoke it as self._to_ns(...), so no other change is needed. Every other line -- the lazy OI series build, causal O(log n) OI lookup, trailing-percentile computation, 200-SMA bull filter, entry/exit logic, and capital-relative sizing -- is byte-identical to the previous iteration, preserving all Layer-1 checks (clean imports, subclass, methods) that already passed. This is the same recurring gotcha where @staticmethod helpers invoked as self._helper(...) break only under the synthetic proxy.

Hypotheses

ETH daily OI-percentile long fired exactly 1 trade in 4,712 bars (single entry 2026-05-04), with the engine flagging metrics_reliable=false — untestable. Root cause is the same open_interest data-coverage gap that already sank BtcOiSurge and BtcOiSpike this session: the percentile signal requires MIN_OI_SAMPLES (20 daily OI samples) before activating, and only one valid entry occurred across six years, meaning the open_interest supplementary feed has no usable historical coverage and _oi_at() returns None for nearly every bar (the lone 2026-05 trade pins coverage to a recent window, mirroring the BtcOiSpike 2026-04 trade). The headline metrics are noise on n=1 (Sharpe 6.49 with sharpe_ci_low -10.68 / ci_high +19.9, win_rate 1.0, profit_factor 0). Not optimize: a 3-phase optimization (walk-forward 3 windows + 15-day holdout) is impossible on 1 trade. Not iterate: the implementation is correct (causal lookup, multiple OI key-format fallbacks, self-adapting percentile, single-dominant-filter) and the blocker is structural historical OI coverage — a data-engineering backfill task no parameter or code change can fix. FAILURE PATTERN: open-interest-primary signals are currently unbacktestable because the open_interest feed lacks multi-year history (only a recent window is populated), so ANY OI-gated entry fires ~once across the full backtest regardless of mechanism (long low-OI-percentile, short OI-surge, OI-spike reversal — all three abandoned this session for the identical 1-trade signature). The OI mechanism class must be shelved until the OpenInterestCollector backfills historical OI; the analyst's reliable-data-path guidance should explicitly exclude open_interest for historical strategies, and the Research Lead should stop proposing OI-primary hypotheses until the data engineer confirms multi-year coverage.

Implementation

Long-only ETHUSDT daily open-interest-percentile carry-and-direction strategy. Each daily bar it samples open interest causally from supplementary_data['open_interest'], maintains a trailing 90-day distribution, and computes the OI percentile. It enters long when OI is in the bottom oi_entry_percentile (30%) of its 90-day distribution AND the close is above the 200-day SMA (bull regime), betting on a catch-up rally as absent speculative leverage re-enters. It exits on the earliest of close < SMA, OI percentile normalizing to >= 50%, an 8% stop, or a 30-day time stop. Long-only, leverage 1.0. Three tunable parameters: oi_entry_percentile, sma_period, stop_pct.

Verification Results

Verification failed (Layer 2 — synthetic scenarios): Parameters used: ['stop_pct', 'sma_period', 'min_notional', 'oi_entry_percentile'] Check that __init__ sets all attributes from self.parameters.get(). - steady_uptrend: TypeError: EthDailyOpenInterestPercentileLong._to_ns() takes 1 positional argument but 2 were given (bar timestamp: 1735701600000) - steady_downtrend: TypeError: EthDailyOpenInterestPercentileLong._to_ns() takes 1 positional argument but 2 were given (bar timestamp: 1735701600000) - flat_ranging: TypeError: EthDailyOpenInterestPercentileLong._to_ns() takes 1 positional argument but 2 were given (bar timestamp: 1735701600000) - volatility_spike: TypeError: EthDailyOpenInterestPercentileLong._to_ns() takes 1 positional argument but 2 were given (bar timestamp: 1735701600000) - zero_volume: TypeError: EthDailyOpenInterestPercentileLong._to_ns() takes 1 positional argument but 2 were given (bar timestamp: 1735701600000) - price_gap: TypeError: EthDailyOpenInterestPercentileLong._to_ns() takes 1 positional argument but 2 were given (bar timestamp: 1735701600000)

Backtest Review

Clean, correct implementation: causal O(log n) OI lookup, multiple key-format fallbacks, relative-percentile (self-adapting) design, single-dominant-filter to avoid AND-gate starvation

Backtest Review

Sound, genuinely orthogonal thesis (low-OI positioning normalization + bull regime) and a reasonable target firing rate by design

Backtest Review

DECISIVE: only 1 trade in 4,712 bars (single entry 2026-05-04); metrics_reliable=false — the open_interest feed lacks historical coverage, so the percentile signal never activates pre-2026

Backtest Review

Headline metrics meaningless on n=1: Sharpe 6.49 with CI -10.68 to +19.9, win_rate 1.0, profit_factor 0; cannot support walk-forward + holdout optimization

Backtest Review

THIRD OI-primary strategy this session blocked by the identical OI data gap (BtcOiSurge, BtcOiSpike both abandoned) — confirms a structural data-engineering blocker, not a per-strategy issue

Outcome Summary

EthDailyOpenInterestPercentileLong introduced a genuinely orthogonal, non-price mechanism for ETH — buying when open interest sat in the bottom of its trailing percentile distribution within a 200-SMA bull regime, betting on positioning normalization — with a clean, correct implementation (causal OI lookup, self-adapting percentile, single-dominant filter). But it fired exactly one trade in six years because the open_interest feed has no usable historical coverage, leaving the metrics unreliable and the percentile signal inert before 2026. This was the third OI-primary strategy of the session blocked by the identical gap after BtcOiSurge and BtcOiSpike, confirming a structural blocker. The analyst abandoned it on its second iteration as a data-engineering backfill task no code change can fix, recommending the Research Lead stop proposing OI-primary hypotheses until multi-year coverage is confirmed.

Outcome Summary

Open-interest-primary signals are currently unbacktestable because the open_interest feed lacks multi-year history — any OI-gated entry fires roughly once across a full backtest regardless of mechanism (low-OI-percentile long, OI-surge short, OI-spike reversal all abandoned this session for the identical 1-trade signature) — so the OI class must be shelved until historical OI is backfilled.

Outcome Summary

The analyst abandoned it at the backtest-review gate before optimization because of the same open_interest data-coverage gap that had already sunk two OI-primary strategies this session: the percentile signal needs ≥20 daily OI samples to activate, but the feed has no usable multi-year history, so the OI lookup returned nothing for nearly every bar and only one valid entry ever occurred — a structural data-engineering blocker, not a strategy flaw.

Outcome Summary

A long-only, single-instrument ETHUSDT daily strategy using open interest as the primary signal — entering long when ETH perp OI sat in the bottom 30% of its trailing 90-day percentile distribution (a self-adapting relative threshold signaling speculative leverage absent) while price held above its 200-day SMA, exiting on a trend break, OI normalization, stop, or time stop, as a deliberately orthogonal, non-price mechanism for ETH per recurring analyst guidance.

Outcome Summary

It was effectively untestable: the signal fired exactly 1 trade across 4,712 bars (a single entry on 2026-05-04), with the engine flagging metrics_reliable=FALSE and the headline metrics meaningless on n=1 (Sharpe 6.49 with a CI of -10.68 to +19.9, win rate 1.0, profit factor 0, total return 0.82%).
Strategy report

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