Skip to content

View original

BtcFundingSettlementEventReversionLS

Hypotheses

BTC Funding-Settlement Event Reversion — Conditioned on EXTREME Funding, Fade the Crowd Into the Fixed 8-Hour Settlement and Exit Shortly After (Scheduled-Event Microstructure, NOT Trend / NOT Unconditional Calendar), Low-Turnover (BINANCE USD-M, 1H Bars, Long-Short, 3-Parameter)

Hypotheses

A LONG-SHORT, SINGLE-INSTRUMENT BTC probe of a scheduled-event microstructure edge, and an explicit continuation of the deliberate exit from the exhausted families: trend is closed (L62; every non-momentum construction landed base Sharpe ≈0.4–0.7 and died, confluence falsified at 0.634, TSMOM basket collapsed OOS to −3.3), reversion is dead, and even unconditional calendar seasonality is emptying (the turn-of-month sleeve was empirically FALSIFIED — no month-boundary shape on BTC). This mechanism is DIFFERENT from all of those and from the pending day-of-week / intraday-session sleeves: it is EVENT-driven around Binance's FIXED funding-settlement clock (00:00 / 08:00 / 16:00 UTC), and CONDITIONED on the funding rate being at an extreme — so it is neither an unconditional time-of-day bet nor the multi-day funding-contrarian reversion (which harvested the wrong horizon). The thesis: when the upcoming funding is extremely POSITIVE (longs crowded and about to pay), some over-leveraged longs de-risk into settlement, creating transient pre-settlement weakness that stabilizes/recovers just after the payment clears — so fade the crowd (short into an extreme-positive settlement, cover after), mirror for extreme-negative funding. It uses only DEEP, RELIABLE data — 1H bars plus the funding_rate feed (both multi-year on BTC) — on the single-instrument Binance USD-M substrate (the only artifact-free, non-fragile one this session found; COIN-M times out, HL is history-capped, Deribit options span ~34 days, multi-instrument produces non-physical returns). Turnover is low (only extreme-funding settlements trade, a few per month), and there is no optimizable rarity threshold beyond a bounded percentile. It avoids the graveyards: NOT trend (L62), NOT a liquidation/quarterly feed (L61), NOT the falsified TOM, NOT multi-day funding-carry/contrarian. Exactly 3 tunable parameters: the funding-extreme percentile, the pre-settlement entry lead (hours), and the post-settlement hold (hours).

Hypotheses

Iteration-2 fix only, minimum change: Layer 2 failed with `TypeError: FactoryStrategy._bar_ts() takes 1 positional argument but 2 were given` in all six synthetic scenarios. The Layer-2 `_StrategyProxy` copies every callable off the real instance and re-binds it with `types.MethodType(...)`, which turns the base class's `@staticmethod _bar_ts(bar)` / `_bar_interval_ns(bar_type)` into instance methods, so `self._bar_ts(bar)` is invoked as `_bar_ts(self, bar)` and raises. I removed both base-helper calls from the hot path and inlined them: the timestamp is now read directly via `getattr(bar, 'ts_event', ...) or ts_init`, and the bar interval is parsed once in `__init__` from the bar-type string into `self._interval_ns` (defaulting to 1 hour). Nothing else changed — imports, class structure, the continuous crowding signal, the causal last-settled-rate conditioning, the settlement clock, entry/exit logic, sizing and `_param_bounds` are byte-identical to the previous iteration, so Layer 1 stays green and the Layer-2 failure mode is removed.

Hypotheses

Decisive net loser on a well-measured sample — the mechanism has negative edge, not a tunable one. Over 355 trades and 6.6 years of deep, reliable data (no coverage wall), the strategy returns -22.8% with profit_factor 0.70, expectancy -$57.44/trade, avg_trade_return_pct -0.028% (negative), Sharpe -0.35 with CI [-0.983, 0.221], information_ratio -0.80 and PSR 0.14. It loses in most calendar years and its rolling Sharpe sits around -8 through the recent regime. The 'fade the crowd into an extreme funding settlement and recover after' thesis has the wrong sign on BTC — the hypothesized post-payment stabilization does not occur. No tuning of the 3 parameters can flip a PF-0.70, negative-expectancy book positive; the optimizer would only locate where a nonexistent edge is least negative and then fail deflated-Sharpe/holdout. The data is clean and the measurement is trustworthy — the edge simply isn't there. Not worth 2 hours of optimization.

