Skip to content

View original

IntradayZStretchMeanReversionFadeMajorsLS15m

Hypotheses

Binance USD-M Intraday Mean-Reversion Fade (Majors BTC/ETH/SOL, 15-Minute, Extreme z-Stretch, Daily-Trend Regime Filter, Fast Exit, Long-Short)

Hypotheses

A short-horizon, long-short MEAN-REVERSION strategy on 15-minute bars across the three most liquid Binance USD-M majors (BTC, ETH, SOL) — the analyst-recommended correct-sign primitive for the short_1m_15m horizon bucket. The factory just empirically established that 15-minute breakouts on these majors WHIPSAW / mean-revert rather than continue (the sibling intraday breakout lost -98.5% precisely because the volatility extensions snap back). This strategy trades the OTHER side of that fact: when price stretches FAR from a short intraday mean by a large multiple of recent volatility, it fades the extreme (SHORT the over-extension up, LONG the over-extension down) and exits as price reverts to the mean. The crucial refinement over a naive mirror (which would inherit the breakout's fee drag) is a DAILY-TREND REGIME FILTER: it suppresses fades that lean against a strong daily trend, so it does not stand in front of the genuine trend days that produce the rare-but-large continuation losses that normally kill intraday mean-reversion. It is data-safe — MAJORS only, where full 15-minute history is confirmed (the broad-alt cross-sectional basket died on data_unavailable; majors do not) — and on pure Binance USD-M OHLCV, avoiding every infrastructure block this session (liquidations, COIN-M, Deribit, Hyperliquid, multi-leg funding). It is distinct from the 4H volume-climax reversal already in the pipeline (different horizon and signal: intraday z-stretch vs daily-grain volume capitulation). Long-short improves the 87%-long skew; the strict stretch threshold + fast exit is the fee-domination defense; few parameters resist overfitting.

Hypotheses

Iteration-3 fix for the Layer-3 300s wall-clock timeout. Root cause: on every new 15m bar for each of 3 majors the code rebuilt two numpy arrays via list comprehensions calling bar.close.as_double() 20 + 96 times (the z-window and the 96-bar daily-trend SMA), a heavy constant-factor scan repeated across ~1M bar events. Smallest change that removes it: keep ALL trading logic byte-for-byte (entry z-threshold, daily-trend filter, z-stop, gross cap, exits, sizing) but replace the numpy/as_double recomputation with incremental rolling statistics — per-asset collections.deque(maxlen) buffers plus running sum and sum-of-squares, updated once per new bar in _update_stats (subtract evicted value, add new). z/mean/std come from Sx and Sx2 (var = Sx2/n - mean^2) and the trend SMA from its running sum, all O(1) per bar with a single as_double() call, eliminating the per-bar numpy allocation and 116 Bar method calls. Float drift is negligible at these window sizes. Imports stay clean (added only stdlib collections.deque; numpy retained for isfinite). No signal, threshold, or sizing behavior changed, so earlier layers stay green and only the wall-clock regression is fixed.

Hypotheses

Matches the known sub-1H-majors fee-domination failure pattern and cannot be rescued by optimization. The strategy is fee-dead by construction: commission_pct_of_gross = 33.2% on 14,861 15-minute trades across BTC/ETH/SOL, and the mean-reversion edge is negative from the very first month (PF 0.57, expectancy -10.3, avg_loss 45 > avg_win 28, every 2020 month negative) — this is the same fee/noise-dominated 15m-majors horizon where the sibling breakout lost -98.5%; fading the same horizon loses the same way. It also liquidated on 2021-02-05 (total_return -100%, leveraged -76.8%/+113%/-126% death-throe days) leaving 5+ years of dead 0.0 returns. No parameter region fixes a 33%-of-gross fee drag while preserving the 15m mean-reversion premise — reducing turnover enough to beat fees means abandoning the thesis for a slower horizon (already covered by the promoted daily/weekly trend baskets). This is a fundamental horizon-choice failure, not a fixable bug, so iterate/optimize would waste effort on a structurally money-losing, fee-dominated signal.

Implementation

Long-short intraday z-stretch mean-reversion fade on 15-minute bars across BTC/ETH/SOL. Fades extreme extensions (|z|>=2.5 from a 20-bar Bollinger mean) — SHORT over-extensions up, LONG over-extensions down — exiting fast on reversion to the mean (|z|<=0.5), a z-based stop (4 std), or a 16-bar max-hold. A daily-trend regime filter (96-bar SMA deviation) suppresses fades leaning against a strong daily trend. Risk-equalized z-stop sizing, per-book notional cap, and a 1.0x portfolio gross cap. Rolling z and trend statistics are maintained incrementally (running sum / sum-of-squares over fixed deques) so per-bar cost is O(1).

Verification Results

Verification failed (Layer 3 — sandbox backtest): smoke test exceeded the 300s wall-clock limit. 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).

