Skip to content
All strategies

Strategies

Price-vs-Basis Disagreement Resolution as an UN-TUNED 8-Name Event Panel: When a Major's 24h Mean Perp Premium Is >= 2 Sigma One Way While Its 24h Price Move Is >= 0.5 Sigma the Other Way, Take the Premium's Side for a Fixed 18h Clock (Binance USD-M 1H, independent single-name event legs, flat ~85% of name-hours, premium_index)

Outcome: Abandoned

PremiumPriceDisagreementPanel

Outcome Summary

After the analyst sent the single-name ETH premium-vs-price disagreement strategy back with a revise_hypothesis verdict (strong per-trade edge, but too few trades to survive deflation or FDR), the Research Lead restated it as a frozen 8-major event panel to increase breadth. On its first full-history backtest, the panel ran 830 trades and lost money: Sharpe -0.146, PF 0.908, -14.5% total return, and 4 of 7 years negative. Only ETH, SOL and LINK were positive, and losses on BTC, DOGE and the short side outweighed them. The strategy was abandoned at backtest review after 3 iterations. The reviewer also flagged two items for metrics and engine review: the sign disagreement between avg_trade_return_pct and the ledger, and recurring paired ±9-10% daily MTM swings.

Hypothesis

Restatement of the ETH price-vs-basis disagreement rule as a PANEL of independent single-name event trades, as the analyst recommended. The per-trade edge on ETH was real (0.5-1.25% per trade, PF 1.5-2.4, near-zero beta, positive holdout), but one coin fires only about 30 times a year and could not clear deflation. MECHANISM, stripped of instrument and timeframe (L138): 'when a perp's sustained premium to its spot index and its price move over the same window point in opposite directions at an extreme, trade in……Show moreShow less

Restatement of the ETH price-vs-basis disagreement rule as a PANEL of independent single-name event trades, as the analyst recommended. The per-trade edge on ETH was real (0.5-1.25% per trade, PF 1.5-2.4, near-zero beta, positive holdout), but one coin fires only about 30 times a year and could not clear deflation. MECHANISM, stripped of instrument and timeframe (L138): 'when a perp's sustained premium to its spot index and its price move over the same window point in opposite directions at an extreme, trade in the premium's direction for about half a day'. UNIVERSE: 8 Binance USD-M USDT perps with premium_index history in data/supplementary/premiumIndexKlines: BTC, ETH, XRP, SOL, ADA, LINK, DOGE, BNB. These are the pre-study breadth set plus the three largest remaining majors. The list is capped at 8 because L173 says baskets of 20-60 names time out. Point-in-time eligibility: a name can trade only after it has >= 60 days of 1H bars and premium data, which excludes SOL before about 2020-11, and only while its trailing 30-day dollar volume is >= $200M/day. The list itself is a 2026 choice. Declare it as a degree of freedom: count 8 names x 5 threshold cells x 3 clocks, about 120 trials, for deflation (L151). This is NOT a neutral book or a cross-sectional ranking (L137/L173). Each name is evaluated on its own series with the same frozen rule, and each position is an independent single-leg event trade. There is no ranking, no beta estimation and no hedging leg. Compute cost per bar is 8 rolling z-scores. SIGNAL (per name, 1H bar close, trailing data only via supp_as_of/supp_window): prem24 = mean of the last 24 hourly premium_index closes. z_prem = (prem24 - mean over 720h) / std over 720h. ret24 = 24h log return, and z_ret = ret24 / (std of 24h returns over 720h). FROZEN thresholds, not optimized: LONG if z_prem >= +2.0 and z_ret <= -0.5 (perp longs kept paying up while spot-led selling pushed price down). SHORT if z_prem <= -2.0 and z_ret >= +0.5 (perp shorts kept paying to hold into a spot-led rally). ECONOMIC CAUSE (unchanged): the side that pays is the finite, size-constrained spot flow (distribution into perp-long absorption, or a spot bid into perp-short resistance). Once it is absorbed, price resolves toward where the leveraged derivative crowd priced it. CLOCK: fixed 18h exit, the midpoint of the 12-24h plateau from the ETH pre-study (12h t 2.8, 24h t 2.5). The ETH optimizer's 12h sat on a cliff, so the developer/analyst MUST report the panel's calendar Sharpe for every clock in {8,12,15,18,21,24,30}h without refitting. If the Sharpe is not roughly flat across 12-24h, the edge is a fit. ANTI-OVERLAP: per name, no re-entry while a position is open and a 6h cooldown after exit. A new trigger during an open trade does not extend the clock. SIZING: equal risk per event. Notional per event = min(20% of equity, 1.0% of equity / (2.5 x ATR%(24h))), so each event risks about 1% of equity to the catastrophe stop. Leverage 2x account. At most 4 concurrent positions and at most 3 on the same side, which limits correlated majors all firing long in one crash (gross cap <= 80% of equity x 2x). Catastrophe stop at 2.5 x the name's 24h ATR from entry, checked on 1H closes. Otherwise the only exit is the clock. There is no take-profit, which keeps the parameter count at 2 thresholds + 1 clock + 1 stop multiple. FLAT STATE (L150): each name is in the market about 3-6% of hours. The panel has at least one position open about 15-25% of hours and is flat about 75-85% of the time. EXPECTED COUNTS: roughly 25-35 de-overlapped events per name-year at 2.0 sigma, so about 1,100-1,500 trades over 2020-2026 across 8 names. FEE ARITHMETIC: the pre-study breadth table at the same rule gave +0.47% to +0.92% gross per event (24h clock) across 5 names. Apply a haircut for the weaker added names (BTC's premium is less informative, so expect about +0.3%) and assume a panel mean of about +0.50% gross. Net of the 0.10% RT and about 0.05% slippage, that is about +0.35%, which is 3.5x the round trip. Expect the calendar Sharpe to scale from the single-name 0.4-0.75 by roughly sqrt(effective independent names). The majors are about 0.6-0.8 correlated, so N_eff is about 3, which gives a panel Sharpe of about 1.0-1.3. REQUIRED REPORTING: a per-name breakdown (trades, avg trade, PF), per-year returns and an ex-2021 result, long and short sides separately, and the clock plateau table.

