Skip to content

View original

BtcSignalAltBasketBetaTimingLS

Hypotheses

BTC-Signal-Driven Diversified Alt-Basket Beta-Timing, Long-Short (Signal: BTCUSDT.BINANCE Momentum Confluence → Execute Equal-Weight ETH+SOL+BNB USD-M Perps in BTC's Direction, Pure OHLCV, 3-Parameter)

Hypotheses

A LONG-SHORT, MULTI-INSTRUMENT, pure-OHLCV strategy that uses the ONLY signal empirically shown to carry edge in this factory — BTC's dual-timeframe momentum confluence (the paper-stage survivor) — as an exogenous driver to time a DIVERSIFIED, equal-weight basket of three higher-beta alt perps (ETHUSDT, SOLUSDT, BNBUSDT), taking all three in BTC's confirmed direction. It is grounded in the session's exhaustive evidence: an alt's OWN price signal has NO edge (XRP, LINK, SOL, ETH all died 'no edge'), supplementary confirms fail on coverage/edge (taker, OI, premium abandoned), and only BTC price momentum is real — so this does not rely on any alt's own signal, only on BTC's proven leadership, which alts follow with higher beta. It is the risk-diversified evolution of my single-ETH lead-lag idea: a single alt carries idiosyncratic decoupling risk (an ETH-specific event mis-times the trade), whereas an equal-weight 3-alt basket averages that noise out and expresses cleaner BTC-led market beta, lowering variance for the same signal. It stays entirely in PURE OHLCV (the only reliably measurable, coverage-complete data — supplementary feeds hit coverage ceilings), is developer-safe (BTC signal + equal-weight basket execution, standard incremental indicators), measurable (~120-200 signal changes at the BTC-confluence cadence over multi-year history), and fee-viable (alt beta makes each leg's move ~1.2-1.5× BTC's, ~3-6% per 4H trend leg vs the ~0.10% fee). It fills the under-target LONG-SHORT (13.3%) and multi-instrument scope (19.1%) buckets. Only 3 parameters.

Hypotheses

Iteration 2 (post clean-restart). The feedback states the prior abandonment was a pipeline artifact -- the Layer-2 harness mis-bound @staticmethod helpers (already worked around here by keeping all helpers at module level and never using zero-arg super() on a rebindable event path), QA's terminal performance verdict on an unoptimized smoke test was removed, and the sandbox timeout was slot starvation. So the signal, the residual-lag gate, the exits and the execution plumbing are UNCHANGED from previous_code; every layer that passed stays passing (same imports, same class structure, same continuous signal that varies every bar including during warmup). The one substantive edit is the basket JOIN WINDOW: previously _manage_basket would keep re-testing non-qualifying legs on every bar for the entire life of a trade, so a leg could join many bars after the cross using a lag reading taken long after the entry, at a worse price and for an extra round trip of fees -- the basket was accumulated rather than established. Legs may now only join within basket_join_periods (locked at 1, enough to absorb intra-period bar-arrival order across four instruments) of the lead's opening period; integrity closing and wrong-side flattening stay unconditional so the basket can still only shrink afterwards. This tightens fee drag and keeps the entry timing honest without touching the mechanism under test. Venue stays BINANCE USD-M because the basket is taken short as well as long; leverage is 1.0 and no sizing path reads leverage, so the leverage_set_but_unused gate is not triggered. Honest note kept from before: this is the basket generalization of a single-name sibling whose edge came entirely from the lag gate; if per-trade return is still negative, the right conclusion is that spreading the transfer edge across three correlated alts dilutes it, not that another parameter needs tuning.

Hypotheses

Overfit / no-generalization, not a fee-edge death (per-trade return 2.23% clears the floor). Two unwaivable HARD gates fail: walk-forward is_overfitted=true with in-sample Sharpe 1.418 collapsing to out-of-sample 0.148 (all three OOS windows near zero: 0.015/0.101/0.328), and PBO 0.5317 > 0.5 (selection more likely than not overfitting). Robustness confirms the selected Sharpe is best-of-N noise: deflated_sharpe 0.375 << 0.95, is_significant=false, Sharpe CI barely off zero, and it does not survive programme-level FDR (keeps 3 of 235, candidate_p 0.625). Per the overfit-vs-dead-premise rule, high-IS/OOS-collapse is ABANDON not revise: the identical BTC-confluence->alt-execution mechanism has already died overfit on both single-name siblings (SOL lead-lag overfit 2 iters, ETH lead-lag overfit 2 iters), so re-pointing the same recipe at a 3-alt basket simply overfits again — the basket diversification did not add robustness the deflation could strip, and the sensitivity grid is flat (~0.6-0.9 everywhere, no cliffs) so there is no un-explored robust parameter region to tune toward. The oos_vault is itself flagged underpowered (~76 expected trades vs 100 needed), so this class is too slow for its own out-of-sample validation. Failure pattern: overfit / no-generalization (BTC-signal lead-lag alt momentum transfer).

Implementation

BTC's dual-timeframe momentum confluence (fast vs slow close-to-close move, both normalized to BTC ATR and made comparable per unit time via sqrt(slow_mult); signed-min when the horizons agree, a clipped average when they disagree) is the ONLY timing signal. On a fresh cross of +/- entry_thresh it takes an equal-weight (by dollar notional) long/short basket of higher-beta USD-M alt perps -- ETHUSDT (lead), SOLUSDT and BNBUSDT -- in BTC's direction, but only in the legs that still OWE the move: a leg is opened only if (btc_fast - leg_fast)/btc_fast >= 0.25, where each move is measured in that instrument's own ATR units so the comparison is beta-free. Legs may only join within one 4H period of the lead's entry, so the basket is established at the cross rather than accumulated mid-trade. Exits are structural and close the whole basket at once: confluence lost with 0.5x hysteresis, a BTC-ATR trailing stop measured on the driver, or loss of the lead leg. Pure 4-HOUR OHLCV, no supplementary data, leverage 1.0, 3 tunable parameters (mom_lookback, entry_thresh, trail_atr_mult).

Verification Results

Keep as-is if the base defers to this override for warmup; otherwise rename to avoid shadowing.

Verification Results

min_bars_required() overrides the framework method. This appears deliberate (returns max(mom_lookback*slow_mult+2, atr_period+2) so warmup covers the slow BTC horizon), and it reads from self.parameters, so it is not a defect — but confirm the base template honors the override for warmup gating rather than using its own implementation.

Verification Results

If tighter risk is desired, cap aggregate basket notional; otherwise no change — the lag gate structurally limits qualifying legs.

Verification Results

Per-leg notional is leg_frac (0.20) of equity, up to 3 legs = 60% gross; the ETH lead adds via position_size too. Sandbox shows avg_position_pct ~20% and exposure ~102%, so typically only 1-2 legs qualify at a cross (the lag gate prunes the rest), but under a broad simultaneous lag on all three, gross exposure to correlated alt beta reaches ~60% of equity at leverage 1.0. Not a bug, but worth confirming this is intended concentration.

Verification Results

This is a basket generalization of a single-name lag-gate sibling; the developer's own honest note warns that spreading the transfer edge across three correlated alts can DILUTE it. The smoke test does not confirm that fear (avg_trade_return_pct +1.76%, total_return +206%, PF 1.46), but Sharpe CI is [-0.073, 1.50] (spans zero), impact_cost_pct is 3.5% at turnover 54, and stressed-regime Sharpe is only 0.26 vs 1.31 normal. The mechanism is genuine (BTC dual-timeframe confluence is the paper-stage OHLCV survivor), but the analyst should confirm on full history that the residual-lag gate still clears fees + impact once three legs are averaged rather than one. Advisory only.

Backtest Review

403 trades over 6.7 years on 4 instruments — reliable sample, healthy trade-to-parameter ratio for a 3-param sweep

Backtest Review

avg_trade_return_pct 1.73% is ~11x the 0.15% Binance USD-M fee floor; the alt-beta amplification thesis survives full history and the QA dilution concern does not materialize

Backtest Review

Built on L82's one proven OHLCV mechanism (BTC dual-timeframe momentum confluence, the paper-stage survivor) used as an exogenous driver, not a dead alt-own signal

Backtest Review

Trades implement the hypothesis: 247 long / 156 short taken in BTC's confirmed direction — directional basket, NOT the dead beta-neutral multi-instrument class

Backtest Review

PF 1.385, DD 25.1% (<50%), CAGR 18.5%, capacity $58.8M, commission only 2.85% of gross, impact 4.1% — all viable

Backtest Review

Positive Sharpe in every vol regime (stressed 0.47 / normal 1.24 / calm 0.82) and PSR 0.915

Backtest Review

Sharpe CI low is ~0 (-0.0026) — the point Sharpe (0.75) is not yet distinguishable from zero; deflation/holdout must resolve this

Backtest Review

Win rate 39% — edge rests on win/loss asymmetry (avg_win 4019 vs avg_loss 1852), so it is trend-dependent

Backtest Review

end_unrealized_pct 27.2 — a meaningful minority of the headline is open-position MTM; realized track record (~175%) still dominates

Backtest Review

Basket generalization could still dilute the single-name transfer edge; walk-forward OOS is the real test

Analysis

Per-trade economics are healthy and clear the fee floor easily: optimized avg_trade_return_pct 2.23% vs the 0.15% Binance USD-M floor, PF 1.55, 444 trades over 6.7 years on 4 instruments (reliable sample) — this is NOT a fee/edge-below-cost death

Analysis

Holdout HARD gate passes: holdout Sharpe 0.819 with 88 trades, consistent_with_oos=true (z_vs_oos 0.582), and no sensitivity cliffs (cliff_count 0)

Analysis

Built on the one signal family that produced a promotion in this factory (BTC dual-TF momentum confluence, L82)

Analysis

Walk-forward flags is_overfitted=true: in-sample Sharpe 1.418 collapses to out-of-sample 0.148, with all three OOS windows near zero (0.015, 0.101, 0.328) against IS windows 1.63/1.27/1.35 — the edge is fit to the training windows, not a stable mechanism (HARD gate, unwaivable)

Analysis

PBO 0.5317 > 0.5 — the parameter selection is more likely than not overfitting (HARD gate, unwaivable)

Analysis

Robustness confirms noise: deflated_sharpe 0.375 << 0.95, is_significant=false, and it does NOT survive programme-level FDR (Benjamini-Hochberg keeps 3 of 235; candidate_p 0.625)

Analysis

The same BTC-confluence -> alt-execution mechanism has already died overfit on the single-name siblings: SOL lead-lag (overfit, 2 iters) and ETH lead-lag (overfit, 2 iters); diversifying into a 3-alt basket did not add robustness the deflation could strip

Analysis

The oos_vault itself is flagged UNDERPOWERED (~76 trades expected vs 100 needed) — this strategy is too slow for its own out-of-sample validation to be inferential

Analysis

Code↔hypothesis misalignment found by the semantic auditor — the code does NOT implement the hypothesis. Re-code the strategy to implement the hypothesis EXACTLY (instrument, timeframe, direction, the named edge/mechanic, sizing). Concrete issues: The hypothesis pre-registers a simple equal-weight three-leg basket taken in BTC's direction on every confluence cross ('taking all three in BTC's confirmed direction', 'does not rely on any alt's own signal, only on BTC's proven leadership'), but the code adds an un-described per-leg residual-lag gate (lag_frac=0.25) that conditions participation on each alt's OWN momentum measured in its OWN ATR units: _lag_ok/_leg_move (v3:308-356) require (btc_fast - leg_move)/btc_fast >= 0.25, should_enter aborts the entire entry when the lead ETH leg fails it (_lead_lag_ok, v3:519/550), and _manage_basket skips each non-qualifying or unmeasurable leg (v3:601). The code's own comments call this 'THE EDGE CONDITION'/'the actual edge', and the developer's rationale states it cuts gross exposure from ~75% to ~40% because typically only one or two legs qualify - so the tested strategy is a lead-lag catch-up trade on a filtered subset, not the equal-weight three-asset beta-timing basket whose variance-reduction premise is the hypothesis's stated reason for existing over the single-ETH sibling.

