Skip to content

View translation

EthPerpBasisDislocationReversalLS15m

Hypotheses

Perp Basis-Dislocation Reversal, Long-Short (Single-Instrument ETHUSDT.BINANCE USD-M — Fade EXTREME Mark-vs-Index Premium Dislocations Intraday: Long the Perp When It Trades at a Deep DISCOUNT to Its Spot Index = Forced-Selling Overshoot, Short When at an Extreme PREMIUM = Leverage Euphoria, Hold Until the Basis Normalizes, 2-Parameter)

Hypotheses

A LONG-SHORT, SINGLE-INSTRUMENT, SINGLE-VENUE microstructure reversion strategy on ETHUSDT.BINANCE USD-M whose signal is the perpetual's own MARK-vs-INDEX PREMIUM (basis) — derived directly from the mark_price and index_price feeds, both of which are first-class catalog data types confirmed present in the Layer-3 sandbox (the one prior premium hypothesis failed on a venue-swap IMPLEMENTATION bug — it traded spot instead of the perp — NOT on data availability; the premium feed itself loaded). This mechanism is genuinely orthogonal to the perp's own price series: the premium isolates the LEVERAGE-DRIVEN dislocation of the perp away from the underlying spot index, which raw OHLCV cannot express. It deliberately AVOIDS every recent death trap: not OHLCV-only-directional (L42 — the signal is the cross-instrument basis, not a price indicator); not the liquidations feed (forward-only from 2026-04-21, structurally unmeasurable); not OI (feed holes / falsified); not options/IV (L43, not in sandbox); and — critically — NOT cross-venue (L44): we trade ONLY the ETHUSDT.BINANCE perp, and mark/index for that exact instrument are jointly and fully available across the multi-year window. It is distinct from the already-pending SOL funding-positioning reversal (that fades the 8h-averaged FUNDING level over multi-DAY holds; this fades the high-frequency intraday BASIS dislocation over hours). Being LONG-SHORT fills the under-represented direction bucket (13.4% vs the ≤55% long-only target), and 15m bars fill the under-represented short-horizon bucket (9.3%).

Hypotheses

Smallest change that addresses BOTH failures QA named, with no regression to earlier layers. (a) SCOPE: Layers 1-3 passed, so imports, class structure, the premium parser, the instance-method helpers (kept non-static for the Layer-2 proxy), the continuous z signal, and the sizing path are all untouched — I re-ran the Layer-1 static analyzer on the new file and it passes with exactly the same four already-guarded warnings as the previous version. Only the exit block, three new frozen parameters (tp_pct, stop_pct retune, min_edge_pct) and the entry_z default changed. (b) FIX FOR THE DECOUPLING: QA's second finding is that the exit is denominated in the premium while P&L is denominated in the perp price, so a normalization driven by the index pays fees for nothing. The normalization exit is now conditioned on realized perp-price edge >= min_edge_pct, which is set at the round-trip taker cost floor (0.15% vs ~0.10% round trip); mechanically, every remaining normalization exit is now one where the reversion demonstrably converted into price P&L. (c) FIX FOR THE EXPECTANCY GEOMETRY: at the observed 37.7% win rate a fade needs a win/loss ratio above ~1.7 to break even; the old construction had ~0.9 because winners were cut at the first normalization tick and losers ran to a 1.2% stop. A 1.0% target against a 0.5% stop inverts that geometry to 2:1, and it is the direct structural consequence of QA's own 'losers larger than winners' diagnosis. (d) WHAT I DELIBERATELY DID NOT DO: I did not flip the signal to continuation. QA's data does suggest these dislocations continue rather than revert, but the hypothesis under test is a REVERSAL, and re-submitting a momentum strategy under a reversion hypothesis's name would be a hypothesis substitution — that call belongs to the Research Lead, not to me. (e) HONEST ASSESSMENT AND PRE-REGISTERED ABANDON CRITERION: the iteration-2 result is a statistically confident negative (300 trades, Sharpe CI entirely below zero), and these two fixes are the last structurally-defensible levers for this construction, not a parameter search. I have stated in the module docstring that if the sandbox still returns a negative avg_trade_return_pct with these changes, the basis-reversion premise is falsified in the ETH perp price after fees and the hypothesis should be ABANDONED rather than iterated a fourth time. Trade frequency remains well above the Layer-3 measurability floor (3-sigma dislocations on a rolling 96-bar baseline still fire on the order of a hundred times across the 363-day sandbox), so this will not stall in a verification loop for lack of trades.