Iteration 3 fixes only the Layer-3 timeout. Signal, sizing and exits are unchanged. Diagnosis: I profiled the iteration-2 code with py-spy in the same sandbox subprocess on the same 833-day, 8-leg 1H window. The run finished in 405-518s with 265 trades, Sharpe -0.15 and avg_trade_return_pct 0.163%. Of 8,026 samples, only about 630 (8%) were in strategy code. About 55% were NautilusTrader ParquetDataCatalog file discovery (fsspec glob/walk in _query_files, bars() and instruments(), run once per leg's bar type).……Show moreShow less

Iteration 3 fixes only the Layer-3 timeout. Signal, sizing and exits are unchanged. Diagnosis: I profiled the iteration-2 code with py-spy in the same sandbox subprocess on the same 833-day, 8-leg 1H window. The run finished in 405-518s with 265 trades, Sharpe -0.15 and avg_trade_return_pct 0.163%. Of 8,026 samples, only about 630 (8%) were in strategy code. About 55% were NautilusTrader ParquetDataCatalog file discovery (fsspec glob/walk in _query_files, bars() and instruments(), run once per leg's bar type). About 20% was _add_per_leg_premium_index loading the 1m premiumIndexKlines parquet for all 8 names (about 41s measured on its own). So per-bar strategy cost does not grow with the backtest span. The timeout comes from per-instrument infrastructure overhead that grows with leg count (L155 option c does not apply). The change here trims the strategy's own share: cache position lookups are now made only for legs with a tracked entry (_stop_dist), and the per-bar count of positions per leg drops from about 3 to 0 on flat legs (flat about 85% of name-hours). That saves at most about 30s of wall time, which is not enough on its own to bring a ~400s run under 300s. The only strategy-side lever that would is cutting legs, and that breaks the declared 8-name hypothesis (hypothesis_mismatch, L86).

Failure code: no_edge (premise_falsified), taken from this first measured full-history report. The frozen 8-name price-vs-basis disagreement panel ran 830 trades with Sharpe -0.146 (CI -0.89 to +0.63), PF 0.908 and total return -14.5%. The ledger's net per-trade return is -0.099%, below the 0.15% USD-M floor. The reported +0.089% avg_trade_return_pct disagrees in sign with the ledger and looks gross of costs (L116), so this needs a metrics review. It is not fee_edge, because the sign is negative even before the……Show moreShow less

Failure code: no_edge (premise_falsified), taken from this first measured full-history report. The frozen 8-name price-vs-basis disagreement panel ran 830 trades with Sharpe -0.146 (CI -0.89 to +0.63), PF 0.908 and total return -14.5%. The ledger's net per-trade return is -0.099%, below the 0.15% USD-M floor. The reported +0.089% avg_trade_return_pct disagrees in sign with the ledger and looks gross of costs (L116), so this needs a metrics review. It is not fee_edge, because the sign is negative even before the floor comparison. The breadth restatement falsified the assumption that the premium-disagreement edge generalizes across majors. BTC (PF 0.63, -$10.9k) and DOGE (PF 0.54, -$13.0k) lose more than ETH, SOL and LINK gain (PF 1.22 to 1.29, about +$11k combined). The short side loses -$22.4k. 2022-2024 and 2026 are negative. QA's concern was confirmed. The per-name winners are an after-the-fact selection from 8 names, and re-running on only those three would be cherry-picking. Note for the Research Lead: do not re-propose this mechanism as a panel of majors or as a hand-picked ETH/SOL/LINK subset. The ETH single-name form already failed deflation, and the panel shows the effect does not replicate out of name. Engine review, unverified: recurring paired -9% to -10% / +9% to +11% daily MTM swings and a -10.0% final-bar print while flat.

Implementation

8-name Binance USD-M 1H event panel (BTC, ETH, XRP, SOL, ADA, LINK, DOGE, BNB). Per name: z-score of the 24h mean premium_index against 720h, and z-score of the 24h log return. LONG when z_prem >= +2 and z_ret <= -0.5; SHORT on the mirror condition. Fixed 18h clock exit, catastrophe stop at 2.5x ATR24 checked on 1H closes, 6h cooldown per name. Each event risks 1% of equity with a 20% notional cap, at most 4 concurrent positions and at most 3 on one side, leverage 2x.

Verification Results

Drop '* self.leverage' so that notional = equity * frac, which matches the stated 1% risk per event and 80% gross; leverage 2x then serves only as margin headroom. Or keep it and fix the docstring so the analyst compares drawdown against a 2%-per-event book.

Per-event sizing multiplies by leverage: notional = equity * min(0.20, 0.01/stop_pct) * 2.0. The hypothesis says 'Notional per event = min(20% of equity, 1.0% of equity / (2.5 x ATR%)), so each event risks about 1% of equity'. As coded, each event risks about 2% of equity to the catastrophe stop, the per-event cap is 40% of equity, and worst-case gross is 4 x 40% = 160% of equity. The class docstring claims 'gross <= 4 x 20% = 80% of equity (fits 1x)', which contradicts the code. The sandbox avg_position_pct of 16.5% confirms the doubling. Risk stays bounded: 160% gross is within 2x venue leverage, the stop is 2.5 x ATR, and risk per event is 2%, which is within L148's 1-2% band. The hypothesis's own line 'gross cap <= 80% of equity x 2x' is also ambiguous. For these reasons this is a warning and not critical. Sharpe and PF are scale-invariant, but return, drawdown and Calmar are about 2x the pre-registered book.

Optionally reset a leg's rolling state, or skip signals, when the gap between consecutive samples exceeds 1h.

prem_h only receives a value when a premium sample exists within max_premium_age_hours (1h). After a gap in the premium feed, the '24h mean' covers more than 24 wall-clock hours. In the same way, closes, highs and lows are count-based deques that skip any hour missing a bar for that leg, so ret24 and the 24h range can span more than 24h after a data gap. On liquid Binance majors the effect is minor.

No change needed.

The notional floor is min_notional=10 in USD, and qty is rounded to 6 dp and then normalised to instrument precision by the base template. At risk_pct 1% and 1x-2x equity every event is far above $5 at any realistic equity, so this is fine.

The sandbox covered 834 days (2024-06 to 2026-09) with 266 trades: PF 0.96, Sharpe -0.37 (CI -1.60 to 0.86), total return -1.84%. The reported avg_trade_return_pct of +0.080% disagrees in sign with total return and with avg_trade_pnl_usd (-$6.93). Commission was $4,404 and net was -$1,844, which implies gross was about +$2,560. So the pct field appears to be gross of commission (L116 sign check: this is a metrics or ledger denominator issue, not strategy code). Read net of fees, the per-event edge is about zero,……Show moreShow less

The sandbox covered 834 days (2024-06 to 2026-09) with 266 trades: PF 0.96, Sharpe -0.37 (CI -1.60 to 0.86), total return -1.84%. The reported avg_trade_return_pct of +0.080% disagrees in sign with total return and with avg_trade_pnl_usd (-$6.93). Commission was $4,404 and net was -$1,844, which implies gross was about +$2,560. So the pct field appears to be gross of commission (L116 sign check: this is a metrics or ledger denominator issue, not strategy code). Read net of fees, the per-event edge is about zero, far below the pre-registered ~+0.35% net. Losses are concentrated in the calm vol tercile (-6.2%, Sharpe -1.77). Things to check first in the full 2020-2026 backtest: (1) net per-trade return per name, since BTC and BNB may dilute the ETH edge; (2) the required clock-plateau table {8..30}h; (3) whether the ETH-only edge survives at all on 2024-2026, which is the ETH holdout window. The developer's own recommendation ('abandon', local sandbox Sharpe -0.15) is about profitability and belongs here, not in a fail. Also note capacity_usd=713.91 and impact_cost_pct=1183 look like runner artifacts on 8 liquid majors. Do not read them as a strategy capacity limit without engine review.

Backtest Review

Sharpe
-0.15
Total return
-14.50%
Max drawdown
24.74%
Trades
830
Win rate
51.3%
Profit factor
0.91

The mechanism is implemented as specified: frozen 2.0/0.5 sigma thresholds, fixed 18h clock (avg hold 17h52m), per-name cooldown, balanced long and short sides (441 L / 389 S), about 15% average notional per event, and a flat state about 70% of the time.

The sample is adequate: 830 trades over 6.6 years on 8 names, metrics_reliable=true.

Three names show a positive net edge per ledger: SOL (+$4.4k, PF 1.25), LINK (+$3.7k, PF 1.29) and ETH (+$3.0k, PF 1.22).

The panel's net result is negative on an adequate sample. Sharpe is -0.146 (CI -0.89 to +0.63), PF is 0.908, total return is -14.5% and expectancy is -$17.5 per trade. This is a completed, falsified measurement under L141, not a tuning problem.

The breadth premise failed. Adding names diluted the edge instead of scaling it: BTC lost $10.9k (PF 0.63) and DOGE lost $13.0k (PF 0.54), and together they erase all of the gains from ETH, SOL and LINK. The short side lost $22.4k while the long side made $7.9k. By year: 2020 +2.7k, 2021 +0.9k, 2022 -5.8k, 2023 -6.8k, 2024 -3.7k, 2025 +0.4k, 2026 -2.0k. Four of seven years lost money, and every year from 2022 on is flat or negative.

Per-trade economics: the ledger's mean net pnl_pct is -0.099% per trade, against the 0.15% USD-M fee floor. Commissions were $11.9k, funding cost $2.9k and impact $5.7k. The reported avg_trade_return_pct of +0.089% has the opposite sign from the ledger (L116). That field looks gross of costs, which confirms QA's note. It is a metrics issue, not a strategy one.

QA's edge_concern was borne out. The sandbox's near-zero net edge carries over to the full 2020-2026 history. The calm vol tercile loses -25.7% (Sharpe -0.42).

Unverified artifact: several paired daily MTM swings of about -8% to -10% followed by +9% to +11% the next day (2025-04-14/15, 2025-07-15/16, 2025-10-15/16, 2026-01-15/16, 2026-04-17/18, 2026-07-18/19), plus a -10.0% print on the final bar with end_unrealized_pct=0. The realized trade PnL sum (-$14,503) matches total_return, so the verdict does not depend on these swings. They should still go to engine review (impact/MTM folding). I have not verified the mechanism.

Analysis

The per-trade economics are real at every tested setting. Base run: avg_trade 0.51% on 210 trades against the 0.15% USD-M floor (3.4x), PF 1.48. Optimized run: avg_trade 1.25% (8x the floor), PF 2.44.

No hard gate fails. CPCV OOS Sharpe is 0.62, PBO 0.17, not overfit. The holdout is positive (Sharpe 1.44, consistent_with_oos, z +0.66).

The result is not beta. Beta is 0.003-0.004, benchmark correlation 0.09-0.16, and max drawdown is 1.9-3.4% against ETH buy-and-hold drawdowns of roughly 70-80% over 2020-2026 (L170 does not apply).

Both sides contribute: 130 longs and 80 shorts in the base run, with long and short win rates both above 0.56. The trades match the hypothesis: long when premium is rich and price fell, short in the mirror case.

Profits are not concentrated in one year: the top year (2021) is 33.7% of PnL. The stressed-regime Sharpe is positive (1.17 optimized).

Significance fails. DSR is 0.68 (0.49 raw) against an expected-max Sharpe of 0.57 over 21 effective trials. The Sharpe CI [-0.02, 1.41] straddles zero. PSR is 0.68. The candidate does not survive the programme-level FDR (p = 0.32 against a threshold of 0.0015).

Sample size is too small. The optimized configuration (premium_entry_z 2.84) cuts trades from 210 to 62, below the 100-trade intraday floor that becomes HARD after the soak. The holdout has exactly 10 trades, the bare minimum. The pre-registered min_trades of 150 is missed. Under L178 this sample cannot be measured.

Only 4 of 7 calendar years are positive (57%, against a 60% floor that becomes HARD after the soak). Optimized results were 2022 -0.47%, 2023 -0.22% and 2026 -0.81%.

Sensitivity cliff on hold_hours. At the base setting (12h) Sharpe is 0.22. At 9.6h, 10.8h, 13.2h and 14.4h it is -0.02, 0.01, 0.01 and 0.02. Moving the clock by one hour erases the edge, which is the fingerprint of a lucky exit time. The optimizer then moved to 16.6h.

The duty cycle is too low. Exposure is 1.8% (4.3% base), and calendar Sharpe is 0.75 optimized, 0.42 base. This is the L165 case: excellent per-trade edge, but a flat-98% book cannot reach Sharpe 1.0. L134's promote floor (Sharpe >= 1.0) is not met.

Unverified symptom: the daily returns repeatedly show paired -X/+X days while the book is flat (for example 2025-10-15 -2.24 / 2025-10-16 +2.30, 2026-01-15/16, 2026-04-17/18). The same pattern appears in other runs today. This is probably a runner MTM/marking artifact that adds noise to Sharpe. It needs engine review. I have not checked the mechanism.

HARD after soak

not surviving

exactly 10 trades

L134 promote floor

The Research Lead REVISED this hypothesis because the previous premise did not work. Implement the REVISED hypothesis (see the hypothesis description) from scratch — do not reuse the prior strategy. Revision rationale: WHAT CHANGED: the single-coin ETH framing became an 8-name panel on Binance USD-M 1H with the SAME rule frozen at the un-tuned pre-study values (2.0 sigma premium, 0.5 sigma price). The analyst's evidence was that the per-trade edge exists but one name gives about 30 events a year, which cannot……Show moreShow less

The Research Lead REVISED this hypothesis because the previous premise did not work. Implement the REVISED hypothesis (see the hypothesis description) from scratch — do not reuse the prior strategy. Revision rationale: WHAT CHANGED: the single-coin ETH framing became an 8-name panel on Binance USD-M 1H with the SAME rule frozen at the un-tuned pre-study values (2.0 sigma premium, 0.5 sigma price). The analyst's evidence was that the per-trade edge exists but one name gives about 30 events a year, which cannot clear DSR 0.68, the 100-trade soak or the positive-years floor. The optimizer's 2.84 sigma and 12h clock were on a cliff, so I discard them: no re-tuned threshold, and the clock moves to 18h, the midpoint of the 12-24h plateau, with mandatory plateau reporting. WHY NOT A DUPLICATE OR BANNED FAMILY: this is not a neutral book (L137). Each position is a single-leg event on the instrument whose own premium generated the signal (no signal-on-A/trade-B, L143). It is not a cross-sectional ranking and is capped at 8 names (L173). It is not a longer clock (L166): 18h sits inside the measured forward-return peak. It declares a flat state of about 80% (L150). The supplementary key premium_index exists for BINANCE USD-M, where it was verified on disk for all 8 symbols (L160). VENUE: BINANCE USD-M is over-represented, but the mechanism requires the premium_index feed (Binance USD-M and HL only), and HL's 1H history of about 7 months is far too short (L168). The design needs shorts, which fills the under-represented long-short bucket. The ETH-only risk of a 2021-only edge is tested directly by the required ex-2021 and per-name tables. Predictions are set modestly: OOS Sharpe 0.9 and avg trade 0.30%, below the pre-study mean, to allow for dilution from BTC/BNB/DOGE.

Benjamini-Hochberg at q=0.10 over 345 programme candidates keeps 9. A candidate that does not survive here is not distinguishable from the programme's own noise, however good its individual statistics look.

Iteration History

sandbox_timeout: Verification failed (Layer 3 — sandbox backtest): smoke test exceeded the 300s wall-clock limit on a ~20000-bar window (833 days of BTCUSDT.BINANCE-1-HOUR-LAST-EXTERNAL). This almost always means per-bar work that scales with history — e.g. rescanning the full funding/supplementary series, or rebuilding a list and calling min()/sorted() inside calculate_signal()/on_bar() on every bar. Precompute sorted timestamp arrays ONCE in __init__ and use bisect, or cache lookups keyed by timestamp, so per-bar cost is O(log n) not O(n).

Outcome Summary

A per-trade edge found on one coin did not carry over to other majors, so widening the universe cannot rescue a single-name signal that failed deflation. Re-running on the after-the-fact winners (ETH/SOL/LINK) would be cherry-picking.

The backtest review gave an 'abandon' verdict (no_edge, premise_falsified): adding names diluted the edge instead of scaling it. BTC (PF 0.63, -$10.9k) and DOGE (PF 0.54, -$13.0k) lost more than ETH, SOL and LINK gained together, the short side lost $22.4k, and 2022-2024 and 2026 were negative.

It restated the ETH price-vs-basis disagreement rule as an 8-name Binance USD-M 1H event panel (BTC, ETH, XRP, SOL, ADA, LINK, DOGE, BNB). When a name's 24h mean perp premium was at least 2 sigma one way and its 24h price move at least 0.5 sigma the other way, it took the premium's side for a fixed 18h clock, using frozen thresholds and a 2.5x ATR catastrophe stop.

Over the full 2020-2026 history, the frozen panel made 830 trades with Sharpe -0.146 (CI -0.89 to +0.63), PF 0.908, total return -14.5% and max drawdown 24.7%. The ledger's net per-trade return was -0.099%, while the reported avg_trade_return_pct was +0.089%. The analyst's earlier single-name ETH review had shown a real per-trade edge (1.25% avg trade, PF 2.44, holdout Sharpe 1.44), but that result had only 62 trades, a DSR of 0.68, and failed the programme FDR.

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