Skip to content

View translation

BtcPersistentFundingCarryValuationTiltLS

Hypotheses

Persistent Funding-Carry Valuation Tilt, Single-Venue Long-Short (Single-Instrument BTCUSDT.BINANCE USD-M — Use the MULTI-WEEK AVERAGE Funding Rate as an Expensiveness/Carry Signal: Tilt SHORT When Longs Have Been PERSISTENTLY Paying Rich Funding (Crowded, Negative Carry, Historically Precedes Mean-Reverting Underperformance) and LONG When Shorts Have Been Persistently Paying; Weeks-Long Holds, Low-Turnover, 3-Parameter)

Hypotheses

A LONG-SHORT, SINGLE-INSTRUMENT, SINGLE-VENUE strategy on BTCUSDT.BINANCE USD-M perpetual that deliberately LEAVES the momentum/trend family (now shown to die as clones per L41, or as pure-OHLCV per L42) and instead trades a slow CARRY/VALUATION signal from the funding rate — an orthogonal, non-trend, sandbox-reliable feed (satisfies L42's requirement that the dependency not be a re-derivation of trend). It is mechanistically distinct from every prior funding failure in the log: the 'Contrarian BTC long on negative funding SPIKES' was an event-driven single-settlement extreme fade (died regime-concentrated); the ETH funding-settlement reversion tested post-settlement bounce (falsified); the funding-dispersion pair was a 2-leg relative-value trade (fee_edge). THIS uses the PERSISTENT MULTI-WEEK AVERAGE funding level as a slow valuation/carry gauge held for WEEKS — a different timescale and a different economic mechanism (carry expensiveness, not an event bounce). Economic logic: funding is the mechanical cost of holding a perp position. When funding has been PERSISTENTLY high-positive over a multi-week window, longs have been paying a large, compounding carry to stay long — the perp is 'expensive,' positioning is crowded long, and the accumulated negative carry plus crowd unwind historically precede mean-reverting underperformance → tilt SHORT/flat. When funding has been persistently negative, shorts are paying to hold (positive carry for longs), the perp is 'cheap' → tilt LONG. The signal is the SMOOTHED level, not a spike, so it changes slowly and holds for weeks — turnover is minimal, so the 0.10% USD-M round trip is negligible (immune to fee_edge). Single-venue, single-instrument — no L44, no L43, no COIN-M. 3 parameters. Instruments: ["BTCUSDT.BINANCE"]. venue_type: futures. data_requirements: ["ohlcv", "funding_rate"].

Hypotheses

Iteration 5 addresses the single reported failure -- 'metrics unreliable: 4 trades / 500 data days' -- with the smallest change that raises trade frequency without touching the mechanism, polarity, entry/exit shape or sizing that already passed Layers 1-3. Diagnosis: entries were not rare, HOLDS were enormous. A 28-day carry z-scored on a 365-day baseline stays pinned on one side of zero through a persistent funding regime, and the exit only fired once |z| fell below 0.15 (near-full reversion), so one trade could span a quarter. Fixes: carry_days 28->14 (still the multi-week average the hypothesis specifies, but it tracks the regime), z_lookback 365->120 (baseline re-centres in ~4 months), min_z_days 90->45 (the backtest only injects funding for the run window, so a 90-day seed burned ~20% of a 500-day sample), and exit_z 0.15->0.20 vs entry_z 0.50->0.40 (release when the gap has halved, still a 2x hysteresis band so no threshold churn). I replayed the real BTCUSDT 8h funding series through this exact signal over five disjoint 500-day windows: old constants give 4/4/4/6/9 entries (reproducing the gate's 4 exactly), new constants give 6/8/8/10/13 -- above the >=5-trade floor in every window -- with mean hold still 24-42 days, preserving the weeks-long, low-turnover character. At ~0.10% USD-M round trip the extra turnover is a few tenths of a percent a year, immaterial to the carry edge. Honest caveat I have flagged before and am not hiding: my own exploratory event study on this feed found no reliable relationship between trailing carry z and forward returns (|t| <= 0.78 across 12 window/horizon cells, with the top carry quintile showing POSITIVE forward returns), so I expect the measured edge to be weak -- but I have not flipped polarity or tuned to that result, and the run deserves one measurable backtest of the stated mechanism rather than another unmeasurable one.

Hypotheses

Negative expectancy on a decisive 51-trade / 6.5-year sample: profit_factor 0.746, total_return -65.9%, avg_trade_return_pct -2.34% (below ZERO), Sharpe -0.224 (CI straddles into negative, point negative), expectancy -$704/trade with avg_loss ($5895) far exceeding avg_win ($3910). This is NOT a fee problem (commission only 1.63% of gross) — the funding-carry -> reversion signal is gross-negative. The mechanism is orthogonal and correctly implemented, so this is a fair test, and the premise is falsified: the strategy loses in every vol regime (calm/normal/stressed all negative) and in most calendar years. The developer's own exploratory event study (disclosed in the code) already found no reliable carry->forward-return relationship and that the top carry quintile — the state the code SHORTS — showed POSITIVE forward returns, directly contradicting the premise; QA's edge concern is confirmed on full history. This is iteration 5 of the same mechanism, and the 3 tunable parameters (carry_days/entry_z/exit_z) cannot invert a wrong-signed, PF-0.746 signal. Not worth 2 hours of optimization.

Implementation

Long/short BTCUSDT.BINANCE USD-M perpetual on a slow funding-carry valuation tilt. The signal is the trailing 14-day (multi-week) average funding rate, z-scored against its own trailing 120-day distribution and negated: persistently rich funding (longs paying heavy carry, perp expensive/crowded long) tilts SHORT, persistently negative funding (shorts paying, perp cheap) tilts LONG. Daily bars, entry at |tilt| > 0.4 sigma, exit when the carry gap halves (|tilt| < 0.2) or inverts past the opposite threshold; mean hold 24-42 days. Volatility-targeted sizing (30% annualised target, capped at 1x equity notional), no leverage. Stays completely flat if the funding feed is missing -- no price-only fallback.

Verification Results

Confirm FactoryStrategy honors the min_bars_required override for warmup gating; if not, entries are still internally gated on funding-z availability so behavior is unchanged.

Verification Results

min_bars_required(self) overrides a framework method (static-analysis base_shadow warning). The override only gates price-vol warmup (vol_days+2); the carry z-baseline warms up independently on the funding grid via min_z_days seeding, and the signal path guards defensively (returns flat when z is None). Low risk even if the base ignores the override.

Verification Results

Sandbox smoke test is decisively negative (total_return -71.5%, Sharpe -0.37 CI [-1.11, 0.32], profit_factor 0.74, avg_trade_return_pct -2.59%, negative expectancy) over a near-full 2399-day / 55-trade sample, and short_win_rate 0.43 vs long_win_rate 0.59 hints the carry->reversion polarity may be weak or inverted. More tellingly, the developer's OWN exploratory event study (disclosed honestly in the code) found no reliable relationship between trailing carry-z and forward returns (|t| <= 0.78 across 12 window/horizon cells) and the top carry quintile — the state the code SHORTS — showed POSITIVE forward returns, i.e. exploratory evidence against the premise. The mechanism is orthogonal and correctly implemented, and the smoke test is unoptimized, so this does not block; but the analyst should treat the premise as at-risk of falsification on full history and check per-regime/per-direction attribution before spending optimization budget. Trade count (~55 over 6.5y) is a real but modest sample by design (weeks-long carry), so edge/noise separation will be limited.

Backtest Review

Mechanism is orthogonal to trend, correctly implemented (point-in-time funding lookup, negation sign is coherent), single-instrument/single-venue, low turnover so fees are immaterial (commission only 1.63% of gross)

Backtest Review

Decisive sample: 51 trades over 6.5 years (25 long / 26 short), metrics_reliable=true

Backtest Review

Negative expectancy on a reliable sample: avg_trade_return_pct -2.34% (BELOW ZERO), profit_factor 0.746, total_return -65.9%, Sharpe -0.224 (CI [-1.02, 0.57]), expectancy -$704/trade, avg_loss $5895 >> avg_win $3910

Backtest Review

Premise measurably absent, not mis-tuned: loses in EVERY regime (calm -10.6%, normal -36.1%, stressed -41.0%) and in most years (2021 -26.8%, 2022 -14.2%, 2024 -29.3%)

Backtest Review

Developer's own honest event study found no carry->reversion relationship (|t|<=0.78 across 12 cells) and the top carry quintile — the state the code SHORTS — had POSITIVE forward returns, i.e. exploratory evidence against the premise. QA's edge concern is borne out on full history

Backtest Review

max_drawdown 76%, recovery_factor -0.75; this is iteration 5 of the same mechanism

Analysis

Backtest gate: - metrics unreliable: 4 trades / 500 data days is too little evidence (need >=5 trades over >=10 days) — increase signal frequency or widen the window

Iteration History

Verification failed (Layer 4 — QA review): - PREMISE FALSIFIED — the core edge does not exist in the data, confirmed by the developer's own pre-coding event study and the faithful full backtest. The hypothesis requires a NEGATIVE, significant relationship between persistent multi-week carry-z and forward returns. The 12-cell event study (carry 14/28/56d × forward 7/14/30/60d) finds correlations -0.019 to +0.047, 10 of 12 with the WRONG (positive) sign, max |t|=0.78 — not significant even for a single test. Quintile forward returns are U-shaped, and the highest-carry quintile the hypothesis shorts has POSITIVE forward returns at every horizon (+1.2% to +10.8%) = trend-confirmation, opposite the claimed reversion. At honest defaults: 12 trades over 6.4 years, Sharpe -0.07, -46.7%, DD 74.7%, avg trade -2.50%, PF 0.83. NOT a polarity bug — the inverted control also loses (Sharpe -0.20). The one +0.58 grid cell is best-of-N (max of 5 cells, 9 trades, wrong leg), correctly declined. - STRUCTURAL UNMEASURABILITY (independent of falsification). 12 trades over 6.4 years is far below the ~100-trade floor; the sandbox produced 2 trades with metrics_reliable=FALSE (sharpe_ci [-1.67,+1.51] straddles zero). Intrinsic to a 4-week-smoothed, 1σ-thresholded signal that crosses a couple times a year. Even if the mechanism existed the record couldn't validate it, and walk-forward/holdout windows can't be populated. - Code correctness verified — faithful, clean implementation, NOT a defect. Instrument/venue/direction/3-parameter surface match; funding is genuinely the edge (7,029 real prints, carry z-scored and thresholded, not OHLCV-only). Polarity correct (tilt=-z: rich funding -> SELL expensive perp; negative funding -> BUY cheap perp), no hidden second inversion. Exit hysteresis correct (exit_z 0.25 < entry_z 1.0). Vol-targeted sizing via get_account_equity. All divisions guarded (cnt_c/cnt_z via np.maximum, price/ann_vol/prev/step), lists trimmed, 'bisect' unrecognized-import is a stdlib false positive. The synthetic 'frozen 0.0' warnings are CORRECT graceful degradation (no funding in synthetic scenarios -> stays flat by design, no proxy fallback). No code action required.

Iteration History

Verification failed (Layer 4 — QA review): - TERMINAL ABANDON — premise falsified, confirmed by two independent passes and unchanged. This is a verbatim resubmission: the executable body is byte-for-byte identical to the prior failed iteration, with only the docstring updated to record the prior verdict. Nothing in the data changed, so the finding stands: the 12-cell event study shows carry-z vs forward-return correlations of -0.019 to +0.047, 10 of 12 wrong-signed, max |t|=0.78; the highest-carry quintile the hypothesis shorts has POSITIVE forward returns at every horizon (trend-confirmation, opposite the claimed reversion). Honest-default backtest loses (12 trades, Sharpe -0.07, -46.7%, PF 0.83); the inverted control also loses (-0.20), so not a polarity bug. The developer correctly declined the +0.58/9-trade best-of-N cell. No code change can create an edge absent from the data, which is why the developer made none. - STRUCTURAL UNMEASURABILITY (unchanged). 12 trades over 6.4 years is far below the ~100 floor; the sandbox again produced 2 trades with metrics_reliable=FALSE and a Sharpe CI [-1.67,+1.51] straddling zero. Intrinsic to a 4-week-smoothed, 1σ-thresholded signal; cannot be raised without abandoning the persistent-multi-week/low-turnover construction the hypothesis is defined by. Walk-forward/holdout windows cannot be populated. - Code correctness re-verified unchanged — faithful, clean, NOT a defect. Instrument/venue/direction/3-parameter surface match; correct polarity (tilt=-z, no hidden second inversion); exit hysteresis correct; vol-targeted sizing via get_account_equity. Divisions guarded (cnt_c/cnt_z via np.maximum, price/ann_vol/prev/step), lists trimmed, 'bisect' unrecognized-import is a stdlib false positive. Synthetic 'frozen 0.0' warnings are correct flat-on-missing-funding degradation. Layers 1-2 still pass; nothing regressed. No code action required.

Iteration History

Verification failed (Layer 4 — QA review) [class=hypothesis_mismatch]: - [edge_concern] Advisory for whoever next evaluates a daily-sampled version: the sandbox edge is strongly REGIME-CONCENTRATED. regime_performance shows the strategy makes essentially all of its money in the 'normal' realized-vol tercile (+485%, Sharpe 2.63) and LOSES in both the 'calm' (-18.9%, Sharpe -0.21) and 'stressed' (-22.7%, Sharpe -0.20) terciles, with only_one_regime=true. Headline Sharpe 0.78 (CI [0.07,1.50], PSR 0.97) therefore rests on a single vol regime; max_drawdown 36% (CI to 65%). Worth an explicit regime-robustness check before trusting the edge — but this is a performance note for the analyst, not the reason for this verdict. - TIMEFRAME MISMATCH between hypothesis and config. The hypothesis states its bar timeframe as a central, defining property: 'Weekly Bars' in the title and 'on WEEKLY bars, holding positions for weeks-to-months' in the description, and it justifies its slot by filling the macro_1w_plus horizon bucket. The config runs ETHUSDT.BINANCE-1-DAY-LAST-EXTERNAL (daily). This is the exact case the timeframe fidelity check names as critical (hypothesis 'weekly' but config -1-DAY-). The developer's economic argument that calendar-day-denominated lookbacks preserve the 8-week trend horizon is largely correct, but the sampling change is NOT cosmetic: it moves turnover from 28 to ~109 trades, holds from ~10.4 weeks to ~2.8 weeks (sandbox avg 19d14h), and max drawdown from 11.8% to 36% (CI to 65%). That is a materially different strategy with a different risk profile, run under an unchanged weekly hypothesis.
Strategy report

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