# Daily-trend veto and wide-stop cap — pre-registered campaign, 2026-09-30 Owner request (2026-09-30): improve the direction call and the trade setup size; anything may change if the evidence supports it. This file holds the rules first, then the results. Sections 1 to 4 were written before any formal run. Section 2 records what was already looked at while planning, so the reader knows which numbers are a confirmation and which are a first look. ## 1. What is tested **Candidate T — daily-trend veto.** The engine sees at most the H1 chart (M5 confirms on M15 and H1, M15 on M5 and H1). None of the 65 decision-time features of the earlier campaigns reads the daily chart. The candidate drops a finished trade setup that goes against a clear daily trend. Definition (fixed; `signal_aggregator.daily_trend_series`): - daily candles from the provider (UTC-aligned, label = 00:00 UTC of the day), closed bars only: a bar labelled D is used once D + 1 day ≤ the close of the primary bar; - bars labelled Sunday are dropped first (Oanda's 1 to 2 hour reopening stub); - `ema = Close.ewm(span=50, adjust=False).mean()`, `change = Close / Close.shift(60) − 1`; - state +1 when `Close > ema` and `change > 0`; −1 when `Close < ema` and `change < 0`; else 0; - after every setup archetype has run (gold ATR, swing, pullback, chart pattern) a setup against a non-zero state is removed: grade D, no setup, warning `DAILY TREND FILTER: …`. Switch `xau_strategy.daily_trend_veto`: `off` (default, books byte-identical), `both`, `buy` (only buys against a falling daily trend are removed), `sell`. **Candidate C — wide-stop cap.** `xau_strategy.wide_stop_cap_atr = K` caps the stop distance of the swing (GENERIC) and chart-pattern setups at `max(K × ATR, the existing floor)`, applied after the min-RR and spread gates so the set of trades cannot change. K = 6, with 5, 7 and 8 declared as neighbours. M15 only (the exit-only screen was negative on M5). ## 2. What was already seen (planning phase, 2026-09-30, read-only, in memory) Prototype: K1 and K2 of the CUDA twin, then a host-side mask on the final candidates before the 5-bar cooldown, then the shared resolver. The control rows of the prototype reproduce the pinned books (M15 W3 1105 / +195.79R, M5 W3 870 / +153.64R, H1 W3 253 / +70.02R). | Book ($0.65) | Control | Veto, both directions | |---|---|---| | M15 W3 2023-09-05 → 2026-09-05 | 1105 / +195.8R / PF 1.49 / DD 20.9 | 824 / +205.1R / PF 1.73 / DD 12.4 | | M15 LONG 2019-01-01 → 2026-08-07 | 2091 / +192.5R / PF 1.24 / DD 64.8 | 1473 / +223.3R / PF 1.42 / DD 41.5 | | M15 rising window 2024-06-01 → 2025-03-30 | 313 / +68.5R / PF 1.67 | 258 / +63.8R / PF 1.80 | | M5 W3 | 870 / +153.6R / PF 1.50 / DD 10.1 | 668 / +159.1R / PF 1.70 / DD 15.2 | | M5 W3, buy side only | | 741 / +156.5R / PF 1.60 / DD 9.6 | | M5 LONG | 1052 / +128.1R / PF 1.34 / DD 18.4 | 790 / +127.5R / PF 1.45 / DD 25.2 | | H1 W3 | 253 / +70.0R / PF 1.98 / DD 4.4 | 231 / +60.3R / PF 1.90 / DD 4.4 | Also seen: neighbouring definitions on M15 (60-day change alone +188.3R W3 / +228.1R LONG; 90-day +196.1 / +228.8; 120-day +199.4 / +233.2; 100-day average +201.2 / +227.3); the share of M15 W3 trades reaching +1R before −1R (58.6% → 61.4%); the live September 2026 setups with the veto applied after the fact (cooldown view −11.6R → −6.0R to −8.8R); an exit-only re-simulation of 25 stop and exit variants (cap 6 × ATR on M15 W3 +14.0R, LONG +11.8R; cap 5 negative on LONG); two variants dropped at this stage and NOT tested formally: lifting the SELL gates when the daily trend is down (worse on LONG on both timeframes), and removing the existing M15 short blocks under the veto (costs 4 to 22R). So the windows W3, W2, the rising window and LONG are a CONFIRMATION through the real code path. First looks are: the HOLDOUT window through the backtester, the $0.30 numbers on LONG, and every number produced by the shipped code rather than the prototype. ## 3. Harness `venv/bin/python backtest/cudaBasedBacktesting.py --pair XAUUSD --primary-tf --start --end --spread <0.65|0.30> [--set xau_strategy.daily_trend_veto=] [--set xau_strategy.wide_stop_cap_atr=] --export-csv `; factory configuration otherwise. Twin numbers count only with the paired `backtest/gpu_backtest.py` MD5 (same flags plus `--workers 12`). Neighbouring trend definitions are not shipped code: they run on the research harness (the prototype), after the harness book for the shipped definition is shown identical to the twin's. Windows: **W3** 2023-09-05 → 2026-09-05 (halves at 2025-03-05); **W2** 2024-09-05 → 2026-09-05 (halves at 2025-09-05); **RISING** 2024-06-01 → 2025-03-30 (the old out-of-sample window; a rising market throughout); **LONG** 2019-01-01 → 2026-08-07; **HOLDOUT** 2026-09-05 → 2026-10-01 (fetched for this campaign, never seen by any tuning or by the prototype). ## 4. Acceptance rules (written before the runs) **Rule T (risk-first; owner decision 2026-09-30).** Candidate T on a timeframe PASSES only if, against the same-harness control: - (a) W3 total R ≥ 97% of the control's at $0.65; - (b) W3 profit factor ≥ control + 0.10; - (c) W3 max drawdown ≤ the control's; - (d) LONG: total R ≥ control, max drawdown ≤ control, and 2021 + 2022 combined R better; - (e) HOLDOUT total R ≥ control − 0.5R; - (f) clauses (a) to (c) also hold at $0.30; - (g) at least 3 of the 4 neighbouring definitions (60-day change alone, 90-day, 120-day, 100-day average alone) satisfy (a) and (c): a plateau, not a spike; - (h) at least 20 trades differ on W3. Reported, NOT clauses (the owner accepted this cost on 2026-09-30): the W2 halves and the RISING window, where the veto is expected to give up some R. The 2026-09-26 template (every half and the old out-of-sample window must not lose) would reject this candidate by construction; that is the difference between the two rules and it is deliberate. Decision per timeframe: `both` if it passes; else `buy` if that passes; else no veto (the daily trend is then shown on the alert as information only). H1 is run for the record. **Rule C (standard).** K = 6 on M15 against the post-T control PASSES only if: W3 ΔR ≥ +5R; both W3 halves ≥ control − 1R; PF ≥ control − 0.02; W3 max drawdown ≤ control + 10%; LONG total R ≥ control; the same sign of ΔR at $0.30; at least 20 trades differ; and the neighbours K = 5 and K = 7 are not negative on W3 or on LONG. No rescue for either rule: no second definition, no other K, no window shopping after the result. ## 5. Results All runs 2026-09-30 on the dev box, branch `sql-integration`, working tree = HEAD `0c56b4e` plus this campaign's code. Every twin log reads `Backend: CuPy GPU (NVIDIA GeForce RTX 4070 SUPER, cupy 14.0.1)` and `GPU cache fallbacks: 0 (no per-bar recompute path in cudaBasedBacktesting)`; every reference log reads the same `Backend:` line and `GPU cache fallbacks: 0`. 86 formal twin books (5 windows × 2 costs × the variants below, plus the fixed-1R-target books). R is per trade in units of the initial risk; "DD" is the largest peak-to-trough fall of the running total, in R. ### 5.1 Proofs before any formal number - **Baseline.** Before any code change the five reference MD5s of CLAUDE.md §9 were reproduced on both scripts (ten books). - **Default-off neutrality.** With the new code and both knobs at their defaults the same ten books are byte-identical to the pins (`e599c8a8…` M5 W2, `5b65ecf6…` M15 W2, `09b8a8e7…` M15 OOS, `a44fd19b…` H1 W3, `f3587bae…` H4 W3). - **Twin = reference on every new path** (`--spread 0.65`, W3 2023-09-05 → 2026-09-05, equal MD5 from `backtest/gpu_backtest.py --workers 12` and `backtest/cudaBasedBacktesting.py`): | Flags | Trades / R / DD | MD5 (both scripts) | |---|---|---| | M15 `--set xau_strategy.daily_trend_veto=both` | 824 / +205.12 / 12.39 | `ad3b0dbda0bf77b659caea1c53be6a50` | | M15 `…=buy` | 999 / +188.21 / 20.87 | `6e0f3b742d9690f78c97319d1b1c8a43` | | M15 `…=sell` | 930 / +212.70 / 13.72 | `31aa5762964d846f15d111cd4a718adc` | | M15 `--set xau_strategy.wide_stop_cap_atr=6` | 1105 / +209.78 / 19.32 | `4ec0e4450d5dab143a4ed37e80545626` | | M5 `--set xau_strategy.daily_trend_veto=both` | 668 / +159.07 / 15.20 | `39cc0f198d38b532720dce4f98d99452` | | M5 `--set xau_strategy.wide_stop_cap_atr=6` | 870 / +141.57 / 13.95 | `4da0997256b272ffcd11a90bf9658eef` | The M15 `both` book equals the planning prototype trade for trade (824 / +205.1R / PF 1.73 / DD 12.4), so the shipped definition is the one that was screened. - **Suite.** 595 passed / 0 failed after Stage 1 (Module 39 new, Module 37 extended). ### 5.2 Candidate T — every window, both costs Command per row: `venv/bin/python backtest/cudaBasedBacktesting.py --pair XAUUSD --primary-tf <15min|5min> --start --end --spread <0.65|0.30> [--set xau_strategy.daily_trend_veto=] --export-csv `. "control" = no `--set`. **M15** | Window | Cost | Variant | Trades | Total R | Win rate | PF | Max DD | First half | Second half | MD5 (8) | |---|---|---|---|---|---|---|---|---|---|---| | W3 | $0.65 | control | 1105 | +195.79 | 61.1% | 1.49 | 20.9 | +76.87 | +118.92 | 70195fb0 | | W3 | $0.65 | both | 824 | +205.12 | 63.1% | 1.73 | 12.4 | +76.72 | +128.40 | ad3b0dbd | | W3 | $0.65 | buy | 999 | +188.21 | 61.3% | 1.52 | 20.9 | +60.40 | +127.81 | 6e0f3b74 | | W3 | $0.65 | sell | 930 | +212.70 | 62.7% | 1.66 | 13.7 | +93.19 | +119.52 | 31aa5762 | | W3 | $0.30 | control | 1105 | +216.53 | 61.4% | 1.55 | 19.6 | +88.86 | +127.67 | ce074a1b | | W3 | $0.30 | both | 824 | +221.18 | 63.6% | 1.81 | 11.4 | +86.41 | +134.77 | 96a87454 | | W3 | $0.30 | buy | 999 | +207.23 | 61.7% | 1.59 | 19.6 | +71.83 | +135.41 | 2ada14e4 | | W3 | $0.30 | sell | 930 | +230.48 | 63.1% | 1.73 | 12.8 | +103.45 | +127.03 | 49665c41 | | W2 | $0.65 | control | 813 | +154.15 | 62.2% | 1.53 | 15.6 | +70.10 | +84.04 | 5b65ecf6 | | W2 | $0.65 | both | 597 | +155.89 | 64.3% | 1.78 | 11.4 | +61.83 | +94.06 | dfc647ee | | W2 | $0.65 | buy | 718 | +154.67 | 63.0% | 1.62 | 14.4 | +65.03 | +89.65 | f23bfda4 | | W2 | $0.65 | sell | 692 | +155.36 | 63.3% | 1.65 | 13.7 | +66.91 | +88.46 | 1a071ac7 | | W2 | $0.30 | control | 813 | +167.53 | 62.6% | 1.59 | 14.5 | +78.61 | +88.91 | 15486607 | | W2 | $0.30 | both | 597 | +166.22 | 64.8% | 1.85 | 11.0 | +68.82 | +97.39 | d2f678bf | | W2 | $0.30 | buy | 718 | +166.64 | 63.4% | 1.68 | 14.0 | +73.12 | +93.52 | f3abc1e8 | | W2 | $0.30 | sell | 692 | +167.10 | 63.7% | 1.71 | 12.8 | +74.31 | +92.79 | d7d038fd | | RISING | $0.65 | control | 313 | +68.50 | 63.6% | 1.67 | 12.4 | +18.87 | +49.63 | 09b8a8e7 | | RISING | $0.65 | both | 258 | +63.78 | 64.3% | 1.80 | 9.1 | +23.97 | +39.81 | e87b6de1 | | RISING | $0.65 | buy | 303 | +60.15 | 63.0% | 1.60 | 12.4 | +18.87 | +41.28 | f001a0a6 | | RISING | $0.65 | sell | 268 | +72.13 | 64.9% | 1.89 | 9.1 | +23.97 | +48.16 | cbe4cb24 | | RISING | $0.30 | control | 313 | +76.21 | 64.5% | 1.77 | 11.1 | +22.92 | +53.29 | 5fc34cef | | RISING | $0.30 | both | 258 | +70.24 | 65.5% | 1.91 | 7.9 | +27.31 | +42.92 | 5de32f51 | | RISING | $0.30 | buy | 303 | +67.59 | 64.0% | 1.70 | 11.1 | +22.92 | +44.67 | 69b41026 | | RISING | $0.30 | sell | 268 | +78.86 | 66.0% | 2.00 | 7.9 | +27.31 | +51.54 | 3631466e | | LONG | $0.65 | control | 2091 | +192.53 | 57.8% | 1.24 | 64.8 | | | c2228398 | | LONG | $0.65 | both | 1473 | +223.33 | 59.7% | 1.42 | 41.5 | | | aa5253aa | | LONG | $0.65 | buy | 1762 | +214.62 | 58.9% | 1.33 | 34.5 | | | 952d64d8 | | LONG | $0.65 | sell | 1802 | +201.23 | 58.3% | 1.30 | 76.4 | | | d3965ab8 | | LONG | $0.30 | control | 2091 | +240.00 | 58.8% | 1.31 | 49.6 | | | 0c58b300 | | LONG | $0.30 | both | 1473 | +257.25 | 60.8% | 1.50 | 37.2 | | | 1835b341 | | LONG | $0.30 | buy | 1762 | +254.33 | 59.9% | 1.40 | 29.5 | | | a2b519bd | | LONG | $0.30 | sell | 1802 | +242.92 | 59.4% | 1.37 | 62.3 | | | f6edb469 | | HOLDOUT | $0.65 | control | 24 | −6.63 | 50.0% | 0.42 | 7.0 | | | c42470a0 | | HOLDOUT | $0.65 | both | 18 | −4.62 | 50.0% | 0.50 | 4.8 | | | fa50bcd0 | | HOLDOUT | $0.65 | buy | 22 | −6.81 | 45.5% | 0.41 | 7.0 | | | 548a4bf4 | | HOLDOUT | $0.65 | sell | 20 | −4.44 | 55.0% | 0.52 | 4.8 | | | 1459ef5f | | HOLDOUT | $0.30 | control | 24 | −6.29 | 50.0% | 0.44 | 6.7 | | | d7fbee9d | | HOLDOUT | $0.30 | both | 18 | −4.35 | 50.0% | 0.52 | 4.5 | | | 2179c08c | | HOLDOUT | $0.30 | buy | 22 | −6.49 | 45.5% | 0.43 | 6.7 | | | 0b90faeb | | HOLDOUT | $0.30 | sell | 20 | −4.15 | 55.0% | 0.54 | 4.5 | | | 70932b7e | **M5** | Window | Cost | Variant | Trades | Total R | Win rate | PF | Max DD | First half | Second half | MD5 (8) | |---|---|---|---|---|---|---|---|---|---|---| | W3 | $0.65 | control | 870 | +153.64 | 53.3% | 1.50 | 10.1 | +16.73 | +136.91 | d20ec8a3 | | W3 | $0.65 | both | 668 | +159.07 | 53.9% | 1.70 | 15.2 | +14.01 | +145.06 | 39cc0f19 | | W3 | $0.65 | buy | 741 | +156.53 | 53.4% | 1.60 | 9.6 | +15.68 | +140.85 | 631f25ac | | W3 | $0.30 | control | 870 | +172.40 | 54.3% | 1.57 | 8.9 | +21.08 | +151.32 | 5acafcba | | W3 | $0.30 | both | 668 | +174.43 | 54.8% | 1.79 | 14.3 | +18.09 | +156.34 | 34f2e282 | | W3 | $0.30 | buy | 741 | +172.72 | 54.3% | 1.69 | 8.9 | +19.87 | +152.86 | c8bdc9e2 | | W2 | $0.65 | control | 781 | +146.07 | 52.9% | 1.52 | 10.1 | +26.42 | +119.65 | e599c8a8 | | W2 | $0.65 | both | 585 | +153.82 | 53.7% | 1.78 | 15.2 | +33.16 | +120.66 | b9fa356c | | W2 | $0.65 | buy | 656 | +151.09 | 53.0% | 1.66 | 9.6 | +27.42 | +123.66 | 30e243b0 | | W2 | $0.30 | control | 781 | +162.09 | 53.9% | 1.60 | 8.9 | +31.71 | +130.37 | 7ab48db9 | | W2 | $0.30 | both | 585 | +166.59 | 54.7% | 1.87 | 14.3 | +38.05 | +128.54 | 3427b933 | | W2 | $0.30 | buy | 656 | +164.66 | 54.0% | 1.74 | 8.9 | +32.58 | +132.08 | 7dd9e2a2 | | RISING | $0.65 | control | 86 | +9.47 | 53.5% | 1.33 | 8.2 | +0.01 | +9.46 | 65c46e62 | | RISING | $0.65 | both | 81 | +9.07 | 54.3% | 1.34 | 7.5 | +0.67 | +8.40 | e20fdef2 | | RISING | $0.65 | buy | 85 | +10.55 | 54.1% | 1.39 | 7.2 | +0.01 | +10.54 | de24b2e8 | | RISING | $0.30 | control | 86 | +12.42 | 54.7% | 1.46 | 6.7 | +1.65 | +10.77 | 5c154360 | | RISING | $0.30 | both | 81 | +11.91 | 55.6% | 1.47 | 6.1 | +2.28 | +9.63 | 3b1a8f9e | | RISING | $0.30 | buy | 85 | +13.46 | 55.3% | 1.52 | 5.7 | +1.65 | +11.81 | 21ffab88 | | LONG | $0.65 | control | 1052 | +128.10 | 50.5% | 1.34 | 18.4 | | | 3f0c091c | | LONG | $0.65 | both | 790 | +127.47 | 50.4% | 1.45 | 25.2 | | | 9872c068 | | LONG | $0.65 | buy | 871 | +123.37 | 49.9% | 1.39 | 27.1 | | | 613dcf0e | | LONG | $0.30 | control | 1052 | +153.02 | 51.7% | 1.41 | 13.0 | | | 6708d8cc | | LONG | $0.30 | both | 790 | +147.13 | 51.5% | 1.54 | 19.6 | | | 201d968f | | LONG | $0.30 | buy | 871 | +144.02 | 51.1% | 1.47 | 22.3 | | | d9cba459 | | HOLDOUT | $0.65 | control | 33 | −2.45 | 51.5% | 0.82 | 6.1 | | | 351f7149 | | HOLDOUT | $0.65 | both | 26 | −2.04 | 50.0% | 0.81 | 5.4 | | | b9c8cb82 | | HOLDOUT | $0.65 | buy | 33 | −2.45 | 51.5% | 0.82 | 6.1 | | | 351f7149 | | HOLDOUT | $0.30 | control | 33 | −1.85 | 51.5% | 0.86 | 5.6 | | | 5a6aea9c | | HOLDOUT | $0.30 | both | 26 | −1.56 | 50.0% | 0.85 | 5.0 | | | ddd29068 | | HOLDOUT | $0.30 | buy | 33 | −1.85 | 51.5% | 0.86 | 5.6 | | | 5a6aea9c | **H1, for the record** ($0.65): W3 control 253 / +70.02R / PF 1.98 / DD 4.4 (`a44fd19b`), `both` 231 / +60.28R / PF 1.90 / DD 4.4 (`cdac563b`); HOLDOUT 3 / −3.04R in both (no trade removed). Fails (a) (60.28 < 67.92) and (b). H4 was not run: it confirms on the daily chart already. ### 5.3 Per calendar year ($0.65), total R / trades M15, LONG 2019-01-01 → 2026-08-07: | Variant | 2019 | 2020 | 2021 | 2022 | 2023 | 2024 | 2025 | 2026 | |---|---|---|---|---|---|---|---|---| | control | +9.0 / 117 | +48.8 / 283 | −25.6 / 210 | −24.6 / 267 | +11.7 / 211 | +53.3 / 343 | +81.2 / 425 | +38.7 / 235 | | both | +14.0 / 88 | +45.1 / 207 | −27.3 / 121 | +3.2 / 149 | +1.8 / 163 | +53.5 / 275 | +92.5 / 341 | +40.6 / 129 | | buy | +7.6 / 111 | +44.2 / 253 | −21.4 / 135 | +7.4 / 166 | +1.6 / 189 | +46.4 / 335 | +83.1 / 416 | +45.9 / 157 | | sell | +15.4 / 94 | +49.7 / 237 | −31.5 / 196 | −28.8 / 250 | +11.9 / 185 | +60.4 / 283 | +90.6 / 350 | +33.4 / 207 | M5, LONG: | Variant | 2019 | 2020 | 2021 | 2022 | 2023 | 2024 | 2025 | 2026 | |---|---|---|---|---|---|---|---|---| | control | −1.0 / 20 | −2.8 / 95 | −1.7 / 32 | −2.2 / 50 | −2.8 / 61 | +1.0 / 102 | +40.5 / 332 | +97.0 / 360 | | both | +0.2 / 17 | −6.9 / 76 | −3.4 / 14 | −4.7 / 28 | −3.5 / 54 | +1.5 / 96 | +43.2 / 297 | +101.0 / 208 | | buy | +0.2 / 17 | −6.7 / 83 | −3.2 / 16 | −6.0 / 30 | −4.6 / 56 | +2.1 / 101 | +40.5 / 329 | +101.0 / 239 | M15, W3 per calendar year (total R / trades / max DD inside the year): | Variant | 2023 (from 09-05) | 2024 | 2025 | 2026 (to 09-05) | |---|---|---|---|---| | control | +10.8 / 66 / 9.0 | +53.3 / 343 / 16.3 | +81.2 / 425 / 15.6 | +50.5 / 271 / 10.3 | | both | +9.3 / 47 / 6.9 | +53.5 / 275 / 11.0 | +92.5 / 341 / 11.4 | +49.9 / 161 / 8.3 | M15, R per month from 2025-09 (W3): | Variant | 2025-09 | 10 | 11 | 12 | 2026-01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 (to 09-05) | |---|---|---|---|---|---|---|---|---|---|---|---|---|---| | control | +14.7 | −1.4 | +3.7 | +19.4 | +29.1 | −2.2 | +9.5 | +4.4 | +0.0 | +1.7 | −4.6 | +12.4 | +0.2 | | both | +19.4 | +0.6 | +8.4 | +18.7 | +32.4 | −2.4 | +1.5 | +7.2 | −2.4 | +5.1 | +2.3 | +5.9 | +0.2 | Losing runs on M15: longest run of losing trades 9 → 8 (W3 and LONG); worst calendar month −10.1R → −6.1R (W3, 2024-01) and −11.7R → −10.0R (LONG); losing months 11 → 8 of 37 on W3, 39 of 92 → 37 of 91 on LONG. ### 5.4 Rule T, clause by clause **M15 `both` — PASS** | Clause | Result | Numbers (candidate vs control) | |---|---|---| | (a) W3 R ≥ 97% of control | PASS | +205.12 vs +195.79 (97% = +189.92) | | (b) W3 PF ≥ control + 0.10 | PASS | 1.734 vs 1.488 | | (c) W3 max DD ≤ control | PASS | 12.39 vs 20.87 | | (d) LONG R ≥ control | PASS | +223.33 vs +192.53 | | (d) LONG max DD ≤ control | PASS | 41.54 vs 64.77 | | (d) 2021 + 2022 better | PASS | −24.12 vs −50.21 | | (e) HOLDOUT R ≥ control − 0.5 | PASS | −4.62 (18 trades) vs −6.63 (24) | | (f) (a) at $0.30 | PASS | +221.18 vs +216.53 (97% = +210.04) | | (f) (b) at $0.30 | PASS | 1.809 vs 1.551 | | (f) (c) at $0.30 | PASS | 11.44 vs 19.56 | | (g) ≥ 3 of 4 neighbours pass (a) and (c) | PASS | 3 of 4 (table 5.5) | | (h) ≥ 20 trades differ on W3 | PASS | 281 removed, 0 added | **M15 `buy` — FAIL**: (a) +188.21 < +189.92; (b) 1.523 < 1.588; the same two at $0.30. **M15 `sell` — FAIL**: (d) LONG max DD 76.39 > 64.77 and 2021 + 2022 −60.29 < −50.21. It has the best W3 total (+212.70R) and that is exactly the trap the long window was there to catch: in the falling years the buys against the daily trend are the losers, and `sell` keeps them. **M5 `both` — FAIL**: (c) W3 DD 15.20 > 10.11 (also at $0.30: 14.30 > 8.88); (d) LONG R +127.47 < +128.10, LONG DD 25.25 > 18.39, 2021 + 2022 −8.02 < −3.91; (g) 0 of 4. **M5 `buy` — FAIL**: (d) LONG R +123.37 < +128.10, LONG DD 27.14 > 18.39, 2021 + 2022 −9.13 < −3.91; (g) 1 of 4. **H1 `both` — FAIL** (a), (b). ### 5.5 Clause (g): neighbouring definitions (research harness) The harness (K1 + K2 of the twin with the veto OFF, a host-side mask on the final candidates before the cooldown, the shared resolver) reproduces the twin's `--set` books byte for byte for the shipped definition, so it is the same thing as the shipped path for a final veto: | Book ($0.65) | Harness CSV MD5 | Twin CSV MD5 | |---|---|---| | M15 W3 control | `70195fb0e6865b3a46ee8a9aa8844e51` | same | | M15 W3 `both` | `ad3b0dbda0bf77b659caea1c53be6a50` | same | | M15 LONG control | `c222839878f791e980b2dbc99fb6dfbd` | same | | M15 LONG `both` | `aa5253aab206fd21fa6a8d5ba25b75b5` | same | | M5 W3 control / `both` / `buy` | `d20ec8a3…` / `39cc0f19…` / `631f25ac…` | same | | M5 LONG control / `both` / `buy` | `3f0c091c…` / `9872c068…` / `613dcf0e…` | same | M15, veto in both directions, each neighbour replacing the definition of "clear daily trend": | Definition | W3 trades | W3 R | W3 PF | W3 DD | (a) | (c) | LONG trades | LONG R | LONG PF | LONG DD | |---|---|---|---|---|---|---|---|---|---|---| | control | 1105 | +195.79 | 1.49 | 20.87 | (97% = +189.92) | | 2091 | +192.53 | 1.24 | 64.77 | | **shipped: 50-day average AND 60-day change** | 824 | +205.12 | 1.73 | 12.39 | PASS | PASS | 1473 | +223.33 | 1.42 | 41.54 | | 60-day change alone | 752 | +188.25 | 1.73 | 11.89 | FAIL | PASS | 1328 | +228.11 | 1.49 | 27.30 | | 90-day change alone | 782 | +196.14 | 1.72 | 12.46 | PASS | PASS | 1412 | +228.75 | 1.46 | 37.36 | | 120-day change alone | 781 | +199.36 | 1.75 | 12.26 | PASS | PASS | 1397 | +233.19 | 1.47 | 34.79 | | 100-day average alone | 796 | +201.23 | 1.74 | 12.26 | PASS | PASS | 1375 | +227.30 | 1.47 | 32.56 | 3 of 4 pass. Every neighbour beats the control on PF and on drawdown in both windows; the one miss is 1.7R under the 97% line. It is a plateau. (Each neighbour has a lower LONG drawdown than the shipped definition; switching to one now would be the rescue the rule forbids.) M5: `both` 0 of 4 (every neighbour keeps the 15.2R drawdown), `buy` 1 of 4 (90-day, 120-day and 100-day average all fall under the 97% line). No plateau on M5. ### 5.6 What the veto removes (M15, $0.65) Zero trades are added in any window (W3 and LONG, every variant, both timeframes): the setups inside a vetoed setup's 5-bar cooldown point the same way under the same daily state and are vetoed with it, so the cooldown displaces nothing. | Slice | W3 trades | W3 R | W3 mean R | LONG trades | LONG R | LONG mean R | |---|---|---|---|---|---|---| | all removed | 281 | −9.32 | −0.033 | 618 | −30.80 | −0.050 | | BUY against a falling daily trend | 106 | +7.59 | +0.072 | 329 | −22.10 | −0.067 | | SELL against a rising daily trend | 175 | −16.91 | −0.097 | 289 | −8.70 | −0.030 | | removed, grade B | 210 | −11.53 | −0.055 | 408 | −25.69 | −0.063 | | removed, grade A | 46 | +1.28 | +0.028 | 164 | −1.12 | −0.007 | | removed, grade A+ | 14 | +4.26 | +0.304 | 26 | +1.81 | +0.069 | | removed, grade C | 11 | −3.34 | −0.304 | 20 | −5.80 | −0.290 | | kept (the new book) | 824 | +205.12 | +0.249 | 1473 | +223.33 | +0.152 | | kept BUY | 763 | +194.20 | +0.255 | 1302 | +222.50 | +0.171 | | kept SELL | 61 | +10.91 | +0.179 | 171 | +0.83 | +0.005 | Reading: the removed trades are close to break-even after costs (−0.03 to −0.05R each) while the kept trades earn +0.15 to +0.25R each. The veto does not find big losers; it drops about a quarter of the trades, the ones with no edge, and with them the long flat-to-down stretches. The two halves of the veto are carried by different windows: the SELL half by the rising 3-year window, the BUY half by the falling years of the long window. Only the symmetric rule holds on both. Share of trades that reach +1R before −1R (same entries, fixed 1R target, `--fixed-rr-tp 1.0`, $0.65): M15 W3 58.6% → 61.4% (1105 → 824 trades), M15 LONG 55.9% → 58.2%; M5 W3 56.8% → 58.2%, M5 LONG 55.3% → 56.1%. Checklist breakdowns, M15 W3 → with the veto (trades / R), $0.65: | Slice | Control | Veto | Change in R | |---|---|---|---| | regime ranging | 140 / +46.75 | 106 / +49.23 | +2.48 | | regime transitioning | 264 / +47.05 | 199 / +49.47 | +2.42 | | regime trending_down | 165 / −4.39 | 43 / +9.71 | +14.10 | | regime trending_up | 536 / +106.38 | 476 / +96.70 | −9.68 | | volatility extreme | 508 / +103.91 | 361 / +95.86 | −8.05 | | volatility high | 228 / +4.00 | 135 / +18.32 | +14.32 | | volatility normal | 202 / +58.96 | 177 / +57.01 | −1.96 | | volatility low | 167 / +28.92 | 151 / +33.94 | +5.01 | | BUY | 869 / +201.79 | 763 / +194.20 | −7.59 | | SELL | 236 / −6.00 | 61 / +10.91 | +16.91 | | setup GENERIC | 1004 / +184.73 | 757 / +192.15 | +7.42 | | setup XAU_ATR | 101 / +11.07 | 67 / +12.97 | +1.90 | | Monday | 188 / +36.54 | 145 / +52.46 | +15.92 | | Tuesday | 240 / +44.89 | 186 / +41.82 | −3.07 | | Wednesday | 234 / +12.08 | 165 / +13.36 | +1.28 | | Thursday | 216 / +63.84 | 157 / +70.36 | +6.51 | | Friday | 214 / +33.51 | 162 / +21.04 | −12.47 | | Sunday evening | 13 / +4.94 | 9 / +6.08 | +1.14 | By entry hour (UTC), change in R on W3 / on LONG: 03 +0.3 / +1.5; 04 −2.1 / −0.1; 05 −0.2 / +2.6; 06 +1.9 / −1.5; 07 +2.9 / +0.9; 08 −5.3 / −0.3; 09 −6.6 / −4.0; 12 −2.9 / +2.7; 14 +11.8 / +12.9; 15 −4.0 / +1.8; 17 −0.5 / −2.4; 18 +11.4 / +11.3; 19 +0.9 / +2.7; 20 +0.8 / +2.9; 22 +0.8 / −0.1. The weekday and hour changes are not stable in sign between the two windows except hours 14 and 18 (positive in both) and hour 9 (negative in both); none of it is a reason to act. ### 5.7 Verdict T - **M15: `both` PASSES every clause and SHIPS** (`pair_signals/xauusd.py`, M15 override 7). - **M5: no veto.** `both` deepens the worst losing run (10.1R → 15.2R) and loses the long window; `buy` passes the 3-year window and fails the long one, with no plateau. The M5 book earns almost all of its R in 2025–2026 and the daily trend adds nothing reliable to it. - **H1 / H4: no veto.** H1 loses 10R of 70R; H4 already confirms on the daily chart. - On the timeframes without the veto the daily trend is shown on the alert as information only. What the owner gives up, as agreed: in the purely rising stretch the veto costs R. W2 first half (2024-09 → 2025-09) +61.83R vs +70.10R; the RISING window +63.78R vs +68.50R; W2 at $0.30 +166.22R vs +167.53R. What it buys: the worst losing run on the 3-year window falls from 20.9R to 12.4R, on the 7.6-year window from 64.8R to 41.5R, 2022 turns from −24.6R to +3.2R, and the three weeks after the test window (HOLDOUT, never seen by any tuning) lose 4.6R instead of 6.6R. 2021 does not improve (−27.3R vs −25.6R) and 2023 is worse (+1.8R vs +11.7R): in a year that chops sideways the daily trend flips late and the veto cannot help. ### 5.8 Candidate C — wide-stop cap on M15 (post-T control) Control = the factory configuration after the M15 flip (daily-trend veto on). Command per row: `venv/bin/python backtest/cudaBasedBacktesting.py --pair XAUUSD --primary-tf 15min --start --end --spread <0.65|0.30> [--set xau_strategy.wide_stop_cap_atr=] --export-csv `. Paired proof on this control: W3, K = 6, `gpu_backtest.py --workers 12` and the twin both give `f94f1429fb4c9172427ea34c2f4d92a1` (824 / +216.87R / DD 11.37). | Window | Cost | K | Trades | Total R | Win rate | PF | Max DD | First half | Second half | MD5 (8) | |---|---|---|---|---|---|---|---|---|---|---| | W3 | $0.65 | off | 824 | +205.12 | 63.1% | 1.73 | 12.4 | +76.72 | +128.40 | ad3b0dbd | | W3 | $0.65 | 5 | 824 | +211.26 | 61.4% | 1.74 | 15.0 | +81.77 | +129.48 | 055d72a4 | | W3 | $0.65 | **6** | 824 | +216.87 | 62.9% | 1.78 | 11.4 | +80.67 | +136.20 | f94f1429 | | W3 | $0.65 | 7 | 824 | +213.15 | 63.1% | 1.76 | 11.8 | +79.08 | +134.07 | 5ea4ab4b | | W3 | $0.65 | 8 | 824 | +208.01 | 62.9% | 1.74 | 12.3 | +77.18 | +130.84 | 372ac298 | | W3 | $0.30 | off | 824 | +221.18 | 63.6% | 1.81 | 11.4 | +86.41 | +134.77 | 96a87454 | | W3 | $0.30 | 5 | 824 | +228.46 | 62.1% | 1.82 | 14.0 | +92.27 | +136.18 | 7453b5f7 | | W3 | $0.30 | **6** | 824 | +233.37 | 63.6% | 1.86 | 11.0 | +90.67 | +142.70 | bf7e4157 | | W3 | $0.30 | 7 | 824 | +229.37 | 63.7% | 1.84 | 11.0 | +88.88 | +140.48 | e44cb5b5 | | W3 | $0.30 | 8 | 824 | +224.12 | 63.5% | 1.82 | 11.3 | +86.91 | +137.22 | c214455b | | W2 | $0.65 | off | 597 | +155.89 | 64.3% | 1.78 | 11.4 | +61.83 | +94.06 | dfc647ee | | W2 | $0.65 | 5 | 597 | +156.59 | 63.3% | 1.79 | 11.4 | +62.63 | +93.96 | 5e5c0207 | | W2 | $0.65 | **6** | 597 | +160.79 | 64.0% | 1.81 | 11.4 | +61.31 | +99.48 | 3614c98a | | W2 | $0.65 | 7 | 597 | +158.70 | 64.3% | 1.79 | 11.4 | +60.19 | +98.51 | afa7eb01 | | W2 | $0.65 | 8 | 597 | +156.58 | 64.2% | 1.78 | 11.4 | +60.54 | +96.04 | ba29cc41 | | RISING | $0.65 | off | 258 | +63.78 | 64.3% | 1.80 | 9.1 | +23.97 | +39.81 | e87b6de1 | | RISING | $0.65 | 5 | 258 | +57.68 | 61.6% | 1.71 | 8.0 | +22.85 | +34.83 | 295731a3 | | RISING | $0.65 | **6** | 258 | +58.03 | 64.0% | 1.72 | 8.6 | +23.84 | +34.19 | 8dba71d7 | | RISING | $0.65 | 7 | 258 | +62.18 | 64.3% | 1.78 | 8.8 | +26.44 | +35.74 | c461380f | | RISING | $0.65 | 8 | 258 | +62.12 | 63.6% | 1.77 | 9.1 | +24.06 | +38.07 | fce21577 | | LONG | $0.65 | off | 1473 | +223.33 | 59.7% | 1.42 | 41.5 | | | aa5253aa | | LONG | $0.65 | 5 | 1473 | +204.76 | 58.4% | 1.38 | 53.1 | | | b365f28f | | LONG | $0.65 | **6** | 1473 | +233.56 | 59.7% | 1.44 | 47.2 | | | 4aa12918 | | LONG | $0.65 | 7 | 1473 | +228.83 | 59.8% | 1.43 | 46.5 | | | 6e91e0dd | | LONG | $0.65 | 8 | 1473 | +223.79 | 59.7% | 1.42 | 43.2 | | | 36267a43 | | LONG | $0.30 | off | 1473 | +257.25 | 60.8% | 1.50 | 37.2 | | | 1835b341 | | LONG | $0.30 | 5 | 1473 | +241.64 | 59.8% | 1.46 | 44.9 | | | 6a346020 | | LONG | $0.30 | **6** | 1473 | +268.63 | 60.8% | 1.52 | 41.6 | | | 526ffa4a | | LONG | $0.30 | 7 | 1473 | +263.16 | 60.9% | 1.51 | 42.1 | | | 3f42a60e | | LONG | $0.30 | 8 | 1473 | +257.84 | 60.8% | 1.50 | 38.9 | | | ffbba3e4 | | HOLDOUT | $0.65 | off, 6, 7, 8 | 18 | −4.62 | 50.0% | 0.50 | 4.8 | | | fa50bcd0 | | HOLDOUT | $0.65 | 5 | 18 | −4.62 | 50.0% | 0.50 | 4.8 | | | 3ff32a0d | (W2 and RISING at $0.30 and the HOLDOUT at $0.30 are in the same direction as the $0.65 rows: W2 +171.35 vs +166.22 for K = 6; RISING +64.66 vs +70.24; HOLDOUT unchanged.) LONG per calendar year ($0.65), total R (trades are identical: 88 / 207 / 121 / 149 / 163 / 275 / 341 / 129): | K | 2019 | 2020 | 2021 | 2022 | 2023 | 2024 | 2025 | 2026 | |---|---|---|---|---|---|---|---|---| | off | +14.0 | +45.1 | −27.3 | +3.2 | +1.8 | +53.5 | +92.5 | +40.6 | | 5 | +19.0 | +27.9 | −32.4 | −1.0 | +2.5 | +63.1 | +89.2 | +36.6 | | 6 | +19.5 | +46.7 | −31.8 | +1.8 | +4.7 | +59.8 | +88.1 | +44.8 | | 7 | +16.5 | +45.4 | −32.2 | +4.3 | +1.8 | +59.2 | +91.1 | +42.7 | | 8 | +14.5 | +43.9 | −29.0 | +3.4 | +2.9 | +54.4 | +92.3 | +41.4 | Trades the cap touches (the trade set is identical by construction; only stops, and through them results, move). All of them are swing (GENERIC) setups; the gold ATR setup is never capped: | Window | K | Stops changed | R of those trades: control → capped | |---|---|---|---| | W3 | 5 / 6 / 7 / 8 | 281 / 168 / 89 / 44 | +66.4 → +72.5 / +49.2 → +60.9 / +25.6 → +33.6 / +12.2 → +15.1 | | LONG | 5 / 6 / 7 / 8 | 597 / 350 / 170 / 83 | +97.5 → +78.9 / +56.7 → +66.9 / +37.0 → +42.5 / +12.5 → +13.0 | | RISING | 5 / 6 / 7 / 8 | 97 / 58 / 25 / 12 | +28.1 → +22.0 / +21.0 → +15.3 / +13.1 → +11.5 / +5.7 → +4.0 | | HOLDOUT | 5 / 6 / 7 / 8 | 3 / 0 / 0 / 0 | −3.03 → −3.04 | **Rule C, K = 6** | Clause | Result | Numbers | |---|---|---| | W3 change in R ≥ +5R | PASS | +11.75 (+216.87 vs +205.12) | | W3 first half ≥ control − 1R | PASS | +80.67 vs +76.72 | | W3 second half ≥ control − 1R | PASS | +136.20 vs +128.40 | | W3 PF ≥ control − 0.02 | PASS | 1.777 vs 1.734 | | W3 max DD ≤ control + 10% | PASS | 11.37 vs 12.39 | | LONG total R ≥ control | PASS | +233.56 vs +223.33 (but max DD 47.19 vs 41.54) | | same sign at $0.30 | PASS | +12.19 (+233.37 vs +221.18) | | ≥ 20 trades differ | PASS | 168 stops and results changed | | neighbour K = 5 not negative on W3 | PASS | +6.14 | | **neighbour K = 5 not negative on LONG** | **FAIL** | **−18.57** | | neighbour K = 7 not negative on W3 | PASS | +8.04 | | neighbour K = 7 not negative on LONG | PASS | +5.50 | **Verdict C: FAIL. Nothing ships; `wide_stop_cap_atr` stays 0.0 (research knob only).** K = 6 is a narrow peak, not a plateau: one step tighter loses 18.6R over the long window (2020 alone −17R), one step wider keeps half the gain, two steps wider keeps none. The cap also costs R in the rising window at every K (−1.6R to −6.1R), deepens the long-window drawdown at every K (41.5R → 43.2R to 53.1R) and changes nothing in the unseen three weeks. This agrees with the planning-phase screen of 25 stop and exit variants: the stop geometry is at a plateau, and tightening it is the one direction that reliably loses. No second K is tried (the rule's no-rescue clause). ### 5.9 What shipped, and the re-pinned books Shipped: `pair_signals/xauusd.py` M15 override 7, `config.xau_strategy.daily_trend_veto = "both"` on M15 only. Not shipped: any veto on M5 / H1 / H4; the wide-stop cap (knob kept at 0.0). Reference books after the flip, factory configuration, `--spread 0.65`, regenerated with BOTH scripts (`gpu_backtest.py --workers 12` and `cudaBasedBacktesting.py`), `Backend: CuPy GPU (NVIDIA GeForce RTX 4070 SUPER, cupy 14.0.1)`, `GPU cache fallbacks: 0`: | Book | Window | Trades / R / PF / DD | MD5 (reference = twin) | | |---|---|---|---|---| | M5 W2 | 2024-09-05 → 2026-09-05 | 781 / +146.07 / 1.52 / 10.1 | `e599c8a8652f95b7fcdf5a7ef2b564f5` | unchanged | | M15 W2 | 2024-09-05 → 2026-09-05 | 597 / +155.89 / 1.78 / 11.4 | `dfc647ee02afd179dd9e031f344ed380` | re-pinned (was `5b65ecf6…`, 813 / +154.15 / 1.53) | | M15 OOS | 2024-06-01 → 2025-03-30 | 258 / +63.78 / 1.80 / 9.1 | `e87b6de12f90f3b5a5d41a953ee9ff7a` | re-pinned (was `09b8a8e7…`, 313 / +68.50 / 1.67) | | H1 W3 | 2023-09-05 → 2026-09-05 | 253 / +70.02 / 1.98 / 4.4 | `a44fd19b4067f46e5bd98d50cc3eff92` | unchanged | | H4 W3 | 2023-09-05 → 2026-09-05 | 114 / +21.7 / 1.59 | `f3587bae3c5dc3eda468ea3588b17dcb` | unchanged | | M15 W3 | 2023-09-05 → 2026-09-05 | 824 / +205.12 / 1.73 / 12.4 | `ad3b0dbda0bf77b659caea1c53be6a50` | was `70195fb0…`, 1105 / +195.79 / 1.49 | The factory books are byte-identical to the `--set xau_strategy.daily_trend_veto=both` books of section 5.2, as they must be. ### 5.10 A fetch bug found on the way (fixed, not a signal change) The first HOLDOUT and RISING runs with the daily frame failed with `OandaDataError: XAU/USD 1d: 3 consecutive failures fetching window 2020-08-01–2020-08-01 … (Empty candle response)`. Since 2026-09-13 `fetch_range` retries a failing page and aborts after three tries, while the Oanda provider raised on an EMPTY date window. A padded window that starts on a closed day (the daily pad is 1,400 days = exactly 200 weeks, so a window starting on a Saturday pads to a Saturday) begins with a page nothing traded in, and the whole fetch aborted. Fix in `providers/oanda.py`: a DATE-WINDOW request with no candles returns an empty frame (a `count` request, the live path, still raises); two Module 15 tests. Books are unaffected (every pinned window was already cached; the ten MD5s reproduce). New cache files fetched for this campaign: the daily frames `oanda_XAU_USD_1d_20201105_20260905`, `_20150303_20260807`, `_20200801_20250330`, `_20221105_20261001`, and the HOLDOUT window `5min` / `15min` / `1h` `_20260705_20261001` and `4h_20260114_20261001`. The two interior gaps the HOLDOUT fetch logged are market closures (Labor Day 2026-09-07, Good Friday 2026-04-02), not dropped pages. ### 5.11 Setup size: what the evidence supports, and the display lines that shipped "Trade setup size" was tested two ways. **The stop itself.** Candidate C (section 5.8) fails its rule, and the planning-phase screen of 25 stop and exit variants found nothing better than the shipped geometry (a flat 2 × ATR stop on M15 turns +196R into +3R). The stops stay as they are. **How much is at risk at once.** If every alert is taken, the plans pile up. Shipped books, W3, $0.65 (`M15` = veto on): | Books taken together | Trades | Same-direction plans already open at an entry: mean | median | max | Entries with ≥ 1 open | with ≥ 3 open | Open at once while anything is open: mean | max | Share of the time something is open | |---|---|---|---|---|---|---|---|---|---| | M15 alone | 824 | 1.17 | 1 | 6 | 62% | 15% | 1.70 | 7 | 41% | | M5 alone | 870 | 0.69 | 0 | 6 | 40% | 7% | 1.36 | 7 | 23% | | M5 + M15 | 1694 | 1.70 | 1 | 12 | 66% | 26% | 1.97 | 13 | 51% | | M5 + M15 + H1 | 1947 | 2.75 | 2 | 15 | 78% | 43% | 2.60 | 16 | 65% | The stacked entries are not worse trades (M5 + M15, by the number of same-direction plans already open at the entry: 0 → +0.154R per trade over 577; 1 → +0.218R over 410; 2 → +0.241R over 271; 3–4 → +0.282R over 267; 5 or more → +0.236R over 169). So there is no evidence for skipping them, and the 2026-09-06 sizing campaign already showed that varying the stake by signal features does not pay. What the numbers do say is that "1% per alert" is in practice several percent on one move of gold. That is a sizing fact for the reader, so it ships as information, not as a gate: - **Size line** (`exposure.py`, off until `config.json` `trade_size.risk_per_trade` is set): the number of lots that keeps the loss at the printed stop inside the owner's risk limit, rounded DOWN to the lot step. Private by default (owner chats and the CLI); the channel and the public dashboard get it only with `trade_size.telegram_channel` / `trade_size.dashboard`. - **Already-open line**: how many ALERTED plans in the same direction are still open in the advisory outcome model (`signal_log.open_alerted_setups`, a read-only query; the bot stamps `alerted_at` on a row once its alert reached a chat). - **Daily-trend line** on every surface (`main.daily_trend_words`): on M15 the veto has already removed a plan against a clear daily trend; on M5 / H1 / H4, where the veto failed its rule, the line is context ("Daily trend: falling — this buy goes against it"). The live wrapper stamps the trend on every logged scan row (`signals.daily_trend`), so the live record can answer the M5 question again after a few months. None of the three is read by a gate, the backtester or the twin. ### 5.12 Final verification (2026-10-01) - `venv/bin/python test_all.py`: **607 passed, 0 failed** (40 modules: Module 39 daily-trend veto and wide-stop cap, Module 40 the display lines, Module 37 extended, two Module 15 tests for the empty-window fetch). - The five reference books regenerated with both scripts after the last code change: ten MD5s equal the table in section 5.9. - Recorder and feature export with the veto on, M15 2024-06-01 → 2025-03-30, `--export-features --record DIR --record-bars` on both scripts: feature CSV `732f396bb3ee6036b62750a8c755194e` on both; `trades` 258 × 137, `indicators` 5900 × 15, `events` 5098 × 14 and `bars` 12315 × 172 identical; both manifests carry book MD5 `e87b6de12f90f3b5a5d41a953ee9ff7a` and differ only in `cli`, `created_at`, `replay_seconds`, `workers`; `replay_scorecard.py DIR --check`: all invariants held. - `agent_panel_base_rates.json` rebuilt from the re-pinned books (M15 timeframe row 597 trades, 64.3% winners, +0.261R; was 813 / 62.2% / +0.190R). ### 5.13 Independent verification (2026-10-01) An agent that had not done the work re-derived the change list from `git diff HEAD` and re-ran the books itself (24 on the twin, 9 on the reference script, all offline, 0 cache fallbacks). Every figure of sections 5.2 to 5.9 it was given matched to the cent, on both scripts where it ran both: the M15 books with the veto on and off (W3, W2, the 2024-06-01 → 2025-03-30 window, LONG with its per-year R, the holdout), the unchanged M5 / H1 / H4 pins, the failed M5, H1, `buy` and `sell` variants, and the removed-trade tables (281 removed on W3, 0 added, all 63 columns of the 824 kept trades identical). Its own implementation of the rule from closed daily bars predicts the removed trades exactly (281 / 281, 618 / 618, 55 / 55); the same rule fed the still-forming day mis-predicts 52, 129 and 14 of them, so there is no look-ahead. The scoring configuration is identical to HEAD on all four timeframes; the only decision-side difference is the M15 veto. It also raised four points this report did not make clearly enough. They change no verdict; they are recorded so the size of the claim is not overstated. 1. **Clause (g) is thinner than "3 of 4" reads.** The "100-day average alone" neighbour of table 5.5 is an EXPONENTIAL average, the same kind as the shipped 50-day one (harness key `e100`). With a SIMPLE 100-day average the M15 W3 book is 781 / +188.68R / PF 1.70 / drawdown 12.27R: it beats the control on profit factor and drawdown like the others, but sits 1.2R under the 97% line (+189.92R), so with that reading the count would be 2 of 4. The four definitions were fixed before the runs in the harness's own form and the clause passes as written; the honest summary is "five alternative definitions, all better than the control on profit factor and drawdown, two of them 1.2R and 1.7R short on total R". 2. **"The veto never adds a trade" is an observation, not a guarantee.** The rule itself only removes a plan. In a book, removing an entry also moves the 5-bar cooldown, which could free a later entry; that happened 0 times in every control / candidate pair compared (13). 3. **It is a risk filter, not a better direction call.** Nothing in how direction is scored changed, and a vetoed bar still shows its buy or sell reading. The removed plans were close to break-even (−0.03R each on W3, −0.05R on LONG; 55% winners against 63% for the kept ones), so total R barely moves while profit factor and the losing runs improve. 4. **The help is concentrated.** Effect of the rule by year on LONG (shipped minus off): 2019 +4.9R, 2020 −3.7R, 2021 −1.8R, 2022 **+27.8R**, 2023 **−10.0R**, 2024 +0.1R, 2025 +11.4R, 2026 +1.9R; total +30.8R, of which 2022 (buys against a falling daily trend) is nine tenths. On W3 the whole gain in R comes from sells removed in 2025, and the drawdown cut from 20.9R to 12.4R is one episode: 13 sells between 2023-12-01 and 2024-02-23 (−8.5R). In a year where the daily trend flips often (2023) the rule costs. The multi-year windows had been looked at with the prototype before rule T was written (section 2), and the only period nobody had seen is four weeks long and differs by six trades. Cross-checked here from the formal books (a filter on the control book reproduces the shipped book and the exponential neighbour exactly, and gives the simple-average figure above). ## 6. Summary of decisions | Item | Verdict | |---|---| | Daily-trend veto, M15, both directions | **PASSED rule T on every clause, SHIPPED** (factory M15 override 7) | | Daily-trend veto, M15, buy-only / sell-only | FAILED (W3 R and PF / LONG drawdown and 2021–22) | | Daily-trend veto, M5 (both, buy-only) | FAILED (W3 drawdown; LONG R, drawdown, 2021–22; no plateau) | | Daily-trend veto, H1 | FAILED (W3 −9.7R); H4 not run | | Wide-stop cap K = 6 on M15 | FAILED rule C (neighbour K = 5 loses 18.6R on LONG); knob kept at 0.0, research-only | | Lot-size, already-open and daily-trend lines | SHIPPED, display only (books byte-identical) | | Oanda empty date window | FIXED (fetch_range no longer aborts on a closed-day page) | | Seven further context screens | no state nominated, nothing shipped (`context_screens_2026-10.md`) | | Eight outside data sources (dollar, silver, bonds, real yield, fund flows, futures and Oanda client positioning) | none adds a forecast to gold's own daily trend; broad dollar index on M5 = WATCH; nothing shipped, no feed added (`new_inputs_2026-10.md`) |