BtcCoinMNegativeFundingCarryLong
Hypotheses
COIN-M BTC Negative-Funding Carry, Long-Only Single-Leg (BINANCE_CM Inverse Perp BTCUSD_PERP, Collect Funding Paid-To-Longs During Backwardation Episodes, Multi-Day Hold, BTC-Denominated Returns, 3-Parameter)
Hypotheses
A LONG-ONLY, single-leg CARRY strategy on the deepest coin-margined inverse perpetual, BTCUSD_PERP.BINANCE_CM. Mechanism is identical in spirit to the deployed survivor '5-Asset Negative-Funding Carry Basket' (Sharpe 1.97) and 'Cross-Venue BTC Funding Carry' (Sharpe 8.58) — collect a real, mechanically-paid cashflow — but expressed on a genuinely under-represented venue (BINANCE_CM is only 3.0% of the portfolio vs a >=5% quota target) and denominated in BTC, which is the reason the COIN-M venue exists. On an inverse perp, when 8h funding is NEGATIVE, shorts pay longs; a long position is PAID to hold. During risk-off / backwardation episodes on BTC, funding on the coin-margined contract goes persistently negative for 1-3 day stretches. We hold a single long BTCUSD_PERP position through those episodes to harvest the funding, with an ATR stop to bound the directional exposure that comes with being long a single name. Funding is used strictly as CARRY (a cashflow to collect), NOT as a direction predictor — this deliberately avoids the exhausted 'funding-as-signal-on-majors' class (L13). BTC CM is the single deepest inverse perp, so its funding history IS catalogued (avoids L20, which only bites thin multi-asset CM baskets). Deliberately 3 parameters and low-turnover to resist the overfitting that killed 229 prior hypotheses.
Hypotheses
Iteration 2 fixes the reported Layer-3 zero-trade failure with two small, targeted changes and touches nothing else. ROOT CAUSE: _build_funding filtered keys with 'if not isinstance(k, int): continue'. The funding dict carries dual int/str keys only IN-PROCESS - the supplementary blob is JSON round-tripped into the backtest subprocess, after which only the STRING keys survive (documented in data_specification and confirmed in supp_collector's json.loads(json.dumps(...)) normalisation step). So the series parsed empty, _fund_ready stayed False, _data_ok was never True, and should_enter returned None on all 6,365 evaluated bars - exactly the diagnostic reported. The fix coerces BOTH key types with int(k) inside a try, deduping by timestamp, which is correct under either shape. SECOND, per the 'loosen the entry threshold' instruction, I measured the real BTCUSD_PERP COIN-M funding series (1,034 settlements): a 3-print mean pays longs at least 0.5 bps/8h in only 24 distinct episodes, versus 42 episodes at 0.25 bps, so the default entry_rate_bps drops 0.5 -> 0.25 while still requiring genuine backwardation (strictly above zero, and the exit stays at zero for hysteresis). Nothing else changed: imports, class structure, the continuous per-bar carry score, the no-price-proxy no-data policy, the exits and the inverse contract sizing are as they were when Layers 1, 1.5 and 2 passed, so no earlier check can regress. Honest note for the analyst: COIN-M funding history begins 2025-05-25, so only the recent ~1 year of the 8H window can generate trades - roughly 40 carry episodes - and the earlier bars are legitimately signal-free rather than broken.
Hypotheses
data_unavailable: backtest data for BTCUSD_PERP.BINANCE_CM could not be collected after 5 retries:
data collection for BTCUSD_PERP.BINANCE_CM exceeded the 600s per-cycle budget; resuming next cycle
The data layer (not the strategy) is the blocker — re-evaluate this hypothesis once collection is fixed / the symbol is backfilled.
Implementation
Long-only negative-funding carry on the BTC COIN-M inverse perpetual (BTCUSD_PERP.BINANCE_CM, 8-hour bars aligned 1:1 with the funding cycle). On an inverse perp a NEGATIVE funding rate means shorts pay longs, so a long is paid to hold. Each bar the strategy computes a carry score - minus the mean of the last 3 funding prints, in bps per 8h - and goes LONG while that score is at least 0.25 bps (a genuine backwardation episode), holding through the episode to collect every settlement. It exits when the carry is exhausted (score back to zero), when the funding view is lost or stale, or on a 3x ATR directional stop that bounds the single-name long exposure. Funding is used strictly as a cashflow to collect, never as a direction predictor. Sizing budgets the ATR stop at 1.5% of equity, caps gross notional at 0.75x equity, and floors to WHOLE $100-face inverse contracts via contracts_for_notional.
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.
Iteration History
Verification failed (Layer 3 — sandbox backtest): No trades produced
Bar type used: BTCUSD_PERP.BINANCE_CM-8-HOUR-LAST-EXTERNAL, Bars processed: 6384
Diagnostics: should_enter() returned a side 0 times over 6365 evaluated bars -> your ENTRY CONDITION never triggered. Loosen the entry logic / thresholds.
Ensure your strategy produces trades with the given data and parameters.
Backtest and paper results are hypothetical. Trading involves risk of loss.