Earnings backfill sourced from the public DoltHub earnings repo at a pinned commit rather than the FMP API: reproducible for anyone re-running the study, and it burns no request quota. 12,414 events, 98.6% of symbols with >=8 announcements, 99.2% paired actual/estimate, no keyed duplicates. 2a earnings-gap diagnostic: INFORMATIONAL, no filter shipped. The pre-earnings cohort's right tail was better, so the registered avoid-earnings condition failed. Note the raw 23/266 vs 115/574 incidence gap is largely a duration confound -- severe losses stop out fast and have less time to span an announcement -- so it is not evidence that holding through earnings is safe. 2b SUE: FAIL against the pre-registered +0.03 bar (unconditional IC +0.0151 over 56 reliable windows, momentum-conditional +0.0213). Signs stable across eras, so this is a clean null rather than an ambiguous one, consistent with post-earnings drift having decayed in large caps. Closes the Tier-1 arc: Task 1 dead on deep evidence, Task 2 dead here, Task 3 complete as diagnostic. No in-sample research thread remains open. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
7.0 KiB
Earnings gap diagnostic + SUE / PEAD (Tier-1 alpha research)
Status: CLOSED — SUE DEAD.
Branch: research/earnings-gap-and-sue
Production impact: none. Local research only; no earnings filter or SUE integration is shipped.
Pre-registration (locked before the final research run)
Data
- Historical earnings announcements for the production universe, stored in the
real
earnings_eventstable and deduplicated on symbol + announcement date. - The originally requested 2016 start is amended, with user approval, to the public source's announcement coverage start of 2020-01-22. Earlier EPS-period history may scale later surprises but may never activate a live signal.
- Report coverage, pairing, duplicates/restatements, annual-rate sanity, and announcement-session quality before either experiment.
- Point-in-time: an earnings surprise is usable only from announcement date +1 trading day. Same-day use is forbidden.
Experiment 2a — earnings-gap risk (defense, report-only)
Run the production-config book on the approximately 505-name production universe with close fills and 0.001 transaction cost per side. Join simulated trades to earnings by symbol and date.
- Among closed trades with realized net R ≤ -1.0, report the fraction with an announcement strictly after entry and before exit, alongside the base rate for all trades.
- Compare entries within three trading sessions before an announcement with all other entries: count, mean/median R, win rate, p05, and p95.
- Compare stops within one trading session after an announcement with all other stops and exits.
Verdict is always INFORMATIONAL. Report only: no filter arm, recommendation,
or implementation. The right tail must be shown alongside the left tail.
Experiment 2b — SUE / PEAD (offense)
Signal sue_latest:
[ \text{SUE} = \frac{\text{actual} - \text{estimate}} {\sigma(\text{trailing 8 surprises})} ]
Use at least four trailing surprises; if estimate history fails the registered
quality gate, use (actual - estimate) / price and name that fallback. Activate
at announcement date +1 trading day, carry for 63 trading days, then drop the
symbol from the cross-section.
Evaluate mean weekly Spearman IC on the existing non-overlapping-window harness.
Always report sue_latest, mom_12_1, and mom_12_1_resid on identical
week-symbol-forward-return cells, plus SUE inside the top momentum quintile.
Mechanical verdict rule
- PASS only if unconditional
sue_latesthas mean IC ≥ +0.03,reliable: true(at least 12 windows), and positive signs in both the pre-2021 and post-2021 eras. - FAIL otherwise, with terminal verdict
SUE DEAD for this stack. - PASS stops at
SUE PASS→PENDING_HUMAN; integration design remains a separate human decision. FAIL is terminal and no variants are proposed.
Results
Data quality gate
Approved earnings window: 2020-01-22 to 2026-07-17. Source mode: dolthub_public_bulk_clone.
| check | result |
|---|---|
| Prod symbols requested / tradable | 506 / 505 |
| Manifest complete + live counts match | True |
| Prod symbols with pre-2021 bars | 491 (97.2%) |
| SPY benchmark depth | 2649 rows, 2016-01-04 to 2026-07-17 |
| Snapshot depth gate | True |
| Bulk source windows / requests logged | 1/1 / 1 |
| Source repository / pinned commit | https://www.dolthub.com/repositories/post-no-preference/earnings @ 9n0et3hpj9j7vue8f3qsldon3qa5sdjj |
| Source license / upstream provider documented | CC-BY-SA-4.0 / False |
| Existing-source conflicts preserved | 940 rows / 1526 fields |
| Symbols with >=8 announcements | 498 (98.6%) |
| Symbols with >=8 paired announcements | 495 (98.0%) |
| Events with estimate + actual | 12311/12414 (99.2%) |
| Duplicate rows in keyed table | 0 |
| Duplicate / restated payload rows fetched | 0 / 940 |
| Mean announcements per active symbol-year | 4.08 (expected about 4) |
| Symbols far off (<2 or >6/year, incl. zero) | 1 |
| Recognised BMO/AMC/during | 92.8% (reliable=True) |
| Point-in-time policy | announce_date_plus_1_trading_day_for_all_events |
| SUE price fallback | not_used |
Deduplication: UNIQUE(symbol, announce_date); normalise dot/dash symbols; retain one calendar row per key; preserve existing non-null session/EPS values from the prior FMP/Alpha Vantage partial backfill, then fill nulls and all remaining symbols from DoltHub; attach DoltHub period-end alignment
Far-off announcement-rate symbols: SPCX
Experiment 2a - earnings-gap risk diagnostic
Verdict: INFORMATIONAL. Report-only; no filter arm or implementation.
Trade cohort is restricted to the approved earnings-coverage window 2020-01-22 to 2026-07-17; 0 simulated trades outside that window were excluded.
| cohort | count | fraction |
|---|---|---|
| Realized net R <= -1.0 | 266 | - |
| Losses with announcement strictly inside hold | 23 | 0.0865 |
| All trades with announcement strictly inside hold | 115 | 0.2003 |
| Entry cohort | count | mean R | median R | win rate | p05 R | p95 R |
|---|---|---|---|---|---|---|
| Within 3 sessions before earnings | 27 | 0.4837 | -1.0265 | 0.3333 | -1.1463 | 5.981 |
| All other entries | 547 | 0.2734 | -0.8316 | 0.3565 | -1.1228 | 4.5888 |
Tail deltas (pre minus other): p05=-0.0235, p95=1.3922.
Registered directional tail condition is not present.
| Exit cohort | count | mean R | median R | win rate | p05 R | p95 R |
|---|---|---|---|---|---|---|
| Stops within 1 session after earnings | 26 | -0.6434 | -0.9753 | 0.2308 | -2.4614 | 1.1142 |
| All other stops | 433 | -0.5035 | -1.0278 | 0.1963 | -1.1373 | 1.3591 |
| All other exits | 548 | 0.3273 | -0.8361 | 0.3613 | -1.0644 | 4.7224 |
Experiment 2b - SUE / post-earnings drift
Mechanical verdict: FAIL - SUE DEAD for this stack
Identical cross-sections:
| signal | mean IC | t | windows | avg N | IC positive % | reliable |
|---|---|---|---|---|---|---|
| sue_latest | 0.0148 | 1.27 | 56 | 450.9 | 51.8 | true |
| mom_12_1 | 0.0195 | 0.74 | 56 | 450.9 | 58.9 | true |
| mom_12_1_resid | 0.0262 | 1.07 | 56 | 450.9 | 55.4 | true |
Unconditional SUE grade row:
| signal | mean IC | t | windows | avg N | IC positive % | reliable |
|---|---|---|---|---|---|---|
| sue_latest | 0.0151 | 1.29 | 56 | 451.4 | 51.8 | true |
Era stability:
| era | mean IC | t | windows | avg N | IC positive % | reliable |
|---|---|---|---|---|---|---|
| pre-2021 | 0.0286 | 0.7 | 9 | 398.3 | 55.6 | false |
| post-2021 | 0.0172 | 1.34 | 48 | 461.9 | 64.6 | true |
Coverage: 501 symbols with live SUE; avg weekly N=453.1; scored non-overlap avg N=451.4.
Cross-section is not flagged thin at the registered <100-name read.
Momentum-conditional top-quintile SUE: mean IC=0.0213, t=1.3, windows=56, avg N=89.8.
Artifacts
reports/earnings-2a-gap-20260720-dolthub-final.jsonand companion Markdownreports/earnings-2b-sue-20260720-dolthub-final.jsonand companion Markdownreports/earnings-backfill-status.json
Production changes: none. No earnings filter or SUE integration was implemented.