# Coppock Curve on 1-hour ES bars - frozen specification (RIP Backtest protocol v1.0 plus the 8 Oct 2026 rules)

Specification written **2026-10-08, before any 1-hour Coppock value, signal or trade was computed.** What was looked at before writing it: the earlier, unprotocolled Coppock tests on ES (NinjaTrader, M1 and M5, with ADX and H1-alignment filters, normal and reversed; profit factors 0.83 to 0.91 after costs; no frozen specification, no controls), the code that computes the curve in `coppock_gold.js`, and the engine of the 1-hour golden cross test. No 1-hour Coppock number was looked at.
Bugs may be fixed after the run; rules may not. If the engine fails its self-test (below), nothing is run.

## What is tested
The Coppock Curve signal of the author's MT4 / NinjaTrader indicator **at its default settings and with no filter**, on **1-hour ES bars**, all sessions, with and without a stop and targets (the same exit grid as the 1-hour golden cross test). The filters (ADX, H1 alignment) and other timeframes are not tested here; the earlier M1 and M5 results are background only.

## Rules
- Bars: 1-hour ES bars built from the 1-minute file exactly as in every hourly test (bar time = close time, New York clock), 24 hours a day, no session filter, positions held over weekends. `ES_1min.csv`, back-adjusted, 2020-01-01 to 2026-09-25; $50 a point.
- **Curve:** raw[k] = ROC(14)[k] + ROC(11)[k], with ROC(n)[k] = 100 x (close[k] - close[k-n]) / close[k-n]; **Coppock[k] = weighted moving average of raw over 10 bars**, weights 10 (newest) down to 1, divided by 55.
- **Signals** at the close of bar k (needs Coppock[k-2]): **bull** if Coppock[k] > Coppock[k-1] and Coppock[k-1] <= Coppock[k-2] (the curve turns up after not rising); **bear** if Coppock[k] < Coppock[k-1] and Coppock[k-1] >= Coppock[k-2]. A signal in the same direction as the previous one (possible only through an exact tie in the curve) is ignored, so signals alternate.
- **Entries only on a signal**, filled at the open of the first 1-minute bar after the signal bar, plus slippage: a bull signal opens a long; in the long-short versions a bear signal opens a short. After a stop or a target the position stays flat until the next signal. The first signal is an entry (no "initial state" assumption).
- Exit: the **opposite signal** at the next 1-minute open (a bull closes a short, a bear closes a long; in the long-short versions it also opens the new position). A position still open on the last bar is closed at its close and flagged.
- **R = 1.5 x ATR(14)** of the 1-hour bars at the signal bar, in points. Stop 1 R; targets at 1 R, 2 R, 3 R; the stop wins a tie; a level gapped through fills at the open; slippage on every fill. (R is defined for the no-stop version too, as a unit only.)
- **12 variants (the only ones tested):** long only (L) and long and short (LS), each with six exit rules: **N** (no stop, no target, exit on the opposite signal), **S** (stop 1 R only), **T1, T2, T3** (stop and one target), **T123** (a third at each target, the exact average of T1, T2, T3, no break-even move). Named `CC-L-N` ... `CC-LS-T123`, prefixed `ES-` in the files. No other settings will be tried after seeing results.

## Costs, periods, units
- **Costs:** commission $5.76 per round trip plus one tick (0.25 point) of slippage on every fill = $30.76 a trade, as in all the ES tests; the same $30.76 for each quarterly roll a position is held through (second Thursday of March, June, September, December, open at 17:00 New York). A signal every few hours makes costs large relative to R: that is part of the test.
- **Periods (by entry date):** development 2020-01-01 .. 2023-12-31; validation 2024-01-01 .. 2025-03-31; holdout 2025-04-01 .. end. **The holdout is not clean** (the same ES data, and earlier Coppock tests, used it).
- **Units:** net R per trade (net points divided by R in points), non-compounded; dollars per contract next to it.

## Gates and verdicts (as in the 1-hour golden cross test)
Six gates per variant: validation profit factor >= 1.2; at least 50 trades in each period; development t >= **2.5** (more than four variants are tried); above the 95th percentile of 500 runs of the matched control; positive without the 10 best trades; holdout net positive (flagged used). **A variant with fewer than 30 trades is Inconclusive**; otherwise Buried or Survivor.

## Matched control (entry state)
A **circularly shifted state-series control**. The state is the direction of the last Coppock signal (+1 after a bull, -1 after a bear), carried forward bar by bar. The real state series is shifted circularly by a random offset of at least 5% of its length and applied to the real prices with the same entry, stop, target and exit rules and the same costs; **the ATR-based R (and so every stop and target distance) is recomputed at the shifted signal time from the real prices**. 500 runs, fixed seeds (1000 + run), runs with no trade excluded, the same shifts for every variant. The statistic is the average net R per trade over the full sample.

## Always reported
Win rate with its 95% Wilson interval, how the trades ended (stop, target, opposite signal), average bars held, long and short sides separately, the cost per trade in R next to the gross result per trade, drawdown on closed trades and including open losses, buy and hold in the same dollars, and the sign of every result in both R and dollars.

## Before anything is run (self-test)
`cc_selftest.js` must pass first: (1) a hand-worked example of the curve and of the signals; (2) the engine's curve and signals match an independent naive recomputation to 1e-9 on the real ES bars; (3) an independent re-implementation of the trade simulation, run on the same signals, matches the engine trade by trade for all 12 variants; (4) the shifted-state control with shift 0 reproduces the real signals. The engine of the golden cross test is reused unchanged except for one additive line (the control can take a state series). No result is printed.

## Reading the result
"Inconclusive" and "no proven edge" mean a statistically convincing edge was not demonstrated; neither is proof that none exists. One market, one set of default settings, one stop size, one signal without filters.
