Skip to content

View translation

BtcFourHourOiDeclinePriceStabilizationLong

Hypotheses

BTC 4H Open-Interest Decline-Plus-Price-Stabilization Long with Daily Bull Regime Filter

Hypotheses

A long-only single-instrument OPEN-INTEREST-BASED CONTRARIAN strategy on BTCUSDT perpetual futures using 4-hour bars + open_interest supplementary data, with a daily-bar bull regime filter. This proposal SPECIFICALLY ADDRESSES the analyst's just-documented 'walk-forward-incompatible signal density' failure pattern: by using 4H timeframe instead of daily, the expected signal frequency is multiplied by 6× compared to my prior daily supplementary-data proposals (funding rate, liquidations). Combined with a less-restrictive trigger condition, this strategy targets 30-60 trades per year — well above the analyst's ~30-trades-over-backtest threshold for walk-forward viability. This is the THIRD supplementary-data strategy class (companion to BtcDailyFundingRateExtremeNegativeSqueezeLong and BtcDailyLongLiquidationSpikePostCapitulationLong), covering a fundamentally different signal: funding rates measure forward-looking carry costs; liquidations measure backward-looking forced flows; open interest measures the CURRENT STATE of leveraged positioning. The economic mechanism: when BTC perpetual open interest drops sharply over 24-48 hours (signaling leverage unwind via either liquidations OR voluntary position closing), AND price stabilizes (the 4H close is within 1% of the 4H low of the prior 8 bars), this signals (a) leverage has been flushed from the market, (b) selling pressure has dried up (price found a floor), (c) the next leveraged-long entries can drive recovery without facing the prior leverage overhang. This is mechanistically DISTINCT from every existing strategy: not a price-action signal (BB/RSI/Vol Breakout), not a funding-cost signal, not a discrete liquidation event — it's a POSITIONING-STATE signal that confirms market structure has lightened. The combination requirement (OI decline + price stabilization) prevents catching a falling knife: OI alone could decline during continuing crashes; price-stabilization filter requires the decline to have HALTED. 4H timeframe is critical for signal density: OI drops can occur over 1-3 days, and combined with price-stabilization filter, this gives meaningful signal frequency on 4H. BTC is chosen because: (a) BTC has the most reliable OI data via Binance futures API, (b) BTC's 4H data path is empirically the most-cached, (c) BTC's OI is dominated by institutional+retail mix where deleveraging signals are economically meaningful. Only 4 explicit parameters (OI lookback, OI decline threshold, stabilization window, stop pct).

Hypotheses