Backtest Review

Data-safe (majors-only 15m OHLCV, confirmed history) and the mean-reversion sign is the analyst-recommended primitive for the whipsaw fact.

Backtest Review

Incremental O(1) rolling stats and a trend-regime filter are competently implemented; the strategy runs and trades (14,861 trades).

Backtest Review

Fee-dominated: commission_pct_of_gross 33.2% ($65.8k) — the hypothesis's 'strict threshold + fast exit' fee defense demonstrably failed at 15m grain across 3 majors.

Backtest Review

Negative edge from the first month: every month of 2020 negative, PF 0.57, expectancy -10.3, avg_loss (45) > avg_win (28) — a consistently losing signal, not regime decay.

Backtest Review

Liquidated 2021-02-05 (total_return -100%, max_dd 100%) with leveraged blow-up days (-76.8%/+113%/-126%); ~5.5 of 6.5 years are dead 0.0 returns.

Backtest Review

Matches the established sub-1H-majors fee/noise-death pattern that already killed the sibling 15m breakout (-98.5%).

Backtest Review

negative

Outcome Summary

This strategy tried to profit from the empirical finding that 15-minute moves on BTC/ETH/SOL whipsaw rather than continue, fading extreme volatility stretches back to the mean with a daily-trend filter and fast exits meant to keep fees in check. In backtest it traded 14,861 times over 6+ years but lost money from the very first month (profit factor 0.57, negative expectancy, avg loss larger than avg win), with commissions eating 33.2% of gross before liquidating to -100% in February 2021. The analyst abandoned it at the backtest-review gate after 3 iterations, judging it a fundamental horizon-choice failure — the same fee-domination pattern that had already killed a sibling 15m breakout — rather than a fixable bug. The takeaway: intraday mean-reversion on majors is fee-dead by construction, and reducing turnover enough to beat costs would mean abandoning the intraday premise for the already-covered daily/weekly trend baskets.

Outcome Summary

A 15-minute mean-reversion signal on liquid majors cannot survive round-trip fees no matter the parameters — beating a 33%-of-gross fee drag requires a slower horizon, which abandons the intraday thesis entirely.

Outcome Summary

The analyst issued an 'abandon' verdict at the pre-optimization backtest-review gate: the strategy is fee-dominated and structurally money-losing at the 15m-majors horizon, matching the same fee/noise-death pattern that killed the sibling breakout (-98.5%), so it never advanced to optimization or later stages.

Outcome Summary

A long-short intraday mean-reversion strategy that fades extreme z-score stretches from a short 15-minute mean on Binance USD-M majors (BTC/ETH/SOL), gated by a daily-trend regime filter and a fast exit to defend against fee drag.

Outcome Summary

Over 2,345 days it ran 14,861 trades with a 47.8% win rate but a negative edge from the first month (profit factor 0.57, expectancy -10.3, avg_loss 45 > avg_win 28, Sharpe -1.11), and commissions consumed 33.2% of gross ($65.8k). It liquidated on 2021-02-05 for a total return of -100% and a 100% max drawdown.

Iteration History

Verification failed (Layer 2 — synthetic scenarios): Parameters used: ['assets', 'exit_z', 'stop_z', 'entry_z', 'risk_frac', 'z_lookback', 'min_notional', 'trend_thresh', 'max_hold_bars', 'qty_precision', 'gross_cap_frac', 'trend_lookback', 'max_position_frac', 'default_qty_precision'] 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)
Strategy report

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