The Bid & Ask

Quotations, Dispatches, and the Daily Tape

Thursday, August 13, 2026

Rejected thesis

News-sentiment layer (removed from the model)

The result

Thesis (rejected): A lexicon-scored sentiment read over cached yfinance headlines carries enough signal to justify 16 % of the composite score.

Code: research/news/ (deleted — see git history at a86bb919~1) Report: none, and that is the finding.

Why it failed: it was never tested, in either direction.

The layer reached DEFAULT_HORIZON_WEIGHTS values of 0.20 / 0.15 / 0.10 (short / medium / long) — second-largest weight at the short horizon, behind catalyst — without ever facing walk-forward. It could not: the backtest config pins news to zero because yfinance cannot backdate headlines, so every weight sweep recorded in this file skipped it by construction. The coordinate-descent run says so explicitly ("21 non-news cells"), and the marginal sweep's "news shows zero impact" line is an artifact of exclusion, not a measurement. Every other layer in the model earned its weight in those sweeps. This one was handed a weight and exempted from the exam.

research/news_gap_validate.py was the only validator ever written, and its own docstring opened with SKELETON ONLY — it tested a different thesis (news gaps continuing vs technical gaps fading) and was blocked on a catalyst classifier that was never built. No report JSON was ever committed, which is the tell.

Blast radius before removal (50 tickers with per-layer scores.json, re-running judgment.judge() with and without the layer):

Measure Result
Ratings that change 1 / 50 (2 %)
Mean |Δ composite| 0.053
Spearman rank correlation 0.977
Top-10 turnover 0 / 10
Top-20 turnover 2 / 20

Notably the raw layer was the loudest input in the panel — mean |score| 0.629 against fundamental 0.343, technical 0.195, sector 0.092, sentiment 0.040 — and non-zero for 100 % of names. Large magnitude, no effect on ranking: after standardisation and orthogonalisation it was contributing variance, not information.

Verdict: removed 2026-08-06 from LAYERS, both weight presets, the orchestrator, the nightly refresh phase and the store's artifact kinds. The remaining weights renormalise in judge(), so the other layers keep their relative proportions.

Be precise about what this measured: it bounds the cost of removing the layer, not the value of keeping it. Nobody has shown news sentiment fails to predict returns. What was shown is that this implementation of it changed almost nothing, had never been validated, and could not be validated on the current data. If it comes back it needs a dated news source the harness can replay — otherwise it is unfalsifiable by design.

The API endpoint /companies/{symbol}/news stays in RETIRED_ENDPOINTS and keeps returning 410 with its explanation; it was already retired on licensing grounds, so removal broke no consumer.

At a glance
Validatorresearch/news/
VerdictRejected

Every result here is reproducible from the script named above. Reports are in the repository.

Other rejected theses