# PREREG -- GPU prop-firm strategy miner, run `GPUMINER-2026-10-11-A`

**Frozen:** 2026-10-11 18:36:36Z by Claude, before any candidate return was read. SHA256 of this file: see `PREREG.lock`.
**Authorisation:** Kaloyan, thread message of 2026-10-11 17:56Z: "ДА! Нареждам ти да пуснеш теста и да продължиш веднага към Фаза 1 и Фаза 2. Правилото
[withheld: a line that refers to the lab's private live strategy]
below re-enter on that order; section 7 states, per family, the earlier test and the structural difference (prompt 4.3).
**Prompt:** `prop_eur2k_lab/prompts/GPU_MINER_PROMPT_2026-10-11.md`; where this file is stricter than the owner's list it wins (gates are never loosened).

## 1. Universe
Assets: `nas100usd` (2005-01..2020-12 in Discovery), `us30usd`, `spx500usd`, `us2000usd`, `de30eur` (2015-01..2020-12). Quotes: M1 bid/ask OHLC, true clock
(zone map of `lab_utc`, then stamp - 1 minute, Phase 0), mid prices for signals and the primary path. No volume exists on these files: RVOL is not
available (replaced by the ATR filters F1 / F2) and "VWAP" is the equal-weight session-anchored mean of the typical price (H+L+C)/3.

## 2. Windows (pinned IANA local times; owner's UTC hours coincide with these in the season where local = UTC offset; Rule 3)
| name | zone | window | entry bars start in | flat at |
|---|---|---|---|---|
| LONDON_AM | Europe/London | 08:00-11:00 | start+15 .. start+150 min | open of the 11:00 minute |
| NY_OPEN | America/New_York | 09:30-12:00 | start+15 .. start+120 | 12:00 |
| LONDON_FIX | Europe/London | 15:30-16:30 | start+15 .. start+30 | 16:30 |
| AFTERNOON | America/New_York | 12:00-15:45 | start+15 .. start+195 | 15:45 |
Timeframes M5, M15, M30 built from M1 inside the window (the flat minute is not a bar). At most 2 trades per day, one position at a time; the second
signal must come strictly after the exit bar. Signal on the close of bar j, market order at the open of bar j+1, M1 path orders stop and target (stop first
on a tie, gap through the stop fills at the minute open), no breakeven, no trailing, no scaling, no limit entries.

## 3. Signal families (the grid; 42 signal cells per window x timeframe)
| family | parameters |
|---|---|
| ORB | {"filt": "F0", "n_or": 15} |
| ORB | {"filt": "F1", "n_or": 15} |
| ORB | {"filt": "F2", "n_or": 15} |
| ORB | {"filt": "F0", "n_or": 30} |
| ORB | {"filt": "F1", "n_or": 30} |
| ORB | {"filt": "F2", "n_or": 30} |
| ORB | {"filt": "F0", "n_or": 60} |
| ORB | {"filt": "F1", "n_or": 60} |
| ORB | {"filt": "F2", "n_or": 60} |
| DONCH | {"N": 10, "filt": "F0"} |
| DONCH | {"N": 10, "filt": "F1"} |
| DONCH | {"N": 10, "filt": "F2"} |
| DONCH | {"N": 20, "filt": "F0"} |
| DONCH | {"N": 20, "filt": "F1"} |
| DONCH | {"N": 20, "filt": "F2"} |
| DONCH | {"N": 40, "filt": "F0"} |
| DONCH | {"N": 40, "filt": "F1"} |
| DONCH | {"N": 40, "filt": "F2"} |
| VWAPREV | {"filt": "F0", "z0": 2.0} |
| VWAPREV | {"filt": "F1", "z0": 2.0} |
| VWAPREV | {"filt": "F2", "z0": 2.0} |
| VWAPREV | {"filt": "F0", "z0": 2.5} |
| VWAPREV | {"filt": "F1", "z0": 2.5} |
| VWAPREV | {"filt": "F2", "z0": 2.5} |
| ENGULF | {"ctx": "none", "q": 0.5} |
| ENGULF | {"ctx": "extreme", "q": 0.5} |
| ENGULF | {"ctx": "trend", "q": 0.5} |
| ENGULF | {"ctx": "none", "q": 1.0} |
| ENGULF | {"ctx": "extreme", "q": 1.0} |
| ENGULF | {"ctx": "trend", "q": 1.0} |
| SWEEP | {"eps": 0.0, "filt": "F0", "level": "PD"} |
| SWEEP | {"eps": 0.0, "filt": "F1", "level": "PD"} |
| SWEEP | {"eps": 0.25, "filt": "F0", "level": "PD"} |
| SWEEP | {"eps": 0.25, "filt": "F1", "level": "PD"} |
| SWEEP | {"eps": 0.0, "filt": "F0", "level": "OR30"} |
| SWEEP | {"eps": 0.0, "filt": "F1", "level": "OR30"} |
| SWEEP | {"eps": 0.25, "filt": "F0", "level": "OR30"} |
| SWEEP | {"eps": 0.25, "filt": "F1", "level": "OR30"} |
| SWEEP | {"eps": 0.0, "filt": "F0", "level": "N20"} |
| SWEEP | {"eps": 0.0, "filt": "F1", "level": "N20"} |
| SWEEP | {"eps": 0.25, "filt": "F0", "level": "N20"} |
| SWEEP | {"eps": 0.25, "filt": "F1", "level": "N20"} |
Filters: F0 none; F1 signal-bar range >= 1.0 x ATR14 of the previous bar; F2 ATR14 >= mean of the previous 60 ATR14 values. ENGULF ctx: none; extreme (bar
low/high beyond the previous 10 bars); trend (close beyond EMA20, finite window 5n). ORB: first close beyond the opening range of n_or minutes after it
completes. DONCH: close beyond the previous N bars' extreme (state change). VWAPREV: |z| >= z0 against the anchored mean/std (>= 30 minutes, fade, state
change). SWEEP: bar pierces the level (+eps x ATR) and closes back inside, fade; levels PD (previous day's same window), OR30, N20. Both-sided bars are skipped.
[withheld: a line that refers to the lab's private live strategy]
[withheld: a line that refers to the lab's private live strategy]

## 4. Stops, targets, cost wall
Stops: k x ATR14 of the signal bar, k in 1.0, 1.5, 2.0, 3.0; or STRUCT = signal-bar extreme -/+ 0.1 ATR clipped to [0.5, 3.0] ATR. Targets: 1.5R, 2.0R,
2.5R, or flat at the window end. R = distance from entry to the initial stop; net R = gross R - cost R.
Cost (project model, section 4.2 of the prompt): US100 inside America/New_York windows 1.70 pt x px / 29794.05 per round trip; every other
case 1.25 x the file's bid/ask spread at the entry minute (causal forward fill of the last positive spread; hollow minutes give no trade). Reported at 1x
and 2x. Eligibility: median cost in R per (asset, window, timeframe, stop) over entry bars on Discovery days must be <= 0.03; computed from
quotes only (`out/eligibility_dsl.json`, sha256 `2e9302da5011721cfbfcd59883318f4e9e7ca8e011374172dc5dd477b04281bf`).
**Eligible (asset, window, timeframe) combinations with their stops** (25 combinations, 61 (combination, stop) pairs, 244 configurations,
10248 selectable cells):

| combination | eligible stops |
|---|---|
| de30eur|LONDON_AM|M15 | 2.0, 3.0 |
| de30eur|LONDON_AM|M30 | 1.5, 2.0, 3.0 |
| de30eur|LONDON_FIX|M15 | 1.5, 2.0, 3.0 |
| de30eur|LONDON_FIX|M30 | 1.0, 1.5, 2.0, 3.0 |
| de30eur|LONDON_FIX|M5 | 3.0 |
| de30eur|NY_OPEN|M15 | 2.0, 3.0 |
| de30eur|NY_OPEN|M30 | 1.5, 2.0, 3.0 |
| nas100usd|AFTERNOON|M15 | 1.0, 1.5, 2.0, 3.0 |
| nas100usd|AFTERNOON|M30 | 1.0, 1.5, 2.0, 3.0, STRUCT |
| nas100usd|AFTERNOON|M5 | 2.0, 3.0 |
| nas100usd|LONDON_FIX|M15 | 3.0 |
| nas100usd|LONDON_FIX|M30 | 1.5, 2.0, 3.0 |
| nas100usd|NY_OPEN|M15 | 1.0, 1.5, 2.0, 3.0, STRUCT |
| nas100usd|NY_OPEN|M30 | 1.0, 1.5, 2.0, 3.0, STRUCT |
| nas100usd|NY_OPEN|M5 | 1.5, 2.0, 3.0 |
| spx500usd|LONDON_FIX|M30 | 3.0 |
| us2000usd|LONDON_FIX|M15 | 3.0 |
| us2000usd|LONDON_FIX|M30 | 2.0, 3.0 |
| us2000usd|NY_OPEN|M30 | 3.0 |
| us30usd|AFTERNOON|M30 | 3.0 |
| us30usd|LONDON_AM|M30 | 3.0 |
| us30usd|LONDON_FIX|M15 | 2.0, 3.0 |
| us30usd|LONDON_FIX|M30 | 1.5, 2.0, 3.0 |
| us30usd|NY_OPEN|M15 | 3.0 |
| us30usd|NY_OPEN|M30 | 2.0, 3.0 |

## 5. Splits and gates (frozen; may be tightened, never loosened)
Discovery: file start -> 2020-12-31. Validation: 2021-01-01 -> 2023-06-30, 5 trading days embargo at both ends. Holdout:
2023-07-01 -> file end. The loader returns no row after the allowed window; Validation opens once for the frozen list, Holdout once for at most
10 finalists in the frozen rank order (Discovery gate t, descending). The Holdout is unseen by this miner, not by the project (contamination map).
Statistic: net t at 1x cost = min(trade-level t, day-clustered t).
S1 (Discovery, net): n >= 300; t >= 3.0; mean at 2x cost > 0; positive in >= 60% of calendar years with >= 10 trades (at least 4 such years); plateau:
the mean of the existing one-step ordinal neighbours (timeframe, stop, target, family parameter) >= 50% of the cell's mean.
S2: t above the 95th percentile of the null of the maximum gate t over the WHOLE selectable grid (cells with n >= 300): 1000 day-block
circular shifts of the signal cube and 1000 random daily direction-sign draws, the larger 95th percentile applies. DSR is reported with
`lab_stats.dsr`, never gated (RULES 8).
S3 (Validation): n >= 100, t >= 2.0 at 1x, t >= 1.0 at 2x, same sign, mean >= 50% of the Discovery mean, win-rate drift < 10 points.
S4 (Holdout, <= 10 finalists): t >= 2.0 at 1x, >= 1.0 at 2x, maximum drawdown < 15 R.
[withheld: a line that refers to the lab's private live strategy]
(strict reading; Jaccard reported).
Battery for cells that pass S1-S6 (FAIL ANYWHERE = FAIL): bar phase -3..+3 min, leak test lag 0/1/2, flipped rule must lose, random-200 placebo, top-5 trade
drop, cost 1x/2x/3x, six macro regimes, strict bid/ask path replay, second-vendor replication (LSE NQ.F / CME where the asset exists), event-engine parity
[withheld: a line that refers to the lab's private live strategy]
Never: re-run a stage with changed gates, look at a later window to choose between cells, add families after Discovery starts, report gross as the headline,
[withheld: a line that refers to the lab's private live strategy]
or the same stage fails three times for the same reason.

## 6. Engine verification done before this freeze (no ledger cost)
* `selftest.py parity`: engine_gpu vs engine_ref on 3 x 210 random (cell, stop, target) draws on synthetic cubes with gaps, half days, holidays, stale
  minutes and price ties, all timeframes: 0 mismatches over ~225,000 trades; features (bars, ATR, EMA, anchored mean/std) bit-identical.
* `selftest.py parity_real`: 300 + 120 draws on the real Discovery cubes, ~280,000 trades, 0 mismatches (statistics not inspected).
[withheld: a line that refers to the lab's private live strategy]
  engine_gpu in bar mode reproduce the same trade set with max |dR| = 0.
* `synth_suite.py null` (40 seeds): observed grid maximum above the null 95th percentile in 1/40 runs (expected ~2); `plant`: a planted edge is recovered at
  the predicted rate (0.08 pt/min: 11/20 vs 11.4 predicted); `look`: planted one-bar lookahead t = +14.2 at lag 0, -0.07 / -0.57 at lag 1 / 2: caught.
Numerical note: PyTorch compiles tensor / python-scalar as multiplication by the reciprocal; every division in the pipeline is a true division
(`indicators_gpu.fdiv`) so that the CPU reference agrees bit for bit.

## 7. Register of re-entering closed families (prompt 4.3: earlier test and numbers, structural difference)
| family | earlier tests and their numbers (CANDIDATES.md, SESSION-STATE.md, NEW_RESULTS, HV_BATTERY) | structural difference |
|---|---|---|
| ORB | P1 breakout matrix (216 cells, CME 2021-2024): 2 FIT survivors t 2.05 / 2.13 -> OOS -0.89 / 0.30; NEW-1 ORB FIT t 0.83, OOS 0.73, 803 new trades gross -$5; HVB-A1..A4 (honest clocks, ORB30 NAS/SPX/US30/US2000): all KILL; P43 US30 FIT n=1,962 t 2.98 -> OOS 0.47; P15 / HVB-A5 DAX t -1.9 / -2.9 | 21-year US100 sample (n x 5-10), five assets, M1 path, bid/ask cost model, grid-calibrated null, plateau + year rule |
| DONCH | P1 (L = 10 / 40 collapsed OOS), GEM047 channel n=492 t +0.98, P17 expansion breakout FIT 1.62 / OOS -0.18 | same |
| VWAPREV | P10 anchored VWAP bands NQ FIT t -2.17, OOS1 -3.12, ES -3.18; P36 US2000 t -4.2..-5.4; P84 YM FIT +0.84, OOS -0.95; GEM049 design-kill | same; unweighted mean (no volume) |
| ENGULF | no direct earlier test; nearest: P4 pinbars (6 assets t -2.3..+1.1, volume-based), CRT t -5.00, GEM051-060 repackages | same |
| SWEEP | P52 Judas sweep NQ FIT 0.19 / OOS -1.22, ES 0.55 / -0.45; P8 (wrong clock); SWEEPFILT01 as a filter; ROUND2 S4 sweep, PDH sweep; P92 breakdown retest | same |
| ATR filters | P6 vol-gated trend t -0.50; OPEG01 / OPZCG01 regime filters t 1.60 / 0.10 | same |
Different parameter values are NOT claimed as the structural difference.

## 8. Resources and accounting
Below-normal priority, <= 12 CPU threads, RAM < 20 GB, VRAM < 10 GB. Own ledger `out/ledger.sqlite` (one row per cell per stage, one chunk marker per
(asset, window, timeframe), resumable). The global ledger is never reset; one closing event with n = distinct cells evaluated on real data is appended
[withheld: a line that refers to the lab's private live strategy]

## 9. Code hashes (sha256)
| file | sha256 |
|---|---|
| `config.py` | `453235917bb26838923ee81b914bf28ca089e1606d0839a6cdaf7a0b19ea93b6` |
| `data_loader.py` | `b5c5c333e7b22a675a99f29315491b97e2ba7cf08be198e70d5ce142eb1515f0` |
| `indicators_gpu.py` | `d59758f5da117989e908efc5a9c5af38fa4f7ddab546af9e5f5d8c5aa99b5b32` |
| `engine_gpu.py` | `307ce9168baf69e13448d0c71e3ad0c1b4b83d99d49253682233208aea308698` |
| `engine_ref.py` | `ade68516cf3d0162eefead6880b31f0a6e7fcc30653cdeeaacd13ed38aa76716` |
| `gates.py` | `e7bad4a6b4bdf820ad2ba723887a90a49be099e15b2d8460991c45d96d6ca758` |
| `run_miner.py` | `4eaf6bb36a31ad84161392304b82316e7fb9d24cda99c082b2c2ddd33836c9f6` |
| `stages.py` | `4e8520955c5b529922d1420d75a1c8252e5a3b91d15a6a4ec3dd1fbe7df115f2` |
| `ledger.py` | `89de43aeeb067e5fb280b19c24fcea4cd5428dc7d087ccf6773f6866881871b7` |
| `selftest.py` | `488b48b6dc240a78c63c9eafe66050d1cb30bfe32058e2773e8572411627c2ba` |
| `synth_suite.py` | `b956925a6e6606dbc3804bf96adfda185b48f8d7738ad9517e52e740b8fa9561` |
