Files
ForexBot2/backtest/research/loss_anatomy_2026-09-18.md
T
Harwinder Sekhon 1454ea1838 Quant review 2026-09-26: alert cooldown, plain-language alerts, M15 grade-A SELL block, 1R printed targets, panel/breach fixes
Live signals.db review (2026-09-04 → 09-25, 100 unique setups replayed on the
scans' stored candles): the stop-hunt claim is refuted (71% of stop-outs ran
≥ 1R past the stop, the same as the books' 70–72%); −25.1R of the −37.8R raw
live book were consecutive-bar re-entries the backtester's 5-bar cooldown never
takes; the cooldown view sits at the 3rd–5th percentile of the books' three-week
windows.

Delivery (book-neutral):
- telegram_bot: 5-bar alert cooldown per timeframe (_ALERT_COOLDOWN_BARS =
  backtest.cooldown_bars); setup block prints the trail first as the tested
  exit, TP1/TP2 as guides with their R, "Planned TP1 RR", and one validated-book
  line per setup class (agent_panel_base_rates.json); the informational 100-pip
  TP line is removed (owner request).
- AI block rewritten for a new trader: "AI check: the odds look better than /
  worse than / about usual", the chance "in 100" against the usual odds, one
  reason for and one against, no verdict word or confidence figure; rendered
  whenever the verdict carries a probability. agent_panel: persona prompts ban
  trading jargon (PANEL_PROMPT_VERSION v2.1-2026-09-26); the macro-source
  verdict now carries its persona's p_win (every live v2 row had
  panel_probability NULL). Dashboard and guides mirror the wording.
- telegram_bot: level-breach rescans skip the settlement-pause window (the
  20:45 M15 bar was re-logged at 22:01/22:06/22:11 every evening).

Signal (pre-registered rule-1 campaign, CUDA twin paired with gpu_backtest.py):
- M15 grade-A SELLs blocked (sell_min_quality ["A+","B"], M15 override 6):
  W2 813/+154.15R PF 1.53 vs 931/+146.14R PF 1.43, OOS +68.5 vs +60.67,
  W3 max DD 20.9 vs 19.3R. PASSED a–f.
- Printed target 1 floored at 1R in every generator (signals.tp_print_floor_rr),
  applied AFTER the min-RR and spread gates so no trade changes; mirrored in
  cuda_signal_kernels.py K2. Label-only re-pin of all four timeframes (only
  tp1/rr_planned columns move). A floor applied before the gate cost −24.6R and
  was rejected.
- FAILED: M15 min_rr_ratio 1.0 (trade-identical, −2.0R). Owner's call: M5
  tp_floor_rr 1.0 (+48.9R W2, max DD 10.1 → 15.9R), not shipped.

New pins: M5 W2 e599c8a8…, M15 W2 5b65ecf6…, M15 OOS 09b8a8e7…, H1 W3
a44fd19b…, H4 W3 f3587bae…; twin and reference MD5s equal on every window.
Base-rate table rebuilt from the new pins. Suite 558 passed.

Evidence: backtest/research/rr_and_sell_campaign_2026-09-26.md (plus the
2026-09-18 loss-anatomy and wrong-direction reports it builds on).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-26 21:06:05 -04:00

10 KiB
Raw Blame History

Why the losing trades lost — two-year M5 and M15 books, 2026-09-18

Owner question: for every losing trade in the two-year books, was it the wrong direction, a late entry, a target the market reversed before reaching, or a bad hour or day? Descriptive, in-book statistics; nothing here is a decision (rule 1 needs a control-versus-candidate run).

1. Data

The validated two-year windows, 2024-09-05 → 2026-09-05, regenerated on the CUDA twin with the decision-time features attached (--export-features), $0.65 round trip, factory configuration:

venv/bin/python backtest/cudaBasedBacktesting.py --pair XAUUSD --primary-tf 5min  --start 2024-09-05 --end 2026-09-05 --spread 0.65 --export-features --export-csv w2_5min_feat.csv
venv/bin/python backtest/cudaBasedBacktesting.py --pair XAUUSD --primary-tf 15min --start 2024-09-05 --end 2026-09-05 --spread 0.65 --export-features --export-csv w2_15min_feat.csv

Backend: CuPy GPU (NVIDIA GeForce RTX 4070 SUPER, cupy 14.0.1), 0 cache fallbacks, 781 and 931 trades, the pinned books (49f8e602…, b4aa07e3…) with the research columns appended. Every stretch feature is signed in the trade's direction (positive = price had already moved the trade's way), so buys and sells read alike. "R" is risk units: profit or loss divided by the distance from entry to the initial stop. A loser is any trade with negative R.

