Skip to content

View original

SolWeekendLullMeanReversionLS

Hypotheses

SOL weekend lull mean-reversion

Hypotheses

SOL/USDT futures weekend mean-reversion. During the low-volatility weekend window (Saturday 00:00 through Sunday 23:59 UTC), fade intraday range extremes: when the 1H close stretches a configurable number of standard deviations (param: entry_sigma, default ~2.0) beyond a short rolling mean (param: ma_period on 1H bars, e.g. 20-EMA), enter a counter-trend position expecting reversion toward the mean. Long when stretched below the mean, short when stretched above. Exit on: (a) reversion back to the mean, (b) a stop beyond the extreme (param: stop_sigma), or (c) a hard time-stop flat at Monday 00:00 UTC. No positions held into the weekday session. Size relative to account equity via get_account_equity() for the ~0.8% hourly-vol weekend regime. Reversion target must clear round-trip fees (>0.15% of notional on Binance USD-M futures). Venue: BINANCE (USD-M futures), instrument SOLUSDT, primary bar_type 1H.

Hypotheses

NO BEHAVIOURAL CHANGE, AND THAT IS THE DELIVERABLE. Layer 4 rejected this as 'structural, not parameterisable' with a deflated-Sharpe signature (max |t| = 1.73 across 81 cells vs ~2.82 expected under pure noise - the best cell is weaker than chance). My own iteration-2 note had already conceded the defaults were below the 0.15% floor. Rather than ship a fourth tuned variant, I re-derived the question independently on the full SOLUSDT 1H catalog (51,497 bars, 2020-09 to 2026-07) at the real 0.10% round trip, and I CONFIRM the falsification - while adding the mechanism QA did not state. Three findings. (1) The weekend lull is real (1.091% vs 1.332% hourly stdev) but it is not the source of any edge: at ma=12 the WEEKDAY fade is as strong or stronger than the weekend fade at short horizons (+3h weekday +0.091%/t=3.1 vs weekend +0.077%/t=1.6; +6h weekday +0.093%/t=2.4 vs weekend +0.135%/t=2.1). The regime premise - the entire content of this hypothesis - adds nothing over a generic fade. (2) THE STRUCTURAL KILL, which is new: the weekend fade drift that does exist peaks at 12-24h (+0.30% to +0.54% gross, t~2.3-2.5) and has INVERTED by 48h. That reversion horizon is a large fraction of the 48-hour weekend window itself, so the hypothesis's own mandated Monday-00:00 flat systematically truncates exactly the drift that carries the edge. The constraint destroys the edge it exists to harvest, and no parameter can relax it without abandoning the hypothesis - which is precisely why it is 'not parameterisable'. (3) I tested the one structural lever left, replacing the mean-touch target with a horizon-matched 12h/24h hold (the same fix that rescued a different strategy earlier today). It does not work here: 12h/stop15 -0.011%, 12h/stop4 -0.084%, 24h/stop4 -0.115%, 6h/stop4 -0.099%, and the least-bad cell (es=3.0, 12h, stop 6.0) is +0.159% at t=0.92 on n=397 while being negative in 4 of 7 years including each of the last three. I deliberately did NOT ship that cell: at t=0.92 it is indistinguishable from noise, it would clear the 0.15% floor on a technicality, pass QA, and then die at the walk-forward/PBO gate after burning a full backtest plus a 3-phase optimization - the exact failure pattern recorded for BtcCmeWeekendGapFillReversionLS and EthFundingSettlementReversionLS, both abandoned at iteration 3 after the same kind of chase. So the change is confined to a recorded EMPIRICAL STATUS block in the module docstring, preserving the measurements so no future iteration re-derives them, with every parameter and every line of executable logic byte-identical to previous_code (Layers 1-3 cannot regress). Worth noting for the Research Lead: the generated/ directory already holds ~20 SOL weekend strategies across four distinct mechanisms (overshoot reversal v1-v3, volatility spike MR v1-v4, volatility breakout v1-v6, volatility regime breakout), which suggests the SOL-weekend seam is thoroughly mined rather than under-explored. RECOMMENDED DISPOSITION: ABANDON. If the short-horizon fade is worth pursuing at all, the data points to an UNGATED 3-6h fade on weekdays as much as weekends - a different hypothesis that the Research Lead should own, not something I should smuggle in under a weekend-lull title.

Hypotheses

Premise falsified — a net-losing single-name weekend mean-reversion fade with an edge far below trading costs (L55/L22). Over 612 trades (a measurable sample): total_return -30.8%, profit_factor 0.77, expectancy -$49/trade, avg_trade_return_pct 0.031% (below the 0.15% Binance USD-M fee floor, commissions 16.5% of gross), Sharpe -0.256 with CI [-1.07,0.58] straddling zero, information_ratio -1.09, losing in 5 of 7 years and in all three vol regimes. avg_loss ($555) is 2x avg_win ($275) — the inherent payoff asymmetry of target=mean/stop=beyond-extreme. The kill is structural: the developer's own re-measurement shows the weekend fade drift peaks at 12-24h and inverts by 48h, so the hypothesis's mandated Monday-00:00 flat truncates exactly the drift that carries the edge, and the regime premise adds nothing (weekday fade is as strong or stronger). Best-of-81-cells t=1.73 is weaker than the 2.82 pure noise would produce — a dead-edge signature. No parameter tuning flips a -0.03%/trade edge above fees; the constraint that defines the hypothesis is what destroys it. Failure pattern: fee_edge/no_edge single-name weekend mean-reversion fade with premise falsified. Not worth 2 hours of optimization.

