# The RSI(2) strategy on SPY, daily closes (Connors' rules) - specification (RIP Backtest protocol v1.0 plus the 8 Oct 2026 rules)

Specification written and **frozen 2026-11-06 (approved by the owner the same day: "Da, îngheață și rulează"; draft 1 unchanged)**, before any RSI(2) value, signal or trade was computed on SPY. Once frozen, any change of a rule is documented and treated as a separate test; bugs may be fixed.

## Why this test, and what was looked at before
- **Chosen by the owner** on 2026-11-06 ("ok hai sa facem"), after reading a commercial page that reports a strong RSI strategy on SPY but keeps its rules for paying members; we cannot test hidden rules, so we test the published ones. [Removed in this published copy: the name of that site and its figures.]
- **The rule:** the 2-period RSI strategy made popular by Larry Connors and Cesar Alvarez (*Short Term Trading Strategies That Work*, 2008, and later books): buy the S&P 500 after a sharp short-term drop while it is above its 200-day average, sell when it closes above its 5-day average. Thresholds of 10 and of 5 are both commonly quoted; both are declared here, nothing else is tried.
- **Why it could work:** short-term overreaction in a broad index, and a long upward drift that rewards buying dips; the effect has been described since the 1990s.
- **Why it might not (written before the run):** it is one of the best-known rules in trading, so any edge may have been traded away; it has no stop, so a dip can turn into a crash; the published results are often shown without costs and without an out-of-sample period.
- **Looked at before on the site (disclosed):** RSI(2) on **ES futures**, 60-minute bars with extra rules of our own (hours, a 24-bar cap, a 3 ATR stop, a short side), buried; the RSI(2) versions on four FX pairs in the FX study, buried. The same SPY file in five tests (SMA 200, Accumulation/Distribution, turn of the month, pre-holiday, pre-FOMC), so the holdout below is already used. **No RSI(2) value has been computed on SPY.**

## Instrument and data
- **SPY**, daily bars 1993-01-29 to 2026-10-20 with 136 dividends, the files of the SMA 200 test (spy_daily.csv 8de2b35662134fe5, spy_dividends.csv f6a7857257bbd23c, dtb3_fred_raw.csv 0ba63bf126e01aa6). Loader: `sma200_lib.loadData`.
- **Indicators on the raw daily closes** (as in the SMA 200 test). **Returns are total returns:** a dividend is reinvested at its ex-date close, so a trade bought at the close of day j and sold at the close of day k grows by the product of (close[i] + dividend[i]) / close[i-1] for i = j+1 .. k.

## Indicators
- **SMA(200)** and **SMA(5)**: plain averages of the last 200 and 5 closes, the day itself included.
- **RSI(2)**, Wilder's: average gain and average loss of the daily close changes with smoothing 1/2 (each = (previous + today's) / 2), seeded with the plain average of the first two changes; RSI = 100 - 100 / (1 + gain / loss) (100 if the loss is 0, 50 if both are 0).
- Signals only from the 250th day (the 200-day average and the RSI no longer depend on their start).

## Rules
- **Entry:** at the **close** of a day when the close is **above its SMA(200)** and **RSI(2) is below the threshold**, if no position is open.
- **Exit:** at the **close** of the first later day when the **close is above its SMA(5)**. A new entry is considered from the next day's close.
- **No stop, no target, no time limit**, as in the published rule. The worst open loss of every trade is reported. A position open at the end of the data closes at the last close.
- **Two variants:** **RS2-10** (RSI(2) below 10) and **RS2-5** (below 5). Long only, one position at a time.

## Costs
- **0.04% of the price per round trip**, as in the other SPY tests; 0.10% shown as a scenario. The verdict is that of 0.04%.