Book Trades Losers Loss rate Loss R Win R Net R Full-stop losers Trailing-stop losers
M5 781 368 47.1% −278.9 +424.9 +146.1 247 (−257.8R) 115 (−19.1R)
M15 931 368 39.5% −341.0 +487.1 +146.1 324 (−336.4R) 39 (−2.6R)

Median loss −1.02R / −1.03R: a loser is almost always a full stop. The trailing exits' losses are small by construction.

2. Price path of the losers (what the market did after entry)

Path after entry M5 losers Share M5 loss R M15 losers Share M15 loss R
Never went our way (best excursion under 0.25R) 153 42% −157.9 (57%) 162 44% −166.9 (49%)
Shallow move, then reversal (0.25R to 0.75R) 165 45% −115.7 (41%) 185 50% −171.6 (50%)
Gave back a real advance (0.75R or more) 50 14% −5.3 (2%) 21 6% −2.5 (1%)
  • Wrong from the start is the largest single cause by R: over half the M5 loss and half the M15 loss comes from trades whose best moment was under a quarter of the risk. Median hold 12 bars (M5) and 18 bars (M15): they were stopped fast.
  • Reversals after a genuine advance cost almost nothing (1–2% of loss R): the trailing stop arms at 0.6R (M5) / 0.7R (M15) and limits the give-back. On M5, 81 losers (22%) did reach the full target-1 distance (median target-1 is only 0.51R on M5) and still closed red; they cost −23.8R. On M15 that is 15 losers, −7.1R.
  • Losers that reached at least half the target-1 distance: M5 157 (43%, −78.8R), M15 115 (31%, −80.8R). So roughly a third to two fifths of losers "were winning at some point".

Would a nearer hard target have helped? (all trades; exit at X when the best excursion reached X)

Hard target M5 losers rescued M5 winners capped M5 net M15 losers rescued M15 winners capped M15 net
0.50R 142 (+118.0R) 267 (−259.2R) +45.4 102 (+118.5R) 329 (−266.0R) +58.6
0.75R 50 (+42.8R) 203 (−201.4R) +72.1 21 (+18.2R) 244 (−194.6R) +97.5
1.00R 3 (+4.8R) 166 (−154.5R) +97.3 2 (+2.4R) 180 (−142.1R) +128.5
1.50R 0 94 (−91.5R) +117.2 0 97 (−74.7R) +143.5
2.00R 0 53 (−56.2R) +132.6 0 58 (−37.5R) +152.2
actual (trailing) +146.1 +146.1

A nearer target rescues losers but caps far more winners; the book's R lives in the right tail (top 5% of trades = 94–96% of R, cycle 1). Only a 2R hard target on M15 edges the trailing exit (+6R), which is the 2026-08-05 fixed-RR finding: it passes on 2024+ windows and is negative in 2021 and 2023 with double the drawdown. Not re-proposed.

3. Late entry: does chasing lose?

No. Loss rate falls as the entry gets "later"; the pullback-style entries are the worst bucket.

Move over the previous 12 bars in the trade's direction M5 trades Loss rate Avg R M15 trades Loss rate Avg R
Against the last 12 bars (pullback entry) 5 80% −0.39 14 64% −0.13
0 to 1 ATR 60 50% +0.18 43 44% −0.06
1 to 2 ATR 157 50% +0.14 148 38% +0.23
2 to 3 ATR 180 42% +0.28 288 41% +0.19
3 ATR or more (chased) 379 47% +0.17 438 38% +0.14
Hourly stretch (distance above the 20-bar hourly mean) M5 loss rate M5 net R M15 loss rate M15 net R
Below the mean 49% +19.4 43% +12.7
0 to 1 ATR 50% +21.9 45% +25.0
1 to 2 ATR 47% +42.6 41% +52.4
2 ATR or more (stretched) 45% +62.2 35% +56.1

Same picture for the 48-bar move (M5: 4 ATR or more = 44% loss rate and +128.5R of the +146.1R), the distance from the 21-bar average, consecutive closes and the exhaustion tags (two or more tags: 45% / 40% loss rate, the best bucket on M5). This is the 2026-08-04 age/stretch verdict again: the best trades are the stretched runs. "Late entry" is not a cause of losses here.

4. Wrong direction: what predicted the wrong side?