Iteration 5 after two consecutive Layer-3 'No trades produced' failures, and the root cause was a wrong field name rather than a threshold — which is why iteration 4's loosening of every gate changed nothing (0 entries over the same 14,205 bars). _ensure_oi read sumOpenInterest / sumOpenInterestValue, the names in data_specification.md line 384, but the rows the loader actually emits come from df.to_dict('records') over data/supplementary/open_interest_hist/BTCUSDT/*.parquet whose columns are symbol, open_interest, open_interest_value, timestamp_ms. Every row failed the value lookup, the OI list stayed empty, _oi_at always returned None and _armed could never be True. The spec table is stale on this key and should be corrected. Two data-path changes only, with the mechanism, gates, exits and sizing untouched so the passing layers stay green: (1) accept both spellings for value and timestamp, preferring contract OI over the *_value variants (which embed the price move and would not be orthogonal to the price leg); (2) merge the metrics series as a second OI source — open_interest_hist for BTCUSDT covers only 2026-03-23..2026-08-03 (12,963 rows) while Binance Vision's metrics file carries the SAME BTCUSDT open-interest column at 5-minute resolution from 2020-09-01 (325,930 rows), six years deeper — downsampled to one point per hour during parsing (36h lookback, 6h tolerance) so the parsed series is ~52k points, not ~326k. I verified the parser against all three real row shapes before submitting. And for the first time on this hypothesis the fixed data path produces a measurable, cost-clearing edge: engine-free over the full sample (2020-09..2026-08, OI read at-or-before the bar open, entry at the 4H close, no look-ahead), the shipped defaults fire 203 times (~34/year, inside the hypothesis's 30-60 target and above the walk-forward density floor the Research Lead raised) with a mean 3-day forward return of +1.405% at t=3.13. All nine threshold x stabilization cells are positive with t between 2.29 and 3.94, and the effect grows monotonically with the decline threshold (0.03 -> +1.21%, 0.05 -> +1.41%, 0.08 -> +2.53%) — mechanism-consistent rather than a hand-picked cell — which is roughly an order of magnitude above the ~0.10% round trip. I kept the ex-ante defaults rather than moving to the strongest cell; the 3% stop / 6% take-profit / 18-bar geometry will capture only part of that raw drift, which is what the backtest is for.

Hypotheses

The OI-decline contrarian is now measurable (good bug fix) but its entire edge is a 2020-2021 bull-market artifact: strongly positive in 2020-2021, then three consecutive losing years (2022 -3.06%, 2023 -0.25%, 2024 -2.78%). Because it is long-only and daily-bull-gated, it is BTC dip-buying beta (alpha 0.0195) concentrated in one cycle — which is structurally fatal for the walk-forward: any OOS window in 2022-2024 is ≤ 0, and OOS Sharpe ≤ 0 is an automatic hard-gate rejection no parameter can fix. Supporting: Sharpe 0.575 with sharpe_ci_low -0.082 (CI straddles zero), 95 trades (below the ~100 measurability floor; the 4H signal-density fix delivered ~15/yr, not the promised 30-60), return_kurtosis 30.6. Not an iterate — the weakness is regime concentration and thin firing, not a tunable parameter. Failure pattern: oi_contrarian_bull_regime_concentration (edge entirely in 2020-2021, three losing OOS-regime years, Sharpe CI straddles zero, sub-100 trades).

Implementation

Long-only positioning-state contrarian on BTCUSDT.BINANCE USD-M perp (4-hour bars) with a daily-bar regime leg. Each bar it reads perpetual open interest at or before the bar's open and returns the continuous OI-decline percent over the last oi_lookback_hours as its signal. It goes LONG when three conditions hold together: open interest has fallen at least oi_decline_thresh over the lookback (leverage flushed, by liquidation or voluntary closing), price has STABILIZED (the 4H close sits within stab_pct of the lowest low of the prior stab_window bars, so the decline has halted rather than continuing), and the daily timeframe is not clearly bearish (daily close above SMA(regime_sma) x (1 - regime_tol)). Exits on a 3% stop, 6% take-profit, an 18-bar time stop, or when open interest re-expands past the entry level (leverage rebuilding, thesis spent). Sizing is capital-relative, capped both by notional_pct of equity and by risk_pct/stop_pct, leverage 1.0. If no open-interest data is available the strategy stays flat and never falls back to a price-only trigger.

Verification Results

At BACKTEST_REVIEW confirm the OI series actually available to the strategy spans the full backtest window (not just the ~4-month open_interest_hist), and that the full run produces >=100 trades with per-window walk-forward counts above the density floor. If only open_interest_hist is injected, the edge is unmeasurable regardless of the positive study.

Verification Results

Data-coverage verification is the decisive open question for BACKTEST_REVIEW. The strategy's deep history depends on merging the Binance Vision 'metrics' OI series (~326k rows, 2020-09..2026-08) because open_interest_hist for BTCUSDT covers only ~4 months (2026-03-23..2026-08-03). The engine-free study (which read the parquet directly) fires 203 times (~34/yr), but the Layer-3 sandbox produced only 11 trades over 362 days (~11/yr) — a 3x shortfall. That is either a benign recent-year effect (fewer OI-decline+stabilization+bull-regime setups in the last year) OR a sign the backtest injects shallower OI (only the ~4-month open_interest_hist) than the developer's direct read. If the deep 'metrics' series is NOT injected into supplementary_data at full-backtest time, the walk-forward will be starved of trades — the exact 'walk-forward-incompatible signal density' failure this hypothesis was designed to avoid, and the same supplementary-feed-availability wall that abandoned the funding-rate and liquidation-spike siblings.

Verification Results

Treat the full-backtest metrics as provisional until the trade count is large enough that a few outlier trades do not dominate; rely on the 203-trigger full-sample study for the edge estimate.

Verification Results

The positive sandbox is thin and outlier-influenced: 11 trades over 362 days, return_skew 3.31, return_kurtosis 37.9, sharpe_ci [-1.09, +2.12] (spans zero), largest_win 1896 vs largest_loss -1074. It corroborates the direction of the engine-free study (+1.405% mean 3-day forward, t=3.13, all 9 cells positive, monotone in threshold) and clears the fee floor by ~9x (avg_trade_return_pct +0.936%), but the sandbox slice alone is not decisive; the full-sample study is what carries the measurability claim.

Backtest Review

Iteration 5 fixed a real data-path bug — the OI series is now populated and the strategy is measurable for the first time after 4 zero-trade iterations

Backtest Review

Genuinely distinct, under-explored signal class (OI positioning-state contrarian), not the exhausted trend/reversion/funding families

Backtest Review

Low max_drawdown (7.5%), profit_factor 1.61, avg_trade_return_pct 0.94% (~6x the fee floor)

Backtest Review

Edge is a 2020-2021 bull-market artifact: +6.4%/+17.3% in 2020-2021, then three consecutive losing years (2022 -3.06%, 2023 -0.25%, 2024 -2.78%); rolling Sharpe decayed from 6-8 to negative

Backtest Review

Structurally fatal for walk-forward: any OOS window in 2022-2024 is ≤ 0, and OOS Sharpe ≤ 0 is an automatic hard-gate rejection — untunable

Backtest Review

Sharpe 0.575 with sharpe_ci_low -0.082 — CI straddles zero, not significant before deflation

Backtest Review

95 trades — below the ~100 measurability floor; the hypothesis's 30-60/yr signal-density promise did not materialize (~15/yr actual)

Backtest Review

Long-only (0 shorts), daily-bull-gated dip-buyer = BTC beta timing with tiny alpha (0.0195); return_kurtosis 30.6 shows outlier dependence

Outcome Summary

This was the third supplementary-data attempt in a series, using open-interest decline plus price stabilization to catch post-flush BTC bottoms, and explicitly engineered on 4H bars to beat the walk-forward signal-density wall that killed its funding and liquidation siblings. Four iterations produced zero trades until the developer traced it to an empty OI series (a stale field name in the spec) and fixed the data path, finally making it measurable — profit factor 1.61, drawdown 7.5%. But the now-visible record showed the edge lived entirely in 2020-2021 with three losing years after, so as a long-only bull-gated dip-buyer it would fail every 2022-2024 OOS window; the analyst abandoned it at BACKTEST_REVIEW as regime-concentrated BTC beta with a Sharpe CI on zero and only ~15 trades a year.

Outcome Summary

Signal density and a clean data path are necessary but not sufficient — a long-only, bull-regime-gated dip-buyer concentrates its edge in a single bull cycle, so consecutive losing OOS years make it structurally fail walk-forward regardless of a strong full-sample profit factor; and always verify the supplementary feed is actually populated (field names matched) before attributing zero trades to thresholds.

Outcome Summary

The analyst abandoned it at the pre-optimization BACKTEST_REVIEW gate: as a long-only, daily-bull-gated dip-buyer it is essentially BTC beta timing with tiny alpha (0.0195) whose entire edge is concentrated in 2020-2021, so any 2022-2024 walk-forward OOS window is ≤ 0 — an automatic hard-gate rejection no parameter can fix — compounded by a CI straddling zero and a sub-100 trade count.

Outcome Summary

A long-only single-instrument contrarian positioning-state strategy on BTCUSDT perp (4H bars + open-interest supplementary data, daily bull-regime filter) that went long when open interest dropped sharply over 24-48h (leverage flush) AND price stabilized near a recent floor, on the thesis that a lightened, floor-found market lets fresh longs drive recovery — with 4 parameters and the 4H timeframe chosen to lift signal density above the walk-forward viability threshold.

Outcome Summary

After the developer fixed a data-path bug (the OI series had been silently empty because of wrong field names, causing four prior zero-trade iterations), it became measurable for the first time: Sharpe 0.575 (sharpe_ci_low -0.082, straddling zero), profit factor 1.61, max drawdown 7.47%, total return 25.4%, avg trade return 0.94% of notional, win rate 55.8% over 95 trades. But the edge was a 2020-2021 bull-market artifact (+6.4% / +17.3% those years) followed by three consecutive losing years (2022 -3.06%, 2023 -0.25%, 2024 -2.78%), with rolling Sharpe decaying from 6-8 to negative, and the promised 30-60 trades/year materialized as only ~15/year.

Iteration History

Verification failed (Layer 2 — synthetic scenarios): Parameters used: ['tp_pct', 'risk_pct', 'stab_pct', 'stop_pct', 'regime_sma', 'stab_window', 'min_notional', 'notional_pct', 'max_hold_bars', 'oi_tolerance_s', 'oi_decline_thresh', 'oi_lookback_hours'] 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: 1735690140000) - steady_downtrend: TypeError: FactoryStrategy._bar_ts() takes 1 positional argument but 2 were given (bar timestamp: 1735690140000) - flat_ranging: TypeError: FactoryStrategy._bar_ts() takes 1 positional argument but 2 were given (bar timestamp: 1735690140000) - volatility_spike: TypeError: FactoryStrategy._bar_ts() takes 1 positional argument but 2 were given (bar timestamp: 1735690140000) - zero_volume: TypeError: FactoryStrategy._bar_ts() takes 1 positional argument but 2 were given (bar timestamp: 1735690140000) - price_gap: TypeError: FactoryStrategy._bar_ts() takes 1 positional argument but 2 were given (bar timestamp: 1735690140000)