## Results, periods, gates, control
- **Unit:** net % per trade.
- **Periods (by entry date):** development 1993 .. 2005; validation 2006 .. 2015; holdout 2016 .. 2026-10-20 (**already used** by five earlier SPY tests).
- **Six gates per variant:** validation profit factor >= 1.2; at least 50 trades in each period; development **t >= 2.5** (RSI(2) already has more than four versions 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 (as for RSI(2) in the FX study):** random entries on days in the signal's state without the RSI(2) condition: the close above its SMA(200) and **below its SMA(5)** (a dip in an uptrend), when no position is open; each such day is entered with one probability, calibrated so that the mean number of trades matches the real variant; the same exit, costs and fills. 500 runs, seeds 1000 + run. Statistic: average net % per trade. It asks whether the RSI(2) extreme picks better dips than any dip in an uptrend.

## Also reported (descriptive, after the gates; nothing here can change the rule or the verdict)
Win rate with its Wilson interval; holding days (median, longest); time in the market; the worst open loss; by year and by period; without the 10 and the 20 best trades; the whole strategy with T-bill interest while out, against buy-and-hold (growth, yearly return, largest drawdown, volatility); the 0.10% cost; **fills at the next day's open** instead of the close, for entries and exits (the close is only known after the bell). [Removed in this published copy: a comparison with that site's figures, left out of the article.]

## Engine and self-test (before the run)
New engine `rsy_lib.js`, an independent re-implementation `rsy_ref.js`, and `rsy_selftest.js`, which must pass before any result is printed:
1. Hand-worked days: SMA(5), SMA(200) on a short series, RSI(2) against a hand calculation (a loss day, a gain day, a flat day), an entry only above the SMA(200) and below the threshold, the exit at the first close above SMA(5), no same-day re-entry, a dividend inside a trade, the end of the data, the costs, the next-open fills.
2. The control's pool (only days above SMA(200) and below SMA(5), only while flat) and its calibration.
3. The independent re-implementation matched trade by trade for both variants on the real data.
4. A control run whose entries are the real ones reproducing the real trades.
5. A mutation check: deliberate changes to the rules (threshold, exit average, RSI smoothing, fill day) must make the test fail.
`rsy_run.js` refuses to run unless the self-test passed on the current code and this file is frozen.

## Before the article
Results go to the owner first (in Romanian), with every gate. One article, only with the owner's agreement, linked to the RSI(2) ES post and the SPY posts. Working title for search: "RSI(2) Strategy on SPY: 33-Year Backtest of Connors' Rules".

## Reading the result
"Buried" or "Inconclusive" mean a statistically convincing edge was not demonstrated; neither is proof that none exists. One ETF, one data source, the published rule only, a holdout already used.

## Log
- 2026-11-06: draft 1 written. Nothing computed.
- 2026-11-06: frozen (draft 1 unchanged), approved by the owner ("Da, îngheață și rulează"). SHA-256 of the frozen text (before this log grew): fc376c1f7ba814f39b5e211d20145f933e519a7593f071f3a67c11ba31f70313.
- 2026-11-06, before any result: rsy_selftest.js passed on the first run (hand-worked averages, RSI(2), entry, exit, dividend, end of data, next-open fills, equity; indicators and trades equal to the independent reference; control pool and calibration; all four mutations detected). Counts only: RS2-10 257 trades, RS2-5 126.
- 2026-11-06, the run (`node rsy_run.js`, once, outputs in `rsy_out/`): **RS2-10 Survivor, 6 of 6** (257 trades, +0.616% a trade net, 75.9% winners; development t 6.74, validation PF 1.63, holdout +50% PF 2.61 (holdout already used), control at the 100th percentile (random dips in an uptrend +0.316%), +125% without the 10 best). **RS2-5 Buried, 5 of 6** (fails only the trade count: 38 / 39 / 49; +0.754% a trade). Descriptive: next-open fills +0.543% a trade (RS2-10); 0.10% cost +0.556%; whole strategy with T-bills x9.76 (7.2% a year, max drawdown -14.8%, invested 10.5% of days) against buy-and-hold x29.06 (10.8% a year, -55.2%). Data check after the run: our total return x31.994 against Yahoo's adjusted close x31.977. Nothing was rerun or changed.
- 2026-11-06: the owner asked for the article the same day ("il scriem azi") and asked that the commercial page that prompted the test is not cited at all. The article does not name it; the published copy of this file removes its name and figures in the two places marked there, and the comparison listed under "Also reported" is left out. Published from the outputs of the single run, unchanged.

**Note on this published copy (2026-11-06):** at the site owner's request the commercial page that prompted the test is not cited. Its name and figures are removed in the two places marked above; nothing else differs from the frozen text, whose SHA-256 in the log refers to the original wording.