Condition at entry M5 trades Loss rate Net R M15 trades Loss rate Net R
Timeframes agreed 579 46% +128.4 897 39% +135.3
Timeframes did not agree 202 51% +17.7 34 44% +10.9
With the trend 475 45% +93.5 596 40% +68.1
No trend, ranging 169 49% +25.7 120 37% +47.0
No trend, transitioning 76 51% +24.0 213 41% +31.7
No trend, mixed trending 61 54% +2.9 (blocked on M15)
Confidence penalty 20 points or more 94 55% −3.3 11 64% −0.4
Buy 683 47% +137.3 635 37% +146.6
Sell 98 49% +8.8 296 46% −0.5
  • Disagreement between timeframes and a mixed regime raise the loss rate by about 5 points on M5 and remove most of the average R; the heavily penalised entries (20+ points) are net negative on both books but are few.
  • Indicator opposition does not predict the wrong side: the M5 bucket with no opposing indicator loses most often (58%, 40 trades). Direction was not "obviously wrong" at entry.
  • M15 shorts: 296 trades, 46% losers, −0.5R net. Every M15 R came from buys. This is the parked cycle-2 candidate (cycle_2026-09-10.md); unchanged status.

5. When we lost

Entry hour is the open of the bar after the signal bar (Coordinated Universal Time). Cells under 30 trades are noise.

M5 hour Trades Loss rate Net R M15 hour Trades Loss rate Net R
08:00 62 55% −0.7 07:00 68 47% −4.1
14:00 117 53% +4.7 09:00 75 47% +3.8
17:00 35 49% −4.0 18:00 45 47% −2.1
22:00 31 55% +4.0 04:00 28 43% +1.9
20:00 42 52% +30.1 14:00 154 40% +16.9
06:00 60 40% +26.5 12:00 68 31% +33.8

The weakest hours are 08:00 and 17:00 on M5 (14:00 is the busiest hour and carries the most loss R, −44.9R, at a 53% loss rate but still nets +4.7R) and 07:00, 09:00 and 18:00 on M15. No hour is both large and clearly negative; 20:00 on M5 loses 52% of the time and is the second best hour by R (+30.1R), which is the whole shape of this edge.

Weekday M5 trades Loss rate Net R M15 trades Loss rate Net R
Monday 153 45% +17.6 169 39% +28.2
Tuesday 159 48% +21.3 212 33% +50.4
Wednesday 176 45% +46.6 189 51% −4.0
Thursday 135 51% +9.2 179 40% +30.6
Friday 151 48% +47.7 169 36% +34.2

Wednesday is the one clear day effect: on M15 it loses more than half the time and is the only negative weekday (−86.2R of loss R, the worst of any day); the worst M15 weekday-hour cells are all Wednesday (14:00: 26 trades, 16 losers, −7.2R; 18:00: 13, 8, −4.7R; 09:00: 20, 14, −3.3R; 08:00: 16, 9, −3.0R). On M5 Wednesday is fine (+46.6R) and Thursday 20:00 is the worst cell (11 trades, 9 losers, −6.5R).

Calendar-day clusters are not the story: the ten worst days hold 11% (M5) and 9% (M15) of all loss R, no single day cost more than −4.2R, and only 27 of 333 (M5) and 15 of 449 (M15) entry days had three or more losers. Losers entered within two hours of the previous loser (re-entries into the same move): M5 46 (−39.5R, 14% of loss R), M15 22 (−21.7R, 6%). By month, July is negative on M15 in both years (2025-07 −7.5R at 57% losers, 2026-07 −8.6R at 58%) and M5 lost in 2024-Q4 and 2025-07/08.

6. Summary for the owner

Question Answer (both books unless stated)
Wrong direction? Yes for about 43% of losers by count and about half of the loss R: they never moved a quarter of the risk our way and were stopped within 12–18 bars. Nothing at entry flagged them: indicator opposition does not predict it, timeframe disagreement and mixed regimes add only ~5 points of loss rate.
Late entry? No. Loss rate falls as the prior move grows; the few pullback-style entries lose 64–80%. Stretched entries carry most of the R. (Confirms the 2026-08-04 verdict.)
Target too far, market reversed first? Rarely the cause of a loss: reversals after a 0.75R advance cost 1–2% of loss R because the trailing stop limits them. About a third of losers were up at least half the target-1 distance before losing; a nearer hard target would rescue them but cap far more winners (net +45R to +133R against +146R).
Bad hours? M5: 08:00 and 17:00 lose most often; 14:00 carries the most loss R but nets positive. M15: 07:00, 09:00 and 18:00. No large hour is clearly negative.
Bad days? Wednesday on M15 (51% losers, −4.0R net, all four worst weekday-hour cells). Not a single-day-cluster problem on either book.

None of this is a change proposal. A Wednesday or hour block on M15, or a shorter M15 SELL list, would each be a rule-1 campaign with a control run, the OOS window and the refuted-hypothesis list in mind (the 2026-07 M15 loss analysis rejected several hour variants). The most useful follow-up, if any, is the parked M15 grade-A SELL block, which this table supports without adding to it.