Strategies
Pension Month-End Rebalancing Pressure on SPY: Fade the Month-to-Date SPY-minus-TLT Gap Over the Last Session of the Month, Then Reverse It Over the First 2 Sessions of the Next (SPY.USEQ 1-DAY, long-short, TLT signal-only, flat ~86%)
Outcome: Abandoned
PensionMonthEndRebalanceSpyTlt
Outcome Summary
PensionMonthEndRebalanceSpyTlt tried to trade against the month-end equity/bond rebalancing flow of balanced funds using the month-to-date SPY-minus-TLT gap. It passed backtest review with 514 trades and 0.162% per trade, and its full-period trade ledger reproduced the pre-study's Sharpe of about 0.55. After optimization it failed two hard gates (walk-forward overfit, CPCV OOS Sharpe 0.26 < 0.5), and holdout-window trades averaged -0.014%, so the analyst abandoned it after 2 iterations as no_edge. The analyst also flagged a suspected USEQ engine artifact for separate review: paired MTM swings on days with no open position, which distort Sharpe and drawdown.
Hypothesis
Iteration 2 fixes the one-session fill lag QA found. On USEQ a market order fills at the NEXT daily bar's close, so every decision now happens one session before its target fill date. G is computed and Leg A submitted at session n-2, so it fills at close(n-1). That is the hypothesis's own T-3 robustness variant, which QA replicated on catalog data at Leg A +0.211%/trade (t=3.72) and Leg B +0.204% (t=2.21). The flip is submitted at n-1 and fills at close(n). The Leg B exit is submitted at session leg_b_sessions-1 of m+1 (or at session n when leg_b_sessions=1) and fills at close(session leg_b_sessions). signal_offset now means the decision session counted from the month end (k = n - offset). Its bounds are unchanged at [2,4], because 1 would leave Leg A with zero length. Only the schedule block and the docstring changed. The signal, sizing, imports and structure are untouched. The same-bar close-then-enter flip is still used; it is correct in the backtest, but paper execution may want a single net order.
Implementation
SPY.USEQ daily, TLT signal-only. G = month-to-date SPY return minus TLT return (vs. last close of the prior month), measured at the T-3 close (session n-2). Leg A: short SPY if G>0, long if G<0, filled at close(n-1) and held to close(n). Leg B: flip to +sign(G) at close(n) and hold to the close of session 2 of the next month. Flat otherwise, about 86% of sessions. Sized at 95% of equity in whole shares.
Verification Results
For paper, submit one net order of 2x size (or target-position logic) at the flip. No change is needed for the backtest.
The Leg A to Leg B flip is done inside should_exit() as _submit_exit() followed by _submit_entry() on the same bar. In the backtest both fill at close(n) and are booked as separate trades, which I verified in the ledger. In a paper or live NETTING account, however, a reduce-only close and an opposite-side entry are in flight at the same time. If the close is rejected or fills only partly, the entry nets against it.
Optionally derive month sessions from src.data.market_calendar if it is importable within ALLOWED_IMPORT_ROOTS.
The strategy embeds its own XNYS holiday calendar instead of using src/data/market_calendar.py, which the project treats as the single source of session truth. I checked the observed-holiday rules, Good Friday, Juneteenth (from 2022), Carter 2025-01-09, Bush 2018-12-05 and Sandy 2012. They are correct, and the 2020-2026 fill dates in the engine land exactly on sessions n-1, n and session 2 of m+1, including 2023-07-05 after the July 4 holiday. But any unlisted special closure would shift n for that month.
Acceptable as pre-registered. The analyst should check worst-leg loss and drawdown against the hypothesis's 18.4% DD in the full backtest.
There is no stop and sizing is 95% of equity per leg (lev 1.0, whole shares, no dynamic scalar). Worst-case gross is 0.95 x equity, below the 2x Reg-T limit. Holds are 1-2 sessions with a flat state about 85% of the time, so this is not the always-in compounding pattern of L148. Still, the worst loss per trade equals one to two days of SPY moves: about 9% of equity on a March-2020-type day (2020-03/05 legs of -1.5% and -2.4%). That is above a 1-2% per-trade risk guideline.
Engine review of the USEQ impact/capacity model on SPY. Use the full-backtest ledger for per-trade economics.
The sandbox ledger in the brief is internally inconsistent: avg_trade_return_pct is +0.024% while avg_trade_pnl_usd is -6.57 and total_return is -1.02%. It also reports impact_cost_pct 148% and capacity_usd $45.6k on SPY, the most liquid ETF in the universe. None of these numbers can be reproduced from the current code (re-run: +0.334% per trade, +$58k). This looks like an engine or metrics artifact, or a stale run, not a strategy defect.
The Layer-3 sandbox metrics in the brief (total_return -1.02%, avg_trade 0.024%, PF 0.98) do not match the submitted code. I re-ran this exact code and config through BacktestRunner on USEQ from 2020-01-01 to 2026-09-26. Result: 158 trades, mean +0.334% per trade (Leg A +0.314%, Leg B +0.354%), net PnL about +$58k. That matches my offline catalog replication of the T-3 variant (2020 onward: A +0.29%, B +0.32%; full 2002-2026: A +0.211% t=3.72, B +0.204% t=2.21). The sandbox figure is probably stale (iteration-1 code) or from a different window. The analyst should judge on the full backtest, not the brief. Remaining doubts: 2020 is flat or negative (-0.04% per trade over 22 trades), and the result rests on about 290 monthly observations, i.e. 2 legs x 289 month-ends.
Backtest Review
- Sharpe
- 0.19
- Total return
- 91.42%
- Max drawdown
- 20.32%
- Trades
- 514
- Win rate
- 55.8%
- Profit factor
- 1.27
Sample is adequate: 514 trades from 2002-08 to 2023-12 (257 long, 257 short, balanced as expected for a -sign(G)/+sign(G) two-leg book). The holdout will hold about 100 trades.
The trades implement the hypothesis. I spot-checked Dec-2018/Jan-2019 and Nov/Dec-2023: a 1-session Leg A into the month-end close, flipped at the last close into a Leg B held 1-2 sessions into the next month, and flat mid-month. Leg A (217 one-day legs) averages +0.15% per trade.
Economics clear the USEQ floor. avg_trade_return_pct is 0.162% (0.138% on the realized trade ledger), against a floor of 0.05% and a preferred level of 0.10%. PF is 1.27 and win rate 0.56. Commission is zero by venue design; impact takes 17.7% of gross.
The realized trade ledger reproduces the pre-registered study. Per-trade t is 2.37, and the Sharpe of monthly returns built from trades is about 0.55, against the hypothesis's 0.58. 14 of 22 years are positive (64%, above the 60% floor). QA's re-run (2020-2026, +0.33% per trade) is consistent with this.
L170 beta screen: benchmark_meaningful is false, the book is long/short sign-alternating, time in market is 15.6%, and max DD of 20% is well below SPY's buy-and-hold DD (~55% in 2008). This is not beta.
SUSPECTED ENGINE ARTIFACT in the MTM equity curve (mechanism not verified). Every month there is a paired swing of -X% then +X% on consecutive mid-month sessions while the book is flat. Examples: 2019-01-18 -7.29% / 2019-01-22 +7.86%, 2020-03-02 -13.6% / 2020-03-03 +14.0%. No trade is open on those dates, which I checked in the trade ledger. There is also a -10.5% final bar on 2023-12-29. Each pair nets to about 0 and the magnitude grows steadily over time (0.07% in 2002 to about 10% in 2023). As a result, annualized_volatility (30%), max_drawdown (20.3%), the reported Sharpe (0.19, with a CI straddling 0) and PSR (0.67) are all contaminated. A 14%-exposure SPY book should run about 6% vol. The same symptom was flagged on the SPY weekly selector run. Needs engine review: MTM/impact folding for USEQ with a signal-only extra leg (TLT).
The backtest window ends 2023-12-29. The hypothesis's pre-study and QA's re-run extend to 2026-08/09, and that stretch is the period the hypothesis reports as strongest (Sharpe 1.02 in the last 20%). The holdout will therefore be roughly 2019-06 to 2023-12, which includes the weak 2018-2020 run (-4.8%, -6.5%, -4.9%).
QA concern partly confirmed: 2018-2020 were three consecutive losing years, and the edge is thin per unit of risk. QA's doubt that the brief's sandbox figures reflect this code is borne out: this full run matches QA's re-run, not the stale sandbox.
artifact-deflated; trade-ledger monthly Sharpe ~0.55
Analysis
Mechanism is correctly implemented. Trade records show a one-session Leg A (-sign(G)) filled at close(n-1) and held to close(n), then a Leg B flip held 2 sessions. Direction is balanced (257 long / 257 short), which matches the hypothesis.
Artifact-free trade ledger over the full 2002-2023 span: 514 trades, mean 0.136%/trade, t=2.34, monthly-aggregated Sharpe about 0.54. This reproduces the Research Lead's pre-study (about 0.58), so the in-sample effect is real.
The per-trade return of 0.14-0.16% clears the USEQ floor of 0.05%. PBO is 0.18. There are no parameter cliffs.
HARD failures (not waivable): walk-forward is flagged overfitted, and CPCV OOS Sharpe is 0.26, below the 0.5 validity floor.
The forward period does not hold up. Trades exiting in the holdout window (2017-10-23 to 2023-12-29, n=150) average -0.014% per trade, t=-0.13, which is zero edge on an adequate sample. 2018, 2019 and 2020 all lose (-4.8%, -6.6%, -4.9% summed trade return). Before the holdout (n=364) the mean is +0.198% with t=2.88. The effect is concentrated in 2003-2011 (2007-2009 alone gives about +41% of the roughly +70% summed). The hypothesis's claim of last-20% Sharpe 1.02 depends on 2024-2026 data that sits behind the locked vault. The 2017-2023 slice that could be observed does not show it.
SUSPECTED ENGINE ARTIFACT, mechanism not verified: the daily MTM series has large paired -X%/+X% swings on dates with no open trade. Examples are 2023-01-26 at -15.75% and 2023-01-27 at +18.70% (the trade ledger shows no position between the 01-04 exit and the 01-30 entry), plus about one such pair per month throughout. There is also a -16.2% print on the final bar, against a zero-PnL phantom short opened and closed on 2023-12-29. This is the same signature as the SPY majority/minority selector run earlier (paired MTM swings while flat, a final-bar loss while flat). These phantom days inflate annualized volatility to 47% and corrupt the Sharpe, OOS, holdout, DSR, drawdown (30.3%) and Calmar figures. The Sharpe rising with equity_fraction (0.16 to 0.24), which a real edge does not do, fits a roughly fixed-dollar noise term. My verdict does NOT rest on these contaminated numbers. It rests on the realized trade ledger above, where the forward period is flat.
The sensitivity sweep is degenerate. signal_offset, leg_b_sessions and min_abs_gap were never varied (all 5 variations are identical), so the only real free parameter was equity_fraction, which is sizing and not signal. The optimizer 'improved' Sharpe only by levering up to 1.42x.
Pre-registered predictions: 3 of 6 missed (min_oos_sharpe 0.55 vs 0.26, max_dd 22% vs 30.3%, PF 1.25 vs 1.24). The PF and drawdown misses may be artifact-driven. The forward-period trade mean of about 0 is not.
Benjamini-Hochberg at q=0.10 over 338 programme candidates keeps 8. A candidate that does not survive here is not distinguishable from the programme's own noise, however good its individual statistics look.
Iteration History
Outcome Summary
The month-end rebalancing effect showed up in-sample, mostly in 2003-2011, but a single-SPY daily calendar rule has not held since 2017; a new attempt needs a different form, such as MOC or intraday-close execution, futures, or a multi-asset panel.
The analyst abandoned it with failure code no_edge. Two gates that cannot be waived failed: walk-forward was flagged as overfit, and CPCV OOS Sharpe of 0.26 was below the 0.5 floor. The edge was also flat in the forward period, and 2018, 2019 and 2020 all lost money.
Trade SPY on daily bars (TLT used only as a signal) against the month-end rebalancing flow of balanced funds: short SPY into the last session of the month if SPY had outperformed TLT month-to-date (long if it had lagged), then take the opposite side for the first 2 sessions of the next month.
The initial backtest (1993-2023, 514 trades) returned 91.4% with an average trade return of 0.162%, a profit factor of 1.27 and an MTM Sharpe of 0.19. After optimization, CPCV OOS Sharpe was 0.26 and holdout Sharpe 0.12. On the realized trade ledger, trades in the holdout window (2017-10 to 2023-12, n=150) averaged -0.014% (t=-0.13), compared with +0.198% (t=2.88) before it.
Backtest and paper results are hypothetical. Trading involves risk of loss.