# The turn-of-the-month effect on SPY, daily closes - specification (RIP Backtest protocol v1.0 plus the 8 Oct 2026 rules)

Specification written and **frozen 2026-11-04 (approved by the owner the same day: "Da, îngheață și rulează"; draft 1 unchanged)**. No turn-of-the-month window, trade, return or equity curve of this test has been computed. Nothing new was looked at in the data: it is the SPY file of the SMA 200 test (checked then: row counts, date range, gaps, prices, total-return index; hashes below). Once frozen, any change of a rule is documented and treated as a separate test; bugs may be fixed and are logged at the end.

## Why this test, and where the rule comes from
- **Chosen by the owner** on 2026-11-04 ("Turn of the month") from three proposals (turn of the month on SPY, the pre-FOMC drift, night versus day on SPY).
- **The effect.** US stocks have earned much of their return around the turn of the month. Ariel ("A Monthly Effect in Stock Returns", Journal of Financial Economics, 1987) found returns concentrated in the first half of trading months, from the last trading day of the previous month. Lakonishok and Smidt (Review of Financial Studies, 1988) located it in the last trading day and the first three trading days of the month, over 90 years of the Dow. McConnell and Xu ("Equity Returns at the Turn of the Month", Financial Analysts Journal, 2008) found that from 1926 to 2005 the average excess return of the US market outside that four-day window was about zero, and that the effect was not limited to small stocks or to month-ends of quarters.
- **Why it could work.** Money arrives at the start of the month: salaries, pension and retirement-plan contributions, fund inflows; some managers also dress their books at the month's end.
- **Why it might not (written before the run).** It has been in print since 1987, and published anomalies tend to shrink after publication (McLean and Pontiff, Journal of Finance, 2016). Our data start in 1993, six years after the first paper. A four-day window also catches the market's general rise; the control below separates the two.
- **Looked at before on the site:** SPY daily bars 1993 to 2026 in the SMA 200 and Accumulation/Distribution tests (both on this file), so the holdout below is already used. No calendar rule has been tested on stocks.