Iteration History

Verification failed (Layer 2 — synthetic scenarios): Parameters used: ['tp_pct', 'risk_pct', 'stab_pct', 'stop_pct', 'regime_sma', 'stab_window', 'min_notional', 'notional_pct', 'max_hold_bars', 'oi_tolerance_s', 'oi_decline_thresh', 'oi_lookback_hours'] Check that __init__ sets all attributes from self.parameters.get(). - steady_uptrend: TypeError: BtcFourHourOiDeclinePriceStabilizationLong._ts_of() takes 1 positional argument but 2 were given (bar timestamp: 1735690140000) - steady_downtrend: TypeError: BtcFourHourOiDeclinePriceStabilizationLong._ts_of() takes 1 positional argument but 2 were given (bar timestamp: 1735690140000) - flat_ranging: TypeError: BtcFourHourOiDeclinePriceStabilizationLong._ts_of() takes 1 positional argument but 2 were given (bar timestamp: 1735690140000) - volatility_spike: TypeError: BtcFourHourOiDeclinePriceStabilizationLong._ts_of() takes 1 positional argument but 2 were given (bar timestamp: 1735690140000) - zero_volume: TypeError: BtcFourHourOiDeclinePriceStabilizationLong._ts_of() takes 1 positional argument but 2 were given (bar timestamp: 1735690140000) - price_gap: TypeError: BtcFourHourOiDeclinePriceStabilizationLong._ts_of() takes 1 positional argument but 2 were given (bar timestamp: 1735690140000)

Iteration History

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

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