Analysis

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

Iteration History

Verification failed (Layer 2 — synthetic scenarios): Parameters used: ['leg_frac', 'bar_hours', 'exit_frac', 'slow_mult', 'atr_period', 'max_periods', 'entry_thresh', 'mom_lookback', 'min_notionals', 'trail_atr_mult', 'size_precisions', 'trail_reseed_max', 'signal_instrument_id', 'basket_instrument_ids'] Check that __init__ sets all attributes from self.parameters.get(). - steady_uptrend: TypeError: super(type, obj): obj must be an instance or subtype of type (bar timestamp: 1735689600000) - steady_downtrend: TypeError: super(type, obj): obj must be an instance or subtype of type (bar timestamp: 1735689600000) - flat_ranging: TypeError: super(type, obj): obj must be an instance or subtype of type (bar timestamp: 1735689600000) - volatility_spike: TypeError: super(type, obj): obj must be an instance or subtype of type (bar timestamp: 1735689600000) - zero_volume: TypeError: super(type, obj): obj must be an instance or subtype of type (bar timestamp: 1735689600000) - price_gap: TypeError: super(type, obj): obj must be an instance or subtype of type (bar timestamp: 1735689600000)

Iteration History

Verification failed (Layer 4 — QA review): - NET-NEGATIVE EDGE -- and it fails for a specific, diagnosable reason: this basket DROPS the residual-lag filter that is the actual edge in its single-ETH sibling. On a measurable 138-trade / 363-day sample (metrics_reliable=true): avg_trade_return_pct -0.140% (negative, below the fee floor on the wrong side), profit_factor 0.847, Sharpe -0.288 (CI [-1.84, 1.33]), total_return -13.4%, win_rate 0.355, expectancy -$97/trade. The hypothesis calls this 'the risk-diversified evolution of my single-ETH lead-lag idea', but it is actually a REGRESSION to the FAILED version of that idea. The single-ETH BTC->ETH lead-lag transfer only became a positive, fee-clearing edge (avg_trade +0.675%, PF 1.55 -- which passed) once iteration 2 added the RESIDUAL-LAG requirement: enter only when the alt still has >=25% of BTC's risk-adjusted move UN-transferred. Its iteration 1, which took the alt in BTC's direction on every confluence cross WITHOUT that lag check, was net-negative (avg_trade -0.087%, PF 0.90) -- and this basket reproduces exactly that mechanism (take ETH+SOL+BNB in BTC's direction whenever BTC confluence fires, no lag gating) and lands at the same net-negative result (-0.140%, PF 0.847). The basket diversification is a red herring: averaging three correlated alts reduces idiosyncratic variance but cannot create edge from a transfer signal that has none once the lag is already closed. Buying alt beta after BTC has already led (and the alts, being higher-beta, have already moved as much or more) is buying a completed move -- the late-entry pathology, three times over. - AMPLIFIED DRAWDOWN / TAIL from correlated basket beta -- even a positive version would run hot. max_drawdown 33.23 (CI [16.21, 57.47]), var_95 2.93, cvar_95 3.92 are the largest tail figures of the session, because three highly-correlated alt legs at leg_frac 0.25 each (~75% of equity gross) move together -- as the developer's own risk note concedes, 'this is ~75% of equity of correlated beta, not three independent bets.' A single wrong BTC call is amplified across all three legs at once (largest_loss -$4212). turnover 49.3 with six order legs per round trip also raises execution drag. Flag for the risk officer if a profitable variant is ever produced.

Iteration History

Verification failed (Layer 4 — QA review): - THE LAG GATE WORKED BUT THE BASKET DILUTES THE EDGE BELOW VIABILITY AND DOES NOT SCALE -- abandon it in favor of the single-ETH sibling, exactly as the developer's own honest bound recommends. Adding the per-leg residual-lag gate flipped this from net-negative (iter2: PF 0.847) to marginally positive (PF 1.046, avg_trade_return_pct 0.335%, total_return +1.83%, win_rate 0.393) -- which confirms the edge is the lag gate, not the transfer. BUT the basket expression is far weaker than the single-ETH BTC->ETH lead-lag that PASSED (PF 1.55, avg_trade +0.675%, Sharpe +0.60, capacity $100M): here Sharpe is 0.105 with a CI of [-1.50, 1.71] that STRADDLES ZERO (statistically indistinguishable from no edge), and -- decisively -- capacity_usd is only $1,528,359 with impact_cost_pct 25.6% (total_impact $629 vs total P&L ~$1,831, i.e. execution eats ~34% of gross). The thin edge therefore exists only at toy scale and does not survive real execution, because the basket trades less-liquid legs (SOL, BNB) and churns the whole basket on one exit. This is a strict DILUTION of the single-ETH trade: as the developer wrote, 'the lag-qualified alt is simply the sibling's single-name trade and the extra legs dilute it' -- the correlated ETH/SOL/BNB legs average the edge down toward noise while adding execution drag and correlated-beta risk, for a WEAKER, un-deployable version of an edge the single-ETH strategy already captures cleanly. - IMPLAUSIBLE RISK-METRIC UNITS + the gross-exposure fix worked. max_drawdown 16.79 (CI [8.49, 33.55]), var_95 1.72, cvar_95 2.50 remain >100% -- the session-wide normalization artifact, engine-side. NOTE the iteration-3 changes did reduce exposure as intended: avg_position_pct fell to 20.0% (from the ungated basket's higher gross), confirming the per-leg lag gate typically qualifies only 1-2 of 3 legs and leg_frac 0.25->0.20 helped -- so the correlated-beta concern from the prior review is materially improved. The blocker is edge/capacity, not sizing.
Strategy report

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