## Instrument and data
- **SPY**, daily bars **1993-01-29 to 2026-10-20** (8,489 trading days), `data_spy/spy_daily.csv` and `spy_dividends.csv` (136 dividends), extracted by `spy_parse.js` from the Yahoo Finance history page saved by the owner on 2026-10-21; cash: FRED DTB3 (`data_spy/dtb3_fred_raw.csv`). File hashes (SHA-256, first 16 characters): spy_daily.csv 8de2b35662134fe5, spy_dividends.csv f6a7857257bbd23c, dtb3_fred_raw.csv 0ba63bf126e01aa6. The only gaps longer than 4 days are the market closures of September 2001, 2 January 2007 and October 2012.
- **Trading days** are the days in the file (the exchange's trading days; the three closures above are not trading days). Their position in a month is counted from the file: day -1 is the last trading day of a month, day +1, +2, +3 the first three trading days of the next.
- **Total return:** close plus each dividend reinvested at the ex-date close, as in the SMA 200 test.

## Rule (one variant, fixed now)
- **TOM:** buy at the **close of day -2** (the second-to-last trading day of the month) and sell at the **close of day +3** (the third trading day of the next month). The trade earns the returns of days -1, +1, +2 and +3: the window of Lakonishok and Smidt and of McConnell and Xu.
- **Fills at the close** (market-on-close orders). The days are known in advance from the calendar, so no signal is used.
- Long only, all-in, one trade a month; no stop, no target. A month turn that is not complete in the file (the first, January 1993, whose day -2 is before the data, and any after the last full one) is not traded.
- Growth of a trade bought at the close of day j and sold at the close of day k: prod over i = j+1..k of (close[i] + dividend[i]) / close[i-1].

## Costs
- **0.04% of the price per round trip** (0.02% a side), as in the SMA 200 test; 0.10% shown as a scenario. No commission. The verdict is that of 0.04%.

## Results, periods, gates, control
- **Unit:** net % per trade (total return, close to close, minus the cost).
- **Periods (by entry date), as in the SMA 200 test:** development 1993 .. 2005; validation 2006 .. 2015; holdout 2016 .. 2026-10-20 (**already used** by the SMA 200 and Accumulation/Distribution tests).
- **Six gates:** validation profit factor >= 1.2; at least 50 trades in each period; development **t >= 2.0** (one variant of a strategy not tested before on the site); above the 95th percentile of 500 runs of the matched control; positive without the 10 best trades; holdout net positive (flagged used). Fewer than 30 trades: Inconclusive.
- **Matched control (random four-day holds in the same months):** for each real trade, a hold of the same length in trading days (4) whose entry close is a trading day drawn at random, uniformly, from the same calendar month as the real entry (any day of that month whose exit falls inside the data); same costs. 500 runs, seeds 1000 + run. Statistic: average net % per trade. It keeps the number of trades, their length and their months, and removes only the position inside the month (the market's rise is in both).

## Also reported (descriptive, after the gates; nothing here can change the rule or the verdict)
- The whole strategy with T-bill interest while out (DTB3 / 360 per calendar day, as in the SMA 200 test) against buy-and-hold SPY: yearly growth, worst drawdown at the close, share of days invested.
- The rest of the month: the same trades' complement (invested from the close of day +3 to the close of day -2), average net % per trade.
- The average return of each trading day from day -5 to day +5 around the turn, and of the days in between.
- Neighbouring windows: -2..+3, -3..+3, -1..+2, -1..+4, -1..+1, with the same periods, gates and control.
- Year by year; by period; without the 10 and the 20 best trades; quarter-end months against the other months; win rate with its Wilson interval.

## Engine and self-test (before the run)
New engine `tom_lib.js`, an independent re-implementation `tom_ref.js`, and `tom_selftest.js`, which must pass before any result is printed: hand-built months (a month ending on a Friday, a holiday on the last trading day or on day +1, a short first week, a dividend inside the hold, the first and last incomplete month turns of the file); the engine equal to the reference trade by trade on the real data; a control run whose drawn entries are the real ones reproducing the real trades. `tom_run.js` refuses to run unless the self-test passed on the current code.

## Before the article
Results go to the owner first (in Romanian), with every gate. One article, only with the owner's agreement.

## Reading the result
"Buried" or "Inconclusive" mean a statistically convincing edge per trade was not demonstrated; neither is proof that none exists. A "Survivor" means the rule passed our six gates on one ETF and one period, with a holdout already used; it is not a promise. One ETF, one data source, the published window only.

## Log
- 2026-11-04: draft 1 written. Nothing computed.
- 2026-11-04: frozen (draft 1 unchanged), approved by the owner. SHA-256 of the frozen text (before this log grew): 161f5afc56c9cc8b73c275fc4dc945ca5fcbc6d8f1d0ce7c3818c6add534d943.
- 2026-11-04, before any result: tom_selftest.js passed (hand-built months, engine = reference on the real data for the rule and the five neighbouring windows, control with the real entries drawn). Counts only: 404 trades (development 155, validation 120, holdout 129); 135 at quarter-end turns.
- 2026-11-04, the run (`node tom_run.js`, once, outputs in `tom_out/`): **TOM Buried, 4 of 6** (fails validation PF 1.11 and the control, percentile 90.4; passes the trade counts, development t 2.33, without the 10 best +56.70%, holdout +34.68% PF 1.47). Rule 3 not applicable. The neighbouring windows were looked at only after the gates, as written above: -3..+3 passed 6 of 6 and -2..+3 5 of 6 there, which are post-hoc readings and **not** passes. Nothing was rerun or changed.
- 2026-11-04: the owner asked for the article ("Da, scrie-l"). Published from the outputs of the single run, unchanged.