Implementation

Long/short weekend mean-reversion on SOLUSDT.BINANCE USD-M perpetual (1H bars). Each bar it returns -(close - EMA)/stdev(residual) over ma_period as the continuous signal, so the sign is the trade direction. Entry is gated to the Saturday 00:00 - Sunday 23:59 UTC window (derived arithmetically from bar.ts_event, so the schedule is restart- and replay-identical) and requires |z| >= entry_sigma with |z| < stop_sigma so the setup still has room. Exits, first to fire: an unconditional Monday-flat on the first non-weekend bar, a protective stop at stop_sigma beyond the mean tested intrabar, and the reversion target when the moving average is touched intrabar. Sizing risks 2% of equity at the stop and is independently capped at 50% of equity notional. BEHAVIOURALLY UNCHANGED from iteration 2 - the only edit is a recorded falsification block in the module docstring.

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

Decisively negative, well-sampled edge (244 trades, PF 0.65, avg_trade_return_pct -0.10%, -17.3%) whose failure is structural not parametric: the weekend regime adds no edge over a generic fade, and the mandated Monday-flat truncates the 12-24h drift horizon. Code faithfully implements the hypothesis (target=mean/stop=beyond-extreme geometry gives the inverted payoff by design), so a mechanism/premise finding for the analyst. Abandon at backtest-review per the developer's pre-registered condition; do not optimize; stop generating SOL-weekend variants.

Backtest Review

Faithful, well-engineered implementation: timestamp-derived weekend schedule, restart-safe indicators, capital-relative sizing, hard Monday flat — no defect to fix

Backtest Review

612 trades over 6 years is a large sample, so the negative verdict is statistically reliable, not an unmeasured artifact

Backtest Review

Net loser: total_return -30.8%, negative in 5 of 7 years; profit_factor 0.77, expectancy -$49/trade

Backtest Review

avg_trade_return_pct 0.031% — far below the 0.15% Binance USD-M fee floor (L22); commissions 16.5% of gross

Backtest Review

Sharpe -0.256 (CI straddles zero), information_ratio -1.09, PSR 0.37 — no risk-adjusted edge; avg_loss 2x avg_win (L55 fade payoff asymmetry)

Backtest Review

Structural kill: reversion horizon (12-24h, inverts by 48h) is a large fraction of the 48h weekend window, so the mandated Monday-00:00 flat truncates the very drift that carries the edge — unfixable by parameters

Backtest Review

Regime premise adds nothing: weekday fade is as strong or stronger than weekend; best-cell t=1.73 < noise-expected 2.82

Iteration History

Verification failed (Layer 4 — QA review): - STRUCTURAL FEE-VIABILITY FAILURE (documented over the full history, not just the sandbox window). Sandbox avg_trade_return_pct = +0.021% net per trade over 98 trades — essentially zero and far below the 0.15% futures floor — with total_return -6.2%, PF 0.80, Sharpe -0.70. This is NOT a small-sample directional miss with large fee-clearing moves; the weekend low-vol regime produces small ~1% moves that net ~zero after the 0.10% round trip. The developer's OWN 6-year, 27-cell grid came out net-negative in EVERY cell (least-bad -0.091% at the shipped defaults), best case ~+0.12% (below the 0.15% floor, not significant, t=1.74). Root cause is structural: the reversion needs ~12h but any risk-bounding stop is hit first. The developer explicitly predicted this Layer-4 failure.

Iteration History

Verification failed (Layer 4 — QA review): - Per-trade edge is below the fee-viability floor and the strategy is net-negative. Layer-3 sandbox (real SOL USD-M fees): avg_trade_return_pct = 0.109% < the 0.15% futures floor; total_return −3.91%, Sharpe −0.77, PF 0.78, negative expectancy over 104 trades. Win rate 61.5% but avg_loss (~$451) ≈ 2× avg_win (~$221) — the weekend low-vol regime makes reversion likely but the moves too small to clear the ~0.10% round trip. Structural, not parameterisable. - Core edge (weekend mean-reversion) empirically falsified across 81 cells / 6 years: max |t|=1.73 vs expected max-|t|≈2.82 under pure noise (best cell weaker than chance — deflated-Sharpe signature), ragged non-monotone stop response, decayed recent years (2023 −0.090%, 2025 −0.193%). The code faithfully implements the hypothesis; the edge is not in the data.

Iteration History

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).
Strategy report

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