Hypotheses

Negative-expectancy single-perp basis-dislocation fade that LIQUIDATED the account (total_return -100%, max_drawdown 100%, liquidation 2024-10-20; annual returns -27% to -128% across 2020-2024). Over 2264 trades: avg_trade_return_pct -0.030% (NEGATIVE), profit_factor 0.55, Sharpe -0.92 (CI [-3.07, -0.24] fully below zero), PSR 0.0025, expectancy -$54/trade, information_ratio -2.04, with avg_loss ($239) ~1.8x avg_win ($132) at a 50% hit rate. It is fee-dominated (commission 44.1% of gross, 42-minute average hold, high turnover) and the position sizing is broken (avg_position_pct 1619%, kurtosis 785, a -9295% single-day print) — leverage overran account equity and drove the blowup. The developer pre-registered the kill: the docstring names entry/exit as 'the last two structurally-defensible levers' and states that if avg_trade_return_pct came back negative with these fixes 'the basis-reversion premise is falsified in the ETH perp price after fees and the hypothesis should be ABANDONED rather than iterated further.' It came back -0.030% — negative — so the strategy's own terms mandate abandon. This is the L73 single-perp supplementary-gated (mark/index basis) directional/fade family, established edge-dead this session, and carries stale-leg/basis-artifact risk for intraday extremes. No tuning of entry_z/exit_z flips a negative per-trade edge positive or repairs a liquidation. Failure pattern: risk_reject/no_edge single-perp basis fade, liquidated (L73).

Implementation

Long-short, single-instrument ETHUSDT.BINANCE USD-M perp on 15-minute bars. The signal is unchanged from the version that passed Layers 1-3: the perp's mark-vs-index premium (premium_index feed) z-scored against a rolling 24-hour (96-bar) baseline, returned continuously every bar. Entry is unchanged in direction — fade the dislocation: z >= +entry_z (perp rich, leverage euphoria) goes SHORT, z <= -entry_z (perp at a discount, forced-selling overshoot) goes LONG — but the threshold is raised from 2.0 to 3.0 sigma so only genuinely rare dislocations trade, cutting turnover and the associated round-trip fee drag roughly threefold. The EXIT is what iteration 3 rebuilds, in response to the two defects QA named. First, the premium-normalization exit is now gated on the position having actually earned at least min_edge_pct (0.15%) on the PERP PRICE, measured via the base class's get_position_pnl_pct on avg_px_open: a premium that normalized because the spot INDEX drifted toward the perp (rather than the perp reverting toward the index) no longer closes the trade for a pure round-trip fee. Second, the trade now has an explicit price take-profit (tp_pct 1.0%) against a halved stop (stop_pct 0.5%), a 2:1 reward:risk that cuts continuation fast and lets reversion pay, replacing the previous no-target / wide-stop construction that produced the observed 0.9 win/loss ratio at a 37.7% hit rate. A 6-hour (24-bar) time stop bounds every trade. Sizing is unchanged: 50% of equity in notional at leverage 1.0.

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

Negative, well-sampled edge (155 trades, PF 0.45, avg_trade_return_pct -0.099%, Sharpe CI entirely below zero): the mark-vs-index basis dislocation doesn't mean-revert in the ETH perp PRICE after fees — dislocations continue or normalize via the index. Faithful implementation, so a mechanism/premise finding for the analyst. Abandon at backtest-review per the developer's pre-registered condition; do not optimize and do not invert to continuation inside this hypothesis (a separate Research-Lead hypothesis, which the developer notes is itself marginal).

Backtest Review

Premium/index feed loaded and produced 2264 trades — genuine negative-edge read, not a data wall

Backtest Review

Single instrument / single venue as designed; no cross-venue leg

Backtest Review

Account LIQUIDATED 2024-10-20: total_return -100%, max_drawdown 100%, loses in every year 2020-2024

Backtest Review

Negative expectancy: avg_trade_return_pct -0.030%, profit_factor 0.55, Sharpe -0.92 (CI [-3.07,-0.24]), PSR 0.0025, expectancy -$54/trade, IR -2.04

Backtest Review

Fee-dominated: commission 44.1% of gross on a 42-minute average hold across 2264 trades

Backtest Review

Broken sizing: avg_position_pct 1619%, kurtosis 785, a -9295% single-day print — leverage overran equity and caused the blowup

Backtest Review

Developer pre-registered abandonment if avg_trade_return_pct returned negative — it did (-0.030%)

