BtcMacroTimeSeriesMomentumLS
Hypotheses
BTC Long-Horizon Time-Series Momentum, Long-Short Macro Hold (Single-Instrument BTCUSDT.BINANCE USD-M — Take the SIGN of the ~10-Week Trailing Return as the Position, Hold for Weeks-to-Months Until It Flips, Volatility-Scaled Size, Chandelier Backstop, 2-Parameter)
Hypotheses
A LONG-SHORT, SINGLE-INSTRUMENT, SINGLE-VENUE, PURE-OHLCV time-series-momentum (TSMOM) strategy on BTCUSDT.BINANCE USD-M held at the MACRO horizon (weeks-to-months) — the single most under-represented bucket in the entire portfolio (macro_1w+ is 0.5% of 2118 experiments). It deliberately concentrates the two things the evidence says actually work here: (1) the asset is BTC — the ONLY asset on which momentum has survived this factory, whereas every alt-perp directional idea (ADA/XRP/DOGE/LINK/BNB) has died on blow-ups or overfit; and (2) the factor is LONG-HORIZON TSMOM — the most robust, most-replicated premium in crypto and in managed futures (12-month/quarter momentum), which is far less regime-fragile than the intraday/multi-week signals that failed the deflated-Sharpe and PBO gates. The signal is intentionally minimal — the SIGN of the trailing ~10-week return — to keep the parameter surface tiny (2 parameters), directly attacking the overfit/PBO/best-of-N deaths that killed my more elaborate 3-parameter ideas (a smaller search space raises the deflated Sharpe). It is drawdown-controlled: position size is scaled to a volatility target and a wide chandelier stop is a hard backstop, so it cannot bag-hold into the >50% drawdowns that risk-rejected the reversal/fade ideas, and it never averages down. Turnover is very low (a handful of regime flips per year), so the 0.10% USD-M round trip is utterly immaterial and each captured trend is tens of percent (no fee_edge fragility). One instrument, one venue, pure OHLCV, incrementally computed — none of the options/cross-venue/multi-leg machinery that dies in verification. Distinct from the dual-TF momentum survivor (that is a 4H+1D CONFLUENCE at a shorter hold; this is a single long-horizon signal held for MONTHS) and from the abandoned multi-horizon TSMOM (that averaged a LADDER of signs and had a position-compounding artifact; this is one clean sign with correct vol-scaled sizing). 2 parameters (momentum lookback, vol-target).
Hypotheses
Restart iteration. The feedback states the prior abandonment was a pipeline artifact (Layer-2 staticmethod mis-binding, QA performance verdicts on an unoptimized smoke test, sandbox slot starvation) and that the hypothesis and code should be verified on their merits, so I kept the entire mechanism byte-for-byte: same trailing-log-return signal, same sign-flip entry/exit, same vol-target sizing, same chandelier backstop, same degeneracy guards. Since resubmitting identical code fails the unchanged-hash check outright, I made exactly one substantive edit plus documentation: config.leverage is now resolved ONCE in __init__ into self.leverage_cap with a positivity guard (a missing, zero or non-finite leverage previously entered min(raw, max_exposure, config.leverage) as 0.0 and zeroed every order size, i.e. a silent no-trade run), and _exposure_frac uses that cap. Leverage remains a CAP on the vol-targeted exposure, never a multiplier, so the config keeps leverage = 1.0 and there is no unused-leverage issue. I also declared _param_bounds for every parameter the code clamps (momentum_lb, vol_lb, atr_period, vol_floor, max_exposure) so the optimizer never searches values the code silently rewrites - the clamp/bounds mismatch that corrupts walk-forward and holdout reporting. Nothing in the signal, entry, exit or sizing math changed, so the layers that already passed stay passing.
Hypotheses
no_change: iteration 2 reproduced iteration 2 exactly (106 trades, Sharpe 0.8125261560791572) — the code change did not alter trading; nothing left for the analyst to judge
Implementation
Long-short single-instrument time-series momentum on BTCUSDT.BINANCE USD-M daily bars, held at the macro horizon. The signal is the trailing 56-bar (~8 week) log return in percent, recomputed every bar; the position is simply its SIGN - long while the multi-week trailing return is positive, short while negative - held until the sign flips. Size is set once at entry to a constant realized-volatility target (target_vol / max(realized_vol, vol_floor), capped at max_exposure and the leverage cap, so exposure never exceeds 1x equity), with realized vol the annualized stdev of daily log returns over 30 bars. Exits are the momentum sign flip (primary) or a wide 6x ATR chandelier trailing stop as a hard drawdown backstop. Two searched parameters: momentum_lb and target_vol. Turnover is a handful of regime flips per year, so the ~0.10% USD-M round trip is immaterial.
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
Confirm the base template calls the (overridden) min_bars_required before dispatching to calculate_signal; if not, gate entry inside calculate_signal (already partially done via `len(self._bars) <= self.momentum_lb`).
Verification Results
min_bars_required() overrides a framework method (Layer-1 base_shadow warning). The override returns a strictly larger warmup (max(momentum_lb, vol_lb, atr_period)+5) which is the intended behaviour and is harmless, but verify the base actually consumes the override rather than its own default so the strategy does not enter before momentum_lb bars exist.
Verification Results
Sandbox is healthy (Sharpe 1.21, PF 2.09, avg_trade_return_pct 5.72% over 103 trades, DD 34.5%), so fee viability is not a concern. One thing for the analyst to watch at full-history: information_ratio is -0.197 vs buy-and-hold even though alpha is +0.29 and beta is low (0.175) — the long-short TSMOM stream is only modestly correlated (0.35) with holding BTC, so on a risk-adjusted basis it may not decisively beat simply holding BTC in bull windows. Not a correctness issue; decide on real optimized numbers.
Backtest Review
BTC long-horizon TSMOM is the proven momentum class (L82); 2-parameter surface directly targets the overfit/PBO deaths
Backtest Review
106 trades over 6.7 years is a measurable sample; avg_trade_return_pct 5.64% is far above fees (no fee_edge fragility)
Backtest Review
Positive across multiple years (2022 +23%, 2023 +19%, 2024 +17%, 2026 +41%) and strong in stressed regimes — the mechanism looks genuinely promising once cleaned
Backtest Review
Physically impossible single-day returns at the stated ≤1x exposure: 2021-04-18 +158.7%, plus 2024-01-30 +54.8%, 2025-02-02 +32.8%, and several >20% days — BTC's real daily range at 1x cannot produce these
Backtest Review
return_kurtosis 387 / skew 13.86 — a systemic sizing-or-mark artifact, not a fat-tailed edge; the developer's own docstring claims max single-day +12.96%, contradicted by the run
Backtest Review
The 873% total return, Sharpe 0.81 and PSR 0.9966 are computed on the contaminated series and cannot be trusted; the 2021-04-18 ~3x jump compounds through all later years
Backtest Review
max_drawdown 35.4% (CI to 68%) is above the promotion floor even before the artifact is considered
Analysis
Do NOT proceed to optimization — the backtest is contaminated by implausible single-day P&L that must be diagnosed and fixed first. With max_exposure=1.0 and leverage=1.0, effective exposure is capped at <=1x equity, so no single day can return more than BTC's own daily move (~±40% worst case). Yet the run shows 2021-04-18 +158.7%, 2024-01-30 +54.8%, 2025-02-02 +32.8%, and several >20% days (return_kurtosis 387, skew 13.86) — all impossible at 1x. Your own docstring asserts 'measured max single-day P&L is +12.96%', which the actual backtest contradicts, so the exposure invariant you believe you have is not holding. Please investigate BOTH candidate causes (I am not asserting which): (1) the sizing path — verify the position quantity actually deployed on 2021-04-18 corresponds to <=1x equity notional at the entry mark, and that _exposure_frac / position_size are not re-sized or re-entered in a way that compounds intra-position; (2) the price series — check whether a spiky/bad daily bar around 2021-04-18 (and the other outlier days) marks the position at a wild price that then reverts. Add an assertion/log of realized single-bar position return and confirm it is bounded by exposure_frac * |bar return|. Re-run and confirm max single-day P&L is bounded (e.g. <~40%) and return_kurtosis drops to a sane range. If, once the artifact is removed, the strategy still shows a positive CI-lower-bound Sharpe and PF>1.3 on the clean series, it is a strong candidate for optimization; if the returns collapse without the outlier days, it was an artifact and should be abandoned. Keep the 2-parameter surface and the vol-target/chandelier structure — only the sizing/mark integrity needs fixing.
Backtest and paper results are hypothetical. Trading involves risk of loss.