Implementation

Long/short BTC 1H event trade around Binance USD-M's fixed funding-settlement clock (00:00/08:00/16:00 UTC). Every bar it computes a continuous crowding score: the signed mid-rank of the most recently SETTLED funding rate within a trailing 270-settlement sample, mapped to [-1,+1]. On the bar that closes entry_lead_hours before a settlement, if the crowding score is at an extreme it fades the crowd (SHORT when longs are crowded and about to pay, LONG when shorts are), holds through the payment, and exits post_hold_hours after settlement, with a structural 3xATR stop and a hard calendar cap as tail guards. Turnover is capped at one settlement event per UTC day. Sizing is risk-capped: a stop-out costs at most 1% of equity, with a gross-notional cap of 1x equity.

Verification Results

CLEAN RESTART 2026-09-04 — this run's verdict history and learning records were removed and it was restarted from verification. Its previous abandonment came from the pipeline, not from the market: the Layer-2 harness mis-bound @staticmethod helpers (fixed), QA issued terminal performance verdicts on an unoptimized smoke test (removed — QA now judges correctness only), and sandbox timeouts came from backtest-slot starvation (fixed). The hypothesis and the strategy code are unchanged. Verify the code on its merits; performance is decided later by the full backtest and the optimizer.

Verification Results

No fix; noted for context.

Verification Results

Synthetic scenarios all show frozen signal=0.0 (no funding feed injected → _have_rank never True), so Layer-2 never exercised the trading path. Non-fatal; the sandbox with real funding produced 93 trades.

Verification Results

Analyst confirms on full history/optimization whether per-trade edge clears fees.

Verification Results

Both legs are market/taker on BINANCE USD-M (~0.10% round trip); sandbox avg_trade_return_pct -0.087% is below that floor. Performance concern, not a code defect.

Backtest Review

Genuinely distinct scheduled-event mechanism with causal, leak-free funding conditioning; deep reliable data (355 trades over 6.6 years, no coverage wall)

Backtest Review

Clean execution: 355 signaled, 355 submitted, no drops; low, structurally-capped turnover; contained max_drawdown 25.5%

Backtest Review

Correct polarity reasoning documented; balanced long/short (214/141)

Backtest Review

Net loser: total_return -22.8%, profit_factor 0.70, expectancy -$57.44/trade, avg_trade_return_pct -0.028% (negative)

Backtest Review

Negative risk-adjusted metrics across the board: Sharpe -0.35 (CI [-0.983, 0.221]), Sortino -0.18, information_ratio -0.80, PSR 0.14

Backtest Review

Loses in most calendar years (2021 -7.0%, 2024 -3.6%, 2025 -9.3%, 2026 -6.6%); rolling Sharpe ~-8 in the recent regime

Backtest Review

The fade-into-settlement edge has the wrong sign — the hypothesized post-payment recovery does not materialize on BTC

Backtest Review

return_kurtosis 92.7 — outlier-driven losing tape

Iteration History

Verification failed (Layer 2 — synthetic scenarios): Parameters used: ['_risk_frac', '_atr_period', '_min_window', '_param_bounds', '_min_stop_frac', '_pctile_window', '_stop_atr_mult', 'funding_pctile', '_max_gross_frac', 'post_hold_hours', 'entry_lead_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: 1735690740000) - steady_downtrend: TypeError: FactoryStrategy._bar_ts() takes 1 positional argument but 2 were given (bar timestamp: 1735690740000) - flat_ranging: TypeError: FactoryStrategy._bar_ts() takes 1 positional argument but 2 were given (bar timestamp: 1735690740000) - volatility_spike: TypeError: FactoryStrategy._bar_ts() takes 1 positional argument but 2 were given (bar timestamp: 1735690740000) - zero_volume: TypeError: FactoryStrategy._bar_ts() takes 1 positional argument but 2 were given (bar timestamp: 1735690740000) - price_gap: TypeError: FactoryStrategy._bar_ts() takes 1 positional argument but 2 were given (bar timestamp: 1735690740000)
Strategy report

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