Files
ForexBot2/backtest/research/llm_news_eval_2026-08-06.md
T
Harwinder Sekhon 858c12280a news: DeepSeek validation, vs_forecast fix, /status source health
Validation (llm_news_eval.py harness + 78-headline golden CSV + verdict
doc): headline scoring 78/78 vs keyword baseline 24/78 — validated;
event gold-direction calls misread close K/M numeric comparisons ~11%
of the time (both claims cases in sample, JOLTS 8.79M vs 8.84M).

Fix: event payload now carries code-computed "vs_forecast" (from
EconomicEvent.surprise) and the prompt gains an explicit inverted-
metrics rule + worked claims example — iteration 1 (field alone) fixed
the arithmetic but exposed a masked inversion error. 18/18 on live
re-verification (4 misreads fixed, 11 regression cases clean, 3 fresh
both-side probes).

/status: new "News & AI" section — per-source health for the calendar
chain (which of FF/MyFXBook served), each RSS feed, and DeepSeek
(daily count, last error kind), written passively by the existing
fetch paths under _cache_lock. Failures WARN once on transition
(repeats DEBUG, recovery INFO) so the rotating log carries outage
stories without 10-min spam.

test_all.py: +5 Module 19 tests (351 total); also carries the Module 22
fixed-RR-TP tests from the prior research session (shared file).
Replay artifacts dir gitignored like commit_ladder.

Claude-Session: https://claude.ai/code/session_017mbXs9HRawZhD1uZ3ze7zQ
2026-08-06 22:21:02 -04:00

87 lines
4.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# DeepSeek news-analysis validation — 2026-08-06
**Verdict: headline sentiment scoring is excellent; event-direction calls are
directionally sound but ~11% of them misread the numeric comparison, and the
failure concentrates on Unemployment Claims / close K-M-suffixed values.**
Method (owner-directed, token-lean): independent expert re-analysis of a
stratified sample of DeepSeek's recorded answers, not a full statistical
backtest. Harness: `backtest/research/llm_news_eval.py` (replays releases
through the REAL `_llm_event_direction` / `_llm_headline_scores` — real
prompts, payloads, validation; raw wire traffic logged). 135 of the 586-event
corpus were replayed before the full run was stopped by owner request
(artifacts retained in `llm_news_eval_2026-08/`, resume-safe).
## Part A — event gold-direction (28-event stratified sample, Jan–Jun 2024)
Reviewer agreement with DeepSeek: **24/28 (86%)**. All 4 disagreements are
DeepSeek errors, in exactly two failure modes:
1. **Numeric comparison misread (3/28 ≈ 11%)** — the doctrine logic is right
but the premise is backwards:
- JOLTS 8.79M vs f 8.84M (a miss) → DS: "Job openings **above** forecast" → bearish (should be bullish)
- Claims 202K vs f 217K (fewer claims) → DS: "Claims **higher** than forecast" → bullish (should be bearish)
- Claims 202K vs f 209K — same backwards read, same wrong call
Both Unemployment Claims events in the sample were misread the same way —
looks systematic on that event type, possibly an anchoring prior that
"claims rose". All misreads involve close values with K/M suffixes.
2. **Direction field contradicts its own reason (1/28)** — Empire State
−43.7 vs f −4.9: reason text says "gold may rise", `gold_direction` says
`bearish`.
Where the numbers were read correctly, hawkish/dovish→gold mapping was
consistently correct (CPI/PPI/NFP/ADP/GDP/PMI/wages/unemployment-rate all
handled properly, including inverted metrics when read right).
Price cross-check (1h horizon, cluster-confounded, indicative only):
reviewer calls 22/28 with the subsequent move, DeepSeek 20/28.
## Part B — headline sentiment (78-headline golden set)
DeepSeek matched the reviewer's expected gold-direction label on
**78/78 (100%)** — including all 8 negation traps ("signals no rate hike",
"no rate cuts until…") and all 6 inverted-metric phrasings ("claims hit
two-year high"). The keyword scorer it overrides got **24/78 (31%)**.
Repeat-batch and shuffled-order probes recorded (headlines_replay.jsonl).
## Implications
- The headline-sentiment override (the main live LLM surface) is validated —
a large, measured upgrade over keywords.
- The event-direction enrichment ("— gold bullish/bearish" appended to
surprise descriptions) is right ~85–90% of the time but can state a
factually backwards comparison in the displayed reason. It is display-only
(never gates signals), so exposure is a possibly-misleading Telegram/CLI
line, not trades.
- **Hardening SHIPPED same day (owner-approved):** the payload now carries a
code-computed `vs_forecast` field ("above/below/in line with forecast",
from `EconomicEvent.surprise`) and the prompt tells the model to trust it.
First iteration fixed the arithmetic but exposed a masked doctrine error
(model read "claims below forecast" correctly, then called it a *weaker*
labor market — and regressed the unemployment-rate case the same way), so
the prompt's inverted-metrics line was expanded to an explicit rule plus a
worked claims example. Verification: **18/18** — all 4 original misreads
fixed, 11/11 no-regression cases unchanged, 3/3 fresh probes on the side
the prompt example does NOT cover (claims 245K vs f 220K → bullish,
unemployment 4.1% vs 3.9% → bullish, JOLTS 9.10M vs 8.80M → bearish).
Suite green at 346 tests, incl. a new payload assertion in Module 19.
- Production observations found while building the harness (not fixed):
`_llm_event_cache` key omits forecast → a repeated `actual` re-serves a
direction computed for a different forecast; a "neutral" reply is
indistinguishable from a failure in the return value.
## Reproduce
```
venv/bin/python backtest/research/llm_news_eval.py events --limit 5 # smoke
venv/bin/python backtest/research/llm_news_eval.py events --determinism 20
venv/bin/python backtest/research/llm_news_eval.py headlines
venv/bin/python backtest/research/llm_news_eval.py report # offline
```
Corpus: 586 high-impact USD surprises 2024-01→2026-07 (calendar.parquet,
NFP-verified UTC); prices: Oanda M15 mids. Full-run cost ≈ cents. The
`report` subcommand (hit rates vs always-bullish/doctrine/FF-betterWorse
baselines, McNemar, cluster view) is built and untested at scale — run it
after completing the replay if a statistical answer is ever wanted.