Strategies
Turn-of-the-Month Seasonal Long Overlay on SPY + QQQ (USEQ, Daily Bars, Own each ETF Only During the [-1,+3] Month-End Window Above its 200-Day Trend, Flat in T-Bill Otherwise, Commission-Free, 3-Parameter)
Outcome: Abandoned
TurnOfMonthSeasonalOverlaySpyQqqUseq
Outcome Summary
This strategy faithfully implemented a well-documented calendar anomaly — owning SPY and QQQ only around the month boundary and only above their own long-term trend — and its backtest looked clean enough on 33 years of data (PF 1.43, 60% win rate, per-trade edge above the USEQ fee floor) that the analyst approved it for optimization. Optimization was where it fell apart: the in-sample Sharpe of 0.87 collapsed to 0.019 out of sample, PBO hit 0.77, and the deflated Sharpe of 0.020 showed the result was statistically indistinguishable from noise across 225 trials. Three non-waivable hard gates failed simultaneously, so the analyst abandoned it after a single iteration. It joins a persistent family of abandoned turn-of-month variants, confirming the effect is too weak to generalize into a live overlay.
Hypothesis
Overfit with no out-of-sample edge: walk-forward OOS Sharpe 0.019 (< 0.5 validity floor) vs IS 0.87, per-window OOS 0.235/-0.017/-0.162, PBO 0.77 (> 0.5), and failed deflated Sharpe: DSR=0.020, expected-max=0.47 over 225 trials (43 effective) — the selected Sharpe is indistinguishable from best-of-N noise, does not survive programme FDR (4 of 272), is_significant=false. Three HARD gates fail (OOS<0.5, is_overfitted, PBO>0.5) so promotion is impossible. Per-trade edge clears the USEQ fee floor and the holdout Sharpe is nominally positive (0.36), but the turn-of-month effect is too thin to generalize as a tradeable overlay — the strategy fit in-sample noise. This matches a persistent family failure (turn-of-month seasonality abandoned on QQQ, BTC, BNB and adjacent USEQ trend variants); reframing the same mechanism onto yet another target has repeatedly re-overfit, so there is no salvageable reframe.
Implementation
Verification Results
Optionally derive the last-weekday anchor from the observed session bars (as _session_index already does) rather than a pure weekday count, so entry timing is holiday-aware like the exit. Not required.
Entry timing is anchored to calendar weekday arithmetic (_weekdays_left) which does NOT model US market holidays, whereas the exit is anchored to the actual session-bar count (_session_index) and is therefore holiday-robust. A month-end holiday landing on one of the last two weekdays (e.g. Memorial Day) shifts that single entry by one session. The developer documents this explicitly and it never changes the sign of the trade; src/data/market_calendar.py (XNYS) does exist and could tighten the entry, but the current approximation is acceptable and does not affect measurability.
No change needed if the base template invokes the subclass override for warm-up gating (it does). Left as informational.
min_bars_required(self) overrides a framework method (static-analysis base_shadow warning). This is deliberate here — it returns trend_sma_days + 2 to gate warm-up — and behaves correctly, but confirm the base honors the override rather than its own implementation.
Sandbox smoke test is marginal: Sharpe 0.107 (CI [-0.68, 0.94] straddles zero), avg_trade_return_pct 0.1535% (barely above the ~0.02-0.05% USEQ spread/impact floor), PF 1.15, win_rate 0.60. Regime split is unflattering — profit is concentrated in the 'normal' vol tercile (+10.44%) while 'calm' (-0.57%) and 'stressed' (-4.35%) both lose, and impact_cost_pct is 16.4% of gross with a modest $3.7M capacity. This is a real, well-documented calendar anomaly and the implementation is faithful, so it deserves a full backtest — but the analyst should confirm the per-window edge survives full-history spread+impact and is not confined to a single vol regime before optimizing.
Backtest Review
- Sharpe
- 0.19
- Total return
- 104.42%
- Max drawdown
- 12.25%
- Trades
- 500
- Win rate
- 60.2%
- Profit factor
- 1.43
Faithful implementation of a well-documented calendar anomaly (turn-of-month) on a 33-year full-history sample (1993-2026), 500 long trades / 0 shorts / ~28.5% exposure — trades match the hypothesis exactly (long-only seasonal overlay, flat in cash otherwise).
Edge clears USEQ costs comfortably: avg_trade_return_pct 0.338% (>> 0.05% abandon floor and >0.10% preference; passes L75), profit_factor 1.43, win_rate 0.60, impact only 7.9% of gross, capacity ~$15.9M.
QA's key concern is NOT borne out on full history: regime_performance is positive in ALL three vol terciles (calm +5.1%, normal +37.3%, stressed +35.4%, only_one_regime=false) — the calm/stressed losses were a truncated-sandbox artifact.
Low max_drawdown 12.2%, ample trade count for parameter fitting.
Headline Sharpe is low (0.194, CI [-0.12, 0.53] straddles zero) — but this is a mostly-cash overlay (28% time-in-market) measured on the full mtm equity curve, so idle cash dilutes it; judge risk-adjusted quality against exposure at the promotion stage, not here.
CAGR only 2.64% — an overlay by design; capital is idle ~72% of the time, so there is headroom to combine or scale rather than a defect.
Some down years (2008 -6.7%, 2022 -8.3%, 2016 -4.1%) but the anomaly is positive in the majority of calendar years.
Analysis
Faithful, low-turnover implementation of a well-documented calendar anomaly (turn-of-month) on a 33-year full-history sample; trades match the hypothesis (500 long / 0 short, ~28% exposure, seasonal-window entries above own 200d trend).
Per-trade edge clears the USEQ fee floor (avg_trade_return_pct 0.21% optimized, floor 0.05%); no sensitivity cliffs; drawdown low (6.1%); holdout Sharpe technically positive (0.36).
Sensitivity surface is flat/smooth across trend_sma_days and exit_trading_day — no fragile parameter.
Walk-forward is decisively overfit: IS Sharpe 0.87 vs OOS 0.019, and per-window OOS is 0.235 / -0.017 / -0.162 — the edge does not survive out of sample.
PBO 0.77 (> 0.5) — the parameter selection is more likely than not overfitting.
Deflated Sharpe 0.020 and PSR/is_significant=false; does not survive programme-level FDR (keeps 4 of 272; candidate p=0.98). The optimized Sharpe is indistinguishable from best-of-N noise over 225 trials (43 effective).
OOS Sharpe 0.019 << 0.5 validity floor — three HARD, non-waivable failures.
Preregistered predictions missed on the ones that matter: OOS Sharpe 0.019 vs declared 0.9, PF 1.39 vs 1.5, avg_trade_return 0.21% vs 0.30%.
Family prior is strongly negative: turn-of-month seasonality has been abandoned repeatedly on adjacent targets (QQQ TOM fee_edge, BTC TOM fee_edge, BNB TOM other, QQQ vol-managed trend overfit). The anomaly is real historically but too thin to clear costs/deflation on a tradeable overlay.
Benjamini-Hochberg at q=0.10 over 272 programme candidates keeps 4. A candidate that does not survive here is not distinguishable from the programme's own noise, however good its individual statistics look.
Outcome Summary
The turn-of-month anomaly is real historically but too thin to clear costs and multiple-testing deflation as a tradeable overlay; reframing the same seasonality onto yet another target (after QQQ, BTC, BNB failures) keeps re-overfitting rather than yielding a generalizable edge.
The analyst abandoned it after optimization: three HARD validity gates failed (OOS Sharpe 0.019 < 0.5 floor, is_overfitted true, PBO 0.77 > 0.5), the deflated Sharpe was indistinguishable from best-of-N noise over 225 trials, and it did not survive programme-level FDR, making promotion impossible.
A long-only turn-of-month seasonal overlay owning SPY and QQQ (USEQ, daily bars) only across the [-1,+3] month-end window and only when each ETF was above its own ~200-day trend, sitting in cash otherwise.
On the full 1993-2026 sample it made 500 long trades with a 0.60 win rate, profit factor 1.43, avg per-trade return 0.34% (0.21% optimized), CAGR 2.64% and max drawdown 12.2%, but headline Sharpe was only 0.194 (CI straddling zero). Optimization exposed decisive overfitting: walk-forward IS Sharpe 0.87 vs OOS 0.019 (per-window 0.235/-0.017/-0.162), PBO 0.77, and deflated Sharpe 0.020.
Backtest and paper results are hypothetical. Trading involves risk of loss.