Backtest Review

L73 single-perp basis-gated directional/fade family, established edge-dead this session

Iteration History

Verification failed (Layer 2 — synthetic scenarios): Parameters used: ['exit_z', 'entry_z', 'stop_pct', 'norm_window', 'min_notional', 'max_hold_bars', 'position_frac', 'size_precision'] Check that __init__ sets all attributes from self.parameters.get(). - steady_uptrend: TypeError: EthPerpBasisDislocationReversalLS15m._ts_of() takes 1 positional argument but 2 were given (bar timestamp: 1735695420000) - steady_downtrend: TypeError: EthPerpBasisDislocationReversalLS15m._ts_of() takes 1 positional argument but 2 were given (bar timestamp: 1735695420000) - flat_ranging: TypeError: EthPerpBasisDislocationReversalLS15m._ts_of() takes 1 positional argument but 2 were given (bar timestamp: 1735695420000) - volatility_spike: TypeError: EthPerpBasisDislocationReversalLS15m._ts_of() takes 1 positional argument but 2 were given (bar timestamp: 1735695420000) - zero_volume: TypeError: EthPerpBasisDislocationReversalLS15m._ts_of() takes 1 positional argument but 2 were given (bar timestamp: 1735695420000) - price_gap: TypeError: EthPerpBasisDislocationReversalLS15m._ts_of() takes 1 positional argument but 2 were given (bar timestamp: 1735695420000)

Iteration History

Verification failed (Layer 4 — QA review): - FEE/EDGE NON-VIABILITY — the Layer-3 sandbox (real ETHUSDT premium_index data, real USD-M fees, 300 trades over 363 days) shows the basis-reversion edge does NOT clear trading costs and is decisively wrong-signed: avg_trade_return_pct -0.11% (below the ~+0.15% futures viability floor, and roughly equal in magnitude to the ~0.10% round-trip taker cost), total_return -33.76%, profit_factor 0.54, Sharpe -2.25 with a 95% CI entirely below zero [-3.77, -0.68] and probabilistic_sharpe 0.0019. The loss is SYMMETRIC across direction (long_win_rate 0.372, short_win_rate 0.382) with losers larger than winners (avg_win 348 vs avg_loss 391, win_rate 0.377) — the low-win-rate / large-loser signature of fading a dislocation that continues rather than reverts. 300 trades over 363 days is above the measurability floor, so this is a real, statistically-confident negative result. The mark-vs-index premium reversion the hypothesis is built on is not present in the ETH perp PRICE after fees. - Exit is triggered on PREMIUM normalization (|pz| back inside exit_z), but P&L accrues on the PERP PRICE. The premium can normalize because the spot INDEX moves toward the perp rather than the perp reverting toward index — in that case the exit fires with no price reversion captured, only fees paid. This decoupling is a plausible structural reason the reversion signal does not convert into tradeable price P&L, consistent with the observed fee-magnitude bleed plus occasional stop-outs.

Iteration History

Verification failed (Layer 4 — QA review): - PREMISE FALSIFIED / EDGE BELOW FEES — CONFIRMED AT ITERATION 3 WITH BOTH LAYER-4 LEVERS APPLIED. The developer faithfully implemented the two structural fixes named in iteration 2: (1) the premium-normalization exit is now gated on realized perp-PRICE edge >= min_edge_pct (0.15%), so a premium normalizing via the index no longer closes a trade for pure fees; (2) an explicit 1.0% price take-profit against a halved 0.5% stop (2:1 reward:risk) replaces the no-target/wide-stop geometry, and entry_z was raised 2.0->3.0 to cut turnover ~3x. Despite all of it the real-data sandbox (292 trades / 363 days, real premium_index, real USD-M fees) is WORSE, not better: avg_trade_return_pct -0.085% (still negative, below the fee floor), total_return -29.67%, profit_factor 0.48, win_rate 0.339 (DOWN from 0.377), Sharpe -2.53 with 95% CI entirely below zero [-4.08, -0.95] and probabilistic_sharpe 0.0006. The 2:1 reward:risk never materialized because the dislocation CONTINUES rather than reverts — the tighter 0.5% stop is hit more often (win rate fell) and losers still exceed winners (avg_win 282 vs avg_loss 298). The loss is symmetric across direction (long 0.333, short 0.345). Three independent, statistically-confident negative runs establish that the mark-vs-index basis does not produce a tradeable ETH perp-PRICE reversion after fees.
Strategy report

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