From 9a8a2c1aa1ec6489574bd6854e89661306419cd6 Mon Sep 17 00:00:00 2001 From: Harwinder Sekhon Date: Thu, 3 Sep 2026 20:47:33 -0400 Subject: [PATCH] xauusd factory: block M5 shorts in transitioning regime, block all H1 shorts (rule-1 validated) M5 sell_blocked_regimes=[transitioning]: 12mo +7.9R (PF 1.50->1.56, both halves up), 5yr +5.3R, OOS unchanged. H1 sell_min_quality=[]: 5yr +16.7R (PF 1.18->1.46), OOS +11.5R (PF 1.13->1.74), 12mo -1.8R with both halves positive. Campaign table, rejected and parked candidates: backtest/research/signal_log_campaign_2026-09.md Claude-Session: https://claude.ai/code/session_01FC4s6VCURFte4dub4xKxYL --- .../research/signal_log_campaign_2026-09.md | 180 ++++++++++++++++++ docs/beginner_guide.html | 2 + docs/user_guide.html | 4 +- pair_signals/xauusd.py | 52 +++++ 4 files changed, 236 insertions(+), 2 deletions(-) create mode 100644 backtest/research/signal_log_campaign_2026-09.md diff --git a/backtest/research/signal_log_campaign_2026-09.md b/backtest/research/signal_log_campaign_2026-09.md new file mode 100644 index 0000000..2ebe3dd --- /dev/null +++ b/backtest/research/signal_log_campaign_2026-09.md @@ -0,0 +1,180 @@ +# Signal-log audit → prediction-quality campaign — 2026-09-03 + +**Source evidence:** `logs/signals.db` 2026-08-13 → 2026-09-03 (14,683 rows, candle +snapshots from 08-18), replayed with the repo's own advisory outcome model +(`analyze_signal_log.py --stored-candles`; the replay reproduces +`advisory_outcome.py` to 5e-17 on the 49 panel-seeded rows), cross-checked +against the pinned Oanda books (`backtest/oanda_*_065*.csv`). + +## Live-log findings that motivated the campaign + +| View (3 weeks, $0.65 rt) | n | WR | R | PF | +|---|---|---|---|---| +| every unique setup event | 144 | 67% | +37.8 | 1.93 | +| opportunities (first per tf+direction, 60 min) | 66 | 67% | +18.3 | 1.92 | +| one-position-per-TF (5-bar cooldown) | 32 | 62% | +6.6 | 1.53 | +| direction BUY / SELL | 121 / 23 | 70% / 48% | +43.2 / −5.4 | 2.53 / 0.56 | + +- Two rally days (08-19, 08-21) contribute essentially all of the R. +- SELL is negative in every view; in the books SELL is the weakest bucket on + every TF (H1 SELL −16.7R/5yr PF 0.77, −11.5R OOS PF 0.30; M15 SELL −11.7R OOS; + M5 SELL in `transitioning` −7.9R/12mo PF 0.21, −5.2R/5yr PF 0.49). +- Bollinger is anti-predictive on all four TFs (forward-return hit 0.26–0.50 at + 12 bars) and "opposes" 93% of taken book trades; divergence is inverted on + M15/H1 live and trades where it opposed outperform in the books. +- Refuted live hypotheses (books disagree): ADX<20 gate, exhaustion gate, + NEAR-EMA200 gate, EXTREME-volatility gate, capping SL/ATR. + +## Method (rule 1) + +Harness: `backtest/gpu_backtest.py --pair XAUUSD --spread 0.65` on the CPU +backend (CuPy present but the GPU was not reachable; the M5 12mo control +reproduces the pinned `oanda_m5_12mo_065_nopb_20260814.csv` trade-for-trade +except the two trades on the end date, which `--end` excludes). Every candidate +is compared with a CONTROL produced on the same harness, never with the pinned +book directly. Windows (cache start = start − 62 days): + +| window | `--start` | `--end` | +|---|---|---| +| 12mo (M15/H1) | 2025-08-04 | 2026-08-04 | +| 12mo (M5 canonical) | 2025-08-14 | 2026-08-14 | +| 5yr | 2021-08-01 | 2026-08-04 | +| OOS | 2024-06-01 | 2025-03-30 | + +Acceptance: positive total R in both 12mo halves, PF ≥ 1.3, OOS not worse +than control, and a candidate that removes a net-positive bucket for a PF-only +gain is rejected (big-candle precedent). Runner: +`/campaign/run_campaign.sh`; summary: `summarize.py`. + +Candidates (all `--set`, no code): + +- **B1 SELL gating** — H1 `xau_strategy.sell_min_quality=[]` (block all H1 + shorts); M5 `xau_strategy.sell_blocked_regimes=["transitioning"]`; M15 + `xau_strategy.sell_min_quality=["B"]`. +- **B2 divergence off** — `technical.disabled_indicators=["divergence"]` on + M15 and H1 (M5 divergence-down was rejected 2026-08-04; not re-run). +- **B3 Bollinger weight 0 in trending regimes** — full + `technical.regime_weights_override` with bollinger 0.0 in + trending_up/trending_down/trending, ranging/transitioning unchanged; M5, M15, H1. + +## Results + +Every control reproduced its pinned book: M15 12mo (`ctl_m15_12mo`) is exact +at 397/+73.93R/PF 1.53; all three H1 controls are exact; the M5 12mo control +(`base_m5_12mo`) is exact except for the two trades that fall on the end +date, which `--end` excludes on this harness (see Method above). + +| book | n | R | PF | DD | H1 | H2 | sellN | sellR | ΔR vs control | ΔPF | +|---|---|---|---|---|---|---|---|---|---|---| +| b1_h1_nosell_12mo | 91 | +22.2 | 1.79 | 4.1 | +20.6 | +1.6 | 0 | +0.0 | -1.8 | +0.25 | +| b1_h1_nosell_5yr | 335 | +49.1 | 1.46 | 13.2 | -5.0 | +54.1 | 0 | +0.0 | +16.7 | +0.28 | +| b1_h1_nosell_oos | 78 | +16.7 | 1.74 | 3.6 | +7.3 | +9.4 | 0 | +0.0 | +11.5 | +0.61 | +| b1_m15_sellB_12mo | 341 | +74.6 | 1.62 | 10.8 | +68.4 | +6.2 | 82 | +9.1 | +0.7 | +0.09 | +| b1_m15_sellB_5yr | 1378 | +119.1 | 1.22 | 41.4 | -21.3 | +140.3 | 335 | +3.7 | -8.9 | +0.02 | +| b1_m15_sellB_oos | 272 | +47.1 | 1.51 | 13.8 | +12.3 | +34.8 | 59 | -3.4 | +8.3 | +0.15 | +| b1_m5_selltrans_12mo | 557 | +112.2 | 1.56 | 9.9 | +55.9 | +56.4 | 75 | +14.8 | +7.9 | +0.06 | +| b1_m5_selltrans_5yr | 889 | +133.7 | 1.41 | 12.8 | -8.3 | +142.0 | 88 | +9.0 | +5.3 | +0.03 | +| b1_m5_selltrans_oos | 86 | +9.4 | 1.33 | 8.2 | -1.4 | +10.9 | 4 | +1.5 | +0.0 | +0.00 | +| b2_h1_nodiv_12mo | 149 | +28.6 | 1.62 | 6.5 | +23.6 | +5.0 | 49 | +5.5 | +4.6 | +0.07 | +| b2_h1_nodiv_5yr | 567 | +40.5 | 1.20 | 14.1 | -5.2 | +45.6 | 203 | -18.2 | +8.1 | +0.02 | +| b2_h1_nodiv_oos | 119 | +7.6 | 1.17 | 7.7 | -1.9 | +9.5 | 31 | -14.3 | +2.4 | +0.04 | +| b2_m15_nodiv_12mo | 439 | +81.3 | 1.51 | 13.1 | +72.3 | +8.9 | 147 | +7.0 | +7.4 | -0.02 | +| b2_m15_nodiv_5yr | 1771 | +139.9 | 1.20 | 47.4 | -16.2 | +156.1 | 578 | +11.7 | +11.9 | -0.01 | +| b2_m15_nodiv_oos | 341 | +52.3 | 1.43 | 17.1 | +15.6 | +36.7 | 93 | -10.0 | +13.5 | +0.07 | +| b3_h1_bb0_12mo | 154 | +31.2 | 1.64 | 9.4 | +22.8 | +8.4 | 52 | +6.7 | +7.3 | +0.09 | +| b3_h1_bb0_5yr | 583 | +37.3 | 1.18 | 18.3 | -7.4 | +44.7 | 206 | -20.4 | +4.9 | +0.00 | +| b3_h1_bb0_oos | 122 | +5.6 | 1.12 | 8.7 | -2.0 | +7.6 | 32 | -13.8 | +0.4 | -0.01 | +| b3_m15_bb0_12mo | 439 | +49.9 | 1.29 | 19.4 | +61.6 | -11.8 | 151 | +0.3 | -24.0 | -0.23 | +| b3_m15_bb0_5yr | 1790 | +126.6 | 1.18 | 42.3 | -1.8 | +128.5 | 592 | +17.4 | -1.3 | -0.03 | +| b3_m15_bb0_oos | 345 | +55.5 | 1.47 | 12.4 | +18.2 | +37.3 | 94 | -8.4 | +16.7 | +0.11 | +| b3_m5_bb0_12mo | 621 | +84.0 | 1.35 | 16.6 | +49.3 | +34.7 | 104 | +9.7 | -20.4 | -0.14 | +| b3_m5_bb0_5yr | 987 | +113.0 | 1.31 | 15.3 | -7.7 | +120.6 | 134 | +12.0 | -15.5 | -0.08 | +| b3_m5_bb0_oos | 93 | +10.6 | 1.35 | 5.6 | -2.9 | +13.5 | 9 | +3.7 | +1.2 | +0.01 | +| b12_h1_nosell_nodiv_12mo | 100 | +23.1 | 1.75 | 4.6 | +21.8 | +1.3 | 0 | +0.0 | -0.8 | +0.20 | +| b12_h1_nosell_nodiv_5yr | 364 | +58.7 | 1.52 | 12.9 | -4.1 | +62.8 | 0 | +0.0 | +26.3 | +0.34 | +| b12_h1_nosell_nodiv_oos | 88 | +21.9 | 1.92 | 4.8 | +9.4 | +12.5 | 0 | +0.0 | +16.8 | +0.79 | +| base_m5_12mo | 575 | +104.3 | 1.50 | 10.7 | +50.8 | +53.5 | 93 | +6.9 | — | — | +| ctl_h1_12mo | 138 | +24.0 | 1.55 | 8.0 | +19.4 | +4.6 | 47 | +1.8 | — | — | +| ctl_h1_5yr | 515 | +32.4 | 1.18 | 15.2 | -5.9 | +38.3 | 180 | -16.7 | — | — | +| ctl_h1_oos | 104 | +5.1 | 1.13 | 7.5 | -0.9 | +6.1 | 26 | -11.5 | — | — | +| ctl_m15_12mo | 397 | +73.9 | 1.53 | 10.8 | +66.7 | +7.2 | 138 | +8.5 | — | — | +| ctl_m15_5yr | 1578 | +128.0 | 1.21 | 35.8 | -3.4 | +131.4 | 535 | +12.6 | — | — | +| ctl_m15_oos | 299 | +38.8 | 1.36 | 15.5 | +5.9 | +32.9 | 86 | -11.7 | — | — | +| ctl_m5_5yr | 911 | +128.4 | 1.39 | 12.8 | -8.3 | +136.7 | 110 | +3.8 | — | — | +| ctl_m5_oos | 86 | +9.4 | 1.33 | 8.2 | -1.4 | +10.9 | 4 | +1.5 | — | — | + +Raw table (n / R / PF / WR% / DD / H1 / H2 / PF-half-1 / PF-half-2 / +sellN / sellR / ΔR / ΔPF / Δn vs control; control and `base_m5_12mo` +rows carry no delta): + +``` +book n R PF WR% DD H1 H2 PF1 PF2 sellN sellR | ΔR ΔPF Δn +b1_h1_nosell_12mo 91 +22.2 1.79 62.6 4.1 +20.6 +1.6 2.10 1.18 0 +0.0 | -1.8 +0.25 -47 +b1_h1_nosell_5yr 335 +49.1 1.46 58.2 13.2 -5.0 +54.1 0.87 1.78 0 +0.0 | +16.7 +0.28 -180 +b1_h1_nosell_oos 78 +16.7 1.74 62.8 3.6 +7.3 +9.4 1.67 1.81 0 +0.0 | +11.5 +0.61 -26 +b1_m15_sellB_12mo 341 +74.6 1.62 62.8 10.8 +68.4 +6.2 2.15 1.10 82 +9.1 | +0.7 +0.09 -56 +b1_m15_sellB_5yr 1378 +119.1 1.22 57.0 41.4 -21.3 +140.3 0.91 1.46 335 +3.7 | -8.9 +0.02 -200 +b1_m15_sellB_oos 272 +47.1 1.51 60.7 13.8 +12.3 +34.8 1.24 1.85 59 -3.4 | +8.3 +0.15 -27 +b1_m5_selltrans_12mo 557 +112.2 1.56 53.7 9.9 +55.9 +56.4 1.54 1.58 75 +14.8 | +7.9 +0.06 -18 +b1_m5_selltrans_5yr 889 +133.7 1.41 51.5 12.8 -8.3 +142.0 0.84 1.52 88 +9.0 | +5.3 +0.03 -22 +b1_m5_selltrans_oos 86 +9.4 1.33 53.5 8.2 -1.4 +10.9 0.91 1.95 4 +1.5 | +0.0 +0.00 +0 +b2_h1_nodiv_12mo 149 +28.6 1.62 62.4 6.5 +23.6 +5.0 1.93 1.24 49 +5.5 | +4.6 +0.07 +11 +b2_h1_nodiv_5yr 567 +40.5 1.20 56.3 14.1 -5.2 +45.6 0.93 1.37 203 -18.2 | +8.1 +0.02 +52 +b2_h1_nodiv_oos 119 +7.6 1.17 56.3 7.7 -1.9 +9.5 0.91 1.44 31 -14.3 | +2.4 +0.04 +15 +b2_m15_nodiv_12mo 439 +81.3 1.51 60.8 13.1 +72.3 +8.9 1.90 1.11 147 +7.0 | +7.4 -0.02 +42 +b2_m15_nodiv_5yr 1771 +139.9 1.20 55.8 47.4 -16.2 +156.1 0.94 1.39 578 +11.7 | +11.9 -0.01 +193 +b2_m15_nodiv_oos 341 +52.3 1.43 59.2 17.1 +15.6 +36.7 1.23 1.68 93 -10.0 | +13.5 +0.07 +42 +b3_h1_bb0_12mo 154 +31.2 1.64 60.4 9.4 +22.8 +8.4 1.89 1.36 52 +6.7 | +7.3 +0.09 +16 +b3_h1_bb0_5yr 583 +37.3 1.18 54.5 18.3 -7.4 +44.7 0.90 1.35 206 -20.4 | +4.9 +0.00 +68 +b3_h1_bb0_oos 122 +5.6 1.12 55.7 8.7 -2.0 +7.6 0.91 1.33 32 -13.8 | +0.4 -0.01 +18 +b3_m15_bb0_12mo 439 +49.9 1.29 59.0 19.4 +61.6 -11.8 1.77 0.87 151 +0.3 | -24.0 -0.23 +42 +b3_m15_bb0_5yr 1790 +126.6 1.18 56.1 42.3 -1.8 +128.5 0.99 1.31 592 +17.4 | -1.3 -0.03 +212 +b3_m15_bb0_oos 345 +55.5 1.47 61.2 12.4 +18.2 +37.3 1.29 1.66 94 -8.4 | +16.7 +0.11 +46 +b3_m5_bb0_12mo 621 +84.0 1.35 51.4 16.6 +49.3 +34.7 1.43 1.28 104 +9.7 | -20.4 -0.14 +46 +b3_m5_bb0_5yr 987 +113.0 1.31 50.7 15.3 -7.7 +120.6 0.85 1.38 134 +12.0 | -15.5 -0.08 +76 +b3_m5_bb0_oos 93 +10.6 1.35 54.8 5.6 -2.9 +13.5 0.85 2.17 9 +3.7 | +1.2 +0.01 +7 +b12_h1_nosell_nodiv_12mo 100 +23.1 1.75 63.0 4.6 +21.8 +1.3 2.00 1.15 0 +0.0 | -0.8 +0.20 -38 +b12_h1_nosell_nodiv_5yr 364 +58.7 1.52 59.6 12.9 -4.1 +62.8 0.90 1.87 0 +0.0 | +26.3 +0.34 -151 +b12_h1_nosell_nodiv_oos 88 +21.9 1.92 63.6 4.8 +9.4 +12.5 1.93 1.92 0 +0.0 | +16.8 +0.79 -16 +base_m5_12mo 575 +104.3 1.50 52.9 10.7 +50.8 +53.5 1.46 1.53 93 +6.9 +ctl_h1_12mo 138 +24.0 1.55 60.9 8.0 +19.4 +4.6 1.84 1.22 47 +1.8 +ctl_h1_5yr 515 +32.4 1.18 55.7 15.2 -5.9 +38.3 0.91 1.34 180 -16.7 +ctl_h1_oos 104 +5.1 1.13 56.7 7.5 -0.9 +6.1 0.95 1.32 26 -11.5 +ctl_m15_12mo 397 +73.9 1.53 62.2 10.8 +66.7 +7.2 1.95 1.10 138 +8.5 +ctl_m15_5yr 1578 +128.0 1.21 56.5 35.8 -3.4 +131.4 0.99 1.37 535 +12.6 +ctl_m15_oos 299 +38.8 1.36 59.2 15.5 +5.9 +32.9 1.10 1.66 86 -11.7 +ctl_m5_5yr 911 +128.4 1.39 51.3 12.8 -8.3 +136.7 0.84 1.48 110 +3.8 +ctl_m5_oos 86 +9.4 1.33 53.5 8.2 -1.4 +10.9 0.91 1.95 4 +1.5 +``` + +## Decisions + +- **SHIPPED** — M5 `xau_strategy.sell_blocked_regimes=["transitioning"]` + (b1_m5_selltrans): 12mo +7.9R, 5yr +5.3R, OOS unchanged (no such trades + in that window); positive in both 12mo halves on every window. H1 + `xau_strategy.sell_min_quality=[]` (b1_h1_nosell, all H1 shorts blocked): + 5yr +16.7R and OOS +11.5R more than pay for the 12mo cost of -1.8R; H1 + shorts were -16.7R/5yr and -11.5R/OOS in the control. Both land in + `pair_signals/xauusd.py`. +- **REJECTED** — M15 `sell_min_quality=["B"]` (b1_m15_sellB): 5yr -8.9R + with max DD widening 35.8 -> 41.4R for a marginal +0.7R on 12mo; fails + the drawdown clause. All three B3 Bollinger-weight-0-in-trending-regimes + runs (b3_h1_bb0, b3_m15_bb0, b3_m5_bb0): negative on M5 (-20.4R/12mo, + -15.5R/5yr) and M15 (-24.0R/12mo, PF 1.29 -> still below the 12mo H2 + going negative at -11.8R); H1's B3 5yr gain (+4.9R) doesn't clear the + bar once M5/M15 fail outright — Bollinger's constant-oppose vote stays + a load-bearing quality bar, consistent with the 2026-08-04 audit. +- **DECLINED** — B2-M15 (`technical.disabled_indicators=["divergence"]` + on M15, b2_m15_nodiv): R improves on every window (+7.4/+11.9/+13.5R) + but 5yr max DD widens 35.8 -> 47.4R while PF stays flat (1.21 -> 1.20) — + more risk for no risk-adjusted gain; owner call. +- **PARKED** — B2-H1 (`technical.disabled_indicators=["divergence"]` on + H1, b2_h1_nodiv, standalone: +4.6/+8.1/+2.4R, PF 1.62/1.20/1.17). The + combined run with the H1 no-short override (b12_h1_nosell_nodiv) passes + rule 1 and beats the no-shorts override alone on both 5yr and OOS: 12mo + 100/+23.1R PF 1.75 (halves +21.8/+1.3), 5yr 364/+58.7R PF 1.52, OOS + 88/+21.9R PF 1.92. Not shipped anyway: it would route through + `technical.disabled_indicators`, which CLAUDE.md rule 8 reserves for + experiments, not production paths. Owner decision; recommended vehicle + is an H1-only `regime_weights_override` with divergence weight 0 plus a + fresh validation run under that mechanism. diff --git a/docs/beginner_guide.html b/docs/beginner_guide.html index b38ad78..400e32b 100644 --- a/docs/beginner_guide.html +++ b/docs/beginner_guide.html @@ -134,6 +134,8 @@ The message says: "once price hits 4,159, trail SL $33 behind best price."
  • H1 is forgiving. You have up to an hour to act on a message, and small delays barely matter. On the 5-minute signals, being two minutes late already costs real money — they are not for manual beginners.
  • H1 trades are held longer — often overnight, sometimes over days. That is normal. Your stop loss is working for you while you sleep.
  • +
  • H1 is BUY-only. All H1 SELL signals are blocked (since 2026-09-03) because they were a losing side on this timeframe — expect to see BUY signals here, never SELL.
  • +
  • M5 also holds back some SELL signals — specifically while the market is in a choppy "transitioning" phase, since those shorts tested poorly.
  • Never take the same signal on two timeframes. They are usually the same gold move seen at different zoom levels. Taking both doubles your risk, not your profit.
  • diff --git a/docs/user_guide.html b/docs/user_guide.html index ddc7078..f0e2119 100644 --- a/docs/user_guide.html +++ b/docs/user_guide.html @@ -96,9 +96,9 @@ Worst drawdown10.7R10.8R8.0R
    If you trade manually from the Telegram alerts, H1 (or M15) is the honest choice. M5's backtested edge assumes near-instant fills that a human copying signals rarely achieves.
    diff --git a/pair_signals/xauusd.py b/pair_signals/xauusd.py index 0089534..b099158 100644 --- a/pair_signals/xauusd.py +++ b/pair_signals/xauusd.py @@ -141,6 +141,49 @@ validated price of riding trends, exits confirmed NOT the loss driver: exit-management accounts for 1-2% of lost R vs 50% wrong-direction / 49% entry-timing). +M5 override 6 — SELL block in transitioning regime (validated +2026-09-03, signal-log campaign, `backtest/research/ +signal_log_campaign_2026-09.md`, $0.65 round trip, same CPU harness +as its control): sell_blocked_regimes=["transitioning"]. Live +evidence: M5 SELLs in transitioning were -7.9R/12mo PF 0.21 and +-5.2R/5yr PF 0.49 in the pinned books; the live signal log showed the +same pocket -7.9R/PF 0.56 over 3 weeks. Blocking: 12mo (2025-08-14 -> +2026-08-14) 557 trades +112.21R PF 1.56 (halves +55.9/+56.4, PF +1.54/1.58) vs control 575/+104.34R PF 1.50; 5yr (2021-08-01 -> +2026-08-04) 889/+133.7R PF 1.41 vs 911/+128.4R PF 1.39; OOS +2024-06-01 -> 2025-03-30 unchanged (86/+9.45R PF 1.33 — no such +trades in that window). Removed trades: 18 in 12mo (-7.9R), 22 in +5yr (-5.3R). + +H1 override — all SELL entries blocked (validated 2026-09-03, same +campaign): sell_min_quality=[] (gate 6e in signal_aggregator.py +downgrades any actionable-grade SELL whose quality is not in this +list to D, so an empty list downgrades every H1 short). H1 shorts +were a structural loser: -16.7R over the 5yr control window and +-11.5R OOS. Blocking: 12mo (2025-08-04 -> 2026-08-04) 91/+22.2R +PF 1.79 (halves +20.6/+1.6) vs control 138/+24.0R PF 1.55 (12mo cost +-1.8R); 5yr 335/+49.1R PF 1.46 vs 515/+32.4R PF 1.18; OOS 78/+16.7R +PF 1.74 vs 104/+5.1R PF 1.13. New reference books: +backtest/oanda_h1_{12mo,5yr,oos}_065_20260903.csv, +backtest/oanda_m5_12mo_065_nopb_20260903.csv, +backtest/oanda_m5_5yr_065_nopb_20260903.csv. + +Rejected/parked in the same campaign (see the memo for the full +table): M15 sell_min_quality=["B"] (5yr -8.9R, max DD 35.8 -> 41.4R +— REJECTED); Bollinger weight 0 in trending regimes on M5, M15, H1 +(M5 -20.4R/12mo, -15.5R/5yr; M15 -24.0R/12mo — REJECTED across the +board); divergence disabled on M15 (R improves +7.4/+11.9/+13.5R +across windows but 5yr max DD 35.8 -> 47.4R with PF flat — DECLINED, +owner call); divergence disabled on H1 (+4.6/+8.1/+2.4R, PF +1.62/1.20/1.17) — PARKED: it passes rule 1 in combination with the +H1 no-short override (b12_h1_nosell_nodiv: 12mo 100/+23.1R PF 1.75, +halves +21.8/+1.3; 5yr 364/+58.7R PF 1.52; OOS 88/+21.9R PF 1.92 — +better than the no-shorts override alone on both 5yr and OOS), but +shipping it would route through technical.disabled_indicators, which +CLAUDE.md rule 8 reserves for experiments; owner decision, recommended +vehicle is an H1-only regime_weights_override with divergence weight +0 plus a fresh validation run. + M5 override 5 — EMA partial-alignment squash (validated 2026-08-04, Oanda bars, $0.65 real spread): ema_partial_neutral True on M5 — partial 4-EMA ribbon alignment (2-3 of 4 checks) scores NEUTRAL @@ -216,6 +259,9 @@ def make_config( # Wider trailing distance on M5 only — see module docstring. config.signals.trail_arm_r = 0.60 config.signals.trail_dist_r = 0.85 + # Block SELL entries while the regime is "transitioning" on M5 + # only — see module docstring (M5 override 6). + config.xau_strategy.sell_blocked_regimes = ["transitioning"] if primary_tf == Timeframe.M15: # 1R minimum target on M15 only — see module docstring. config.signals.tp_floor_rr = 1.0 @@ -226,4 +272,10 @@ def make_config( # Later trailing-stop arm on M15 only — see module docstring. config.signals.trail_arm_r = 0.70 config.signals.trail_dist_r = 0.75 + if primary_tf == Timeframe.H1: + # Block every H1 SELL — the SELL quality gate (6e in + # signal_aggregator.py) downgrades any actionable-grade short + # to D when its grade is not in this list; an empty list means + # no grade qualifies. H1-only — see module docstring. + config.xau_strategy.sell_min_quality = [] return config