# RSI divergence reversal, simple and with a profit target and stop - frozen specification (RIP Backtest protocol v1.0)

Specification written **2026-10-07, before `dv_protocol.js` was run on any data.** Bugs may be fixed after the run; rules may not.

## The claim being tested
A widely taught reversal idea: when price makes a new low but the RSI makes a higher low (**bullish divergence**), downside momentum is fading and price tends to turn up.
The mirror image, a higher high in price with a lower high in RSI (**bearish divergence**), is read as a warning of a turn down. The RSI was created by J. Welles Wilder Jr.
We found no single source for this exact rule set, so we describe it as a common setup and test our own exact definition at common defaults, with nothing tuned.

## Instrument and data
ES futures, 60-minute bars built from our 1-minute data (bar time = close time, New York clock), 2020-01-01 to 2026-09-25. Costs: $5.76 commission per round trip and
1 tick ($12.50) slippage on every fill, 1 contract, $50/point.

## Indicator and swing points
- RSI(14), Wilder smoothing, on hourly closes. ATR(14) Wilder.
- A **swing low** is a bar whose low is below the lows of the 5 bars before it and not above the lows of the 5 bars after it. A **swing high** is the mirror image (highs).
  A swing is only known 5 bars later, so it is **confirmed at the close of the bar 5 bars after it**. No signal uses information from after that bar.

## Signals (evaluated at the close of the confirmation bar; market orders fill at the open of the next 1-minute bar)
- **Bullish divergence (long):** a new swing low whose low is **lower** than the previous confirmed swing low, while the RSI value at the new swing low is **higher** than the RSI at the previous swing low,
  with the two swings between 5 and 60 bars apart.
- **Bearish divergence (short):** a new swing high **higher** than the previous swing high while the RSI at it is **lower**, same distance rule.
- One position at a time, around the clock, flat before the weekend (a Friday bar closing at or after 16:00 New York time exits, and no entries then). Signals that appear while in a position are ignored.

## Exits
- **Simple version (S):** a long exits at the first bar close with RSI(14) above 50. A short exits at the first bar close with RSI(14) below 50. No stop, no target. Weekend flat.
- **Full version (F):** stop = 2 x ATR(14) (at the signal bar) from the entry fill, target = 4 x ATR(14), time limit 24 bars. Weekend flat. No RSI exit.
  If target and stop could both have been touched inside the same 1-minute bar, the stop is assumed to hit first.

## Variants (declared up front; the ONLY ones tested)
DV-LS-S (long + short, simple), DV-L-S (long only, simple), DV-LS-F (long + short, full), DV-L-F (long only, full). Variants tried: **4**.

## Periods
Development 2020-01-01 .. 2023-12-31; Validation 2024-01-01 .. 2025-03-31; Holdout 2025-04-01 .. 2026-09-25.
The holdout is NOT unopened: this ES data was used in earlier tests of other strategies. It is reported, flagged as used.

## Gates (protocol v1.0, net of costs, per variant)
1. PF >= 1.2 in the validation period. 2. At least 50 trades in each period. 3. Development t-statistic >= 2.0 (four variants tried, so the base bar applies).
4. Above the 95th percentile of 500 random-entry runs. 5. Positive after removing the 10 best trades. 6. Holdout net positive (flagged used).

## Random-entry control
Same exits, session rule and costs, entries at random bars when flat. The side is the one a reversal would take at that bar (long if RSI(14) is below 50, short if above; long only for
the long-only variants), and the trade count is calibrated to match the real variant. This tests whether the divergence matters, or whether any bar on that side of RSI 50 does as well.
500 runs, fixed seeds. The statistic is the average net $ per trade over the full sample.

## Amendment, 2026-10-08 (control check; no rule, gate or result above was changed)
After an outside review we checked the control above against the real signal. The frozen control trades only when RSI(14) is below 50 (long) or above 50 (short). The real signal has no
RSI condition at confirmation, and in DV-L-S 134 of 281 long signals fired with RSI at or above 50 (they exit after about 1.8 bars, because the exit rule is already met).
We therefore ran two alternative controls, reported in the post as a sensitivity check: (C1) no RSI condition, and (C2) matched on RSI at entry (RSI buckets of 5 points; the control enters
with the same spread of RSI values as the real signals). Code: `dv_control_check.js`; output: `dv_control_check.txt`. The frozen gate 4 result is unchanged and still reported.

## Engine conventions (fixed before the run)
Identical to our other ES tests: a target fills at its price or at the bar's open if a 1-minute bar gaps through it; a stop fills at its price or at the open if gapped; costs apply to
every fill; indicators are computed continuously on the full series. Drawdown is reported both on closed trades and approximately including open losses.
The engine reproduces the published RSI(2) Dip Buyer trades exactly.
