research: Task 2 closed — SUE dead, earnings gap informational

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>
This commit is contained in:
2026-07-20 21:10:46 +02:00
co-authored by Claude Fable 5
parent 1fa3d70dec
commit c7c60a64f2
14 changed files with 3705 additions and 1828 deletions
@@ -0,0 +1,348 @@
{
"generated_at": "2026-07-20T07:02:10.934892+00:00",
"snapshot": "C:\\Workspace\\signal-platform\\backtest_snapshots\\research.sqlite",
"snapshot_depth": {
"manifest": {
"schema_version": 1,
"snapshot": "research.sqlite",
"snapshot_resolved": "C:\\Workspace\\signal-platform\\backtest_snapshots\\research.sqlite",
"complete": true,
"finished_at": "2026-07-19T14:22:15.706192+00:00",
"ticker_count": 4650,
"ohlcv_row_count": 5081073,
"rank_only_count": 4144,
"sources": {
"pool": "source_snapshot"
},
"history_days": 5000,
"min_bars": 1262,
"fetch_ok": 505,
"fetch_fail": 1,
"limit": null,
"extra": {
"prod_symbols_at_start": 506,
"pool_size": 506,
"to_fetch": 506,
"source_symbols_only": true,
"benchmark_spy_rows": 2649
},
"live_counts": {
"ticker_count": 4650,
"ohlcv_row_count": 5081073,
"rank_only_count": 4144
}
},
"requested_symbols": 506,
"tradable_symbols": 505,
"missing_symbols": [],
"zero_bar_symbols": [
"RHM"
],
"bar_count": {
"min": 24,
"median": 2649,
"max": 2649
},
"symbols_with_pre2021_bars": 491,
"symbols_with_pre2021_bars_pct": 97.2,
"shallow_symbols_lt_1000_bars": [
{
"symbol": "SPCX",
"first_bar": "2026-06-12",
"last_bar": "2026-07-17",
"bars": 24
},
{
"symbol": "Q",
"first_bar": "2025-11-03",
"last_bar": "2026-07-17",
"bars": 176
},
{
"symbol": "PSKY",
"first_bar": "2025-08-07",
"last_bar": "2026-07-17",
"bars": 237
},
{
"symbol": "SNDK",
"first_bar": "2025-02-13",
"last_bar": "2026-07-17",
"bars": 357
},
{
"symbol": "GEV",
"first_bar": "2024-04-02",
"last_bar": "2026-07-17",
"bars": 575
},
{
"symbol": "SOLV",
"first_bar": "2024-04-01",
"last_bar": "2026-07-17",
"bars": 576
},
{
"symbol": "VLTO",
"first_bar": "2023-10-02",
"last_bar": "2026-07-17",
"bars": 700
},
{
"symbol": "KVUE",
"first_bar": "2023-05-04",
"last_bar": "2026-07-17",
"bars": 803
},
{
"symbol": "GEHC",
"first_bar": "2022-12-15",
"last_bar": "2026-07-17",
"bars": 898
}
],
"price_window": {
"min": "2016-01-04",
"max": "2026-07-17"
},
"benchmark_spy": {
"rows": 2649,
"min": "2016-01-04",
"max": "2026-07-17"
},
"gate_threshold": {
"min_tradable_symbols": 505,
"max_missing_or_zero_bar": 1,
"min_symbols_with_pre2021_bars_pct": 80.0,
"benchmark_min_rows": 1000,
"benchmark_must_begin_pre2021": true
},
"gate_pass": true
},
"data_quality": {
"window": {
"from": "2020-01-22",
"to": "2026-07-17"
},
"prod_symbols": 505,
"events": 12414,
"symbols_with_any_event": 504,
"symbols_with_ge8_announcements": 498,
"symbols_with_ge8_announcements_pct": 98.6,
"symbols_with_ge8_paired_announcements": 495,
"symbols_with_ge8_paired_announcements_pct": 98.0,
"events_with_actual_and_estimate": 12311,
"events_with_actual_and_estimate_pct": 99.2,
"duplicate_rows_in_table": 0,
"duplicate_rows_fetched": 0,
"restated_rows_fetched": 940,
"dedupe_policy": "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",
"events_per_symbol_year": {
"mean_active_span_rate": 4.08,
"expected": "approximately 4",
"far_off_rule": "active-span rate <2 or >6, plus zero-event symbols",
"far_off_count": 1,
"far_off_symbols": [
{
"symbol": "SPCX",
"events": 0,
"events_per_year": 0.0
}
]
},
"announcement_session": {
"recognised_bmo_amc_or_during": 11520,
"recognised_pct": 92.8,
"reliable": true,
"assessment": "usable"
},
"point_in_time_policy": "announce_date_plus_1_trading_day_for_all_events",
"sue_scaling": {
"primary": "eps_surprise_over_stdev_of_prior_8_surprises_min_4",
"fallback_trigger": "paired event coverage <50% or symbols with >=8 paired events <50%",
"fallback_needed": false,
"fallback_name": "not_used"
},
"backfill": {
"mode": "dolthub_public_bulk_clone",
"window": {
"from": "2020-01-22",
"to": "2026-07-17"
},
"coverage_amendment": {
"approved_by_user": true,
"reason": "FMP free tier blocks historical bulk earnings",
"original_start": "2016-01-04",
"amended_announcement_start": "2020-01-22"
},
"source": {
"repository": "https://www.dolthub.com/repositories/post-no-preference/earnings",
"commit": "9n0et3hpj9j7vue8f3qsldon3qa5sdjj",
"license": "CC-BY-SA-4.0",
"upstream_provider_documented": false
},
"bulk_windows_total": 1,
"bulk_windows_done": 1,
"bulk_requests_logged_total": 1,
"bulk_exports": 2,
"calendar": {
"raw_rows": 117482,
"universe_rows_in_window": 12342,
"deduped_rows_in_window": 12342,
"duplicate_rows": 0,
"restated_rows": 0
},
"eps_history": {
"raw_rows": 165050,
"universe_rows": 18515,
"deduped_rows": 18515,
"duplicate_rows": 0,
"restated_rows": 0,
"complete_actual_and_estimate": 18304
},
"pairing": {
"method": "minimum-cost monotonic alignment per symbol",
"allowed_announce_minus_period_end_days": [
-14,
90
],
"matched_calendar_events": 12271,
"unmatched_calendar_events": 71,
"unmatched_periods_in_pairing_window": 538,
"announce_minus_period_end_days": {
"min": -10,
"median": 30,
"max": 89
},
"pre_2020_eps_history_use": "trailing_surprise_stdev_only; never treated as an announcement or live signal event"
},
"duplicate_rows_logged_total": 0,
"restated_rows_logged_total": 940,
"conflicting_existing_rows": 940,
"conflicting_existing_fields": 1526,
"preserved_existing_fields": 2945,
"existing_enrichment_events_not_in_dolthub_calendar": 72,
"dedupe_policy": "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",
"events_in_window": 12414,
"events_with_actual_and_estimate": 12311,
"symbols_done": 506,
"symbols_universe": 506,
"symbols_with_dolthub_calendar": 504,
"symbols_without_dolthub_calendar": [
"RHM",
"SPCX"
],
"announce_date_range": {
"min": "2020-01-22",
"max": "2026-07-17"
},
"complete": true
}
},
"production_impact": "none",
"experiment": "2a",
"result": {
"verdict": "INFORMATIONAL",
"costs": {
"per_side": 0.001,
"r_is_net_of_round_trip_costs": true
},
"closed_trades": 574,
"q1_loss_concentration": {
"loss_definition": "realized_net_R <= -1.0",
"holding_period_definition": "announcement strictly after entry and before exit",
"losses_count": 266,
"losses_with_announcement_count": 23,
"losses_with_announcement_fraction": 0.0865,
"all_trades_with_announcement_count": 115,
"all_trades_with_announcement_fraction": 0.2003
},
"q2_entries_within_3_trading_days_before_announcement": {
"pre_earnings": {
"count": 27,
"mean_r": 0.4837,
"median_r": -1.0265,
"win_rate": 0.3333,
"p05_r": -1.1463,
"p95_r": 5.981,
"min_r": -1.2449,
"max_r": 8.8996
},
"all_other_entries": {
"count": 547,
"mean_r": 0.2734,
"median_r": -0.8316,
"win_rate": 0.3565,
"p05_r": -1.1228,
"p95_r": 4.5888,
"min_r": -6.0161,
"max_r": 19.98
},
"tail_deltas_pre_minus_other": {
"p05_r": -0.0235,
"p95_r": 1.3922
},
"directional_tail_condition_present": false,
"tail_read": "Registered directional tail condition is not present."
},
"q3_stop_exits_within_1_trading_day_after_announcement": {
"stops_after_earnings": {
"count": 26,
"mean_r": -0.6434,
"median_r": -0.9753,
"win_rate": 0.2308,
"p05_r": -2.4614,
"p95_r": 1.1142,
"min_r": -2.6413,
"max_r": 1.7012
},
"all_other_stops": {
"count": 433,
"mean_r": -0.5035,
"median_r": -1.0278,
"win_rate": 0.1963,
"p05_r": -1.1373,
"p95_r": 1.3591,
"min_r": -6.0161,
"max_r": 19.98
},
"all_other_exits": {
"count": 548,
"mean_r": 0.3273,
"median_r": -0.8361,
"win_rate": 0.3613,
"p05_r": -1.0644,
"p95_r": 4.7224,
"min_r": -6.0161,
"max_r": 19.98
}
},
"implementation": "REPORT_ONLY_NO_FILTER_ARM_NO_FILTER_CHANGE",
"analysis_window": {
"from": "2020-01-22",
"to": "2026-07-17",
"rule": "entry_on_or_after_start_and_exit_on_or_before_end",
"simulation_trades_total": 574,
"trades_excluded_outside_earnings_coverage": 0
},
"run_config": {
"universe_symbols": 505,
"fill_mode": "close",
"cost_per_side": 0.001,
"momentum_cutoff": 80.0,
"exit_policy": "atr_trail3",
"hold_days": 30,
"max_positions": 10,
"risk_per_trade": 0.01
},
"sim_summary": {
"start_date": "2020-01-22",
"end_date": "2026-07-13",
"trades": 574,
"sharpe": 1.03,
"cagr_pct": 22.9,
"max_drawdown_pct": 26.6,
"total_return_pct": 280.6
}
}
}
@@ -0,0 +1,58 @@
# Earnings Task 2a - gap diagnostic
### 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 |
@@ -0,0 +1,349 @@
{
"generated_at": "2026-07-20T07:02:10.934892+00:00",
"snapshot": "C:\\Workspace\\signal-platform\\backtest_snapshots\\research.sqlite",
"snapshot_depth": {
"manifest": {
"schema_version": 1,
"snapshot": "research.sqlite",
"snapshot_resolved": "C:\\Workspace\\signal-platform\\backtest_snapshots\\research.sqlite",
"complete": true,
"finished_at": "2026-07-19T14:22:15.706192+00:00",
"ticker_count": 4650,
"ohlcv_row_count": 5081073,
"rank_only_count": 4144,
"sources": {
"pool": "source_snapshot"
},
"history_days": 5000,
"min_bars": 1262,
"fetch_ok": 505,
"fetch_fail": 1,
"limit": null,
"extra": {
"prod_symbols_at_start": 506,
"pool_size": 506,
"to_fetch": 506,
"source_symbols_only": true,
"benchmark_spy_rows": 2649
},
"live_counts": {
"ticker_count": 4650,
"ohlcv_row_count": 5081073,
"rank_only_count": 4144
}
},
"requested_symbols": 506,
"tradable_symbols": 505,
"missing_symbols": [],
"zero_bar_symbols": [
"RHM"
],
"bar_count": {
"min": 24,
"median": 2649,
"max": 2649
},
"symbols_with_pre2021_bars": 491,
"symbols_with_pre2021_bars_pct": 97.2,
"shallow_symbols_lt_1000_bars": [
{
"symbol": "SPCX",
"first_bar": "2026-06-12",
"last_bar": "2026-07-17",
"bars": 24
},
{
"symbol": "Q",
"first_bar": "2025-11-03",
"last_bar": "2026-07-17",
"bars": 176
},
{
"symbol": "PSKY",
"first_bar": "2025-08-07",
"last_bar": "2026-07-17",
"bars": 237
},
{
"symbol": "SNDK",
"first_bar": "2025-02-13",
"last_bar": "2026-07-17",
"bars": 357
},
{
"symbol": "GEV",
"first_bar": "2024-04-02",
"last_bar": "2026-07-17",
"bars": 575
},
{
"symbol": "SOLV",
"first_bar": "2024-04-01",
"last_bar": "2026-07-17",
"bars": 576
},
{
"symbol": "VLTO",
"first_bar": "2023-10-02",
"last_bar": "2026-07-17",
"bars": 700
},
{
"symbol": "KVUE",
"first_bar": "2023-05-04",
"last_bar": "2026-07-17",
"bars": 803
},
{
"symbol": "GEHC",
"first_bar": "2022-12-15",
"last_bar": "2026-07-17",
"bars": 898
}
],
"price_window": {
"min": "2016-01-04",
"max": "2026-07-17"
},
"benchmark_spy": {
"rows": 2649,
"min": "2016-01-04",
"max": "2026-07-17"
},
"gate_threshold": {
"min_tradable_symbols": 505,
"max_missing_or_zero_bar": 1,
"min_symbols_with_pre2021_bars_pct": 80.0,
"benchmark_min_rows": 1000,
"benchmark_must_begin_pre2021": true
},
"gate_pass": true
},
"data_quality": {
"window": {
"from": "2020-01-22",
"to": "2026-07-17"
},
"prod_symbols": 505,
"events": 12414,
"symbols_with_any_event": 504,
"symbols_with_ge8_announcements": 498,
"symbols_with_ge8_announcements_pct": 98.6,
"symbols_with_ge8_paired_announcements": 495,
"symbols_with_ge8_paired_announcements_pct": 98.0,
"events_with_actual_and_estimate": 12311,
"events_with_actual_and_estimate_pct": 99.2,
"duplicate_rows_in_table": 0,
"duplicate_rows_fetched": 0,
"restated_rows_fetched": 940,
"dedupe_policy": "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",
"events_per_symbol_year": {
"mean_active_span_rate": 4.08,
"expected": "approximately 4",
"far_off_rule": "active-span rate <2 or >6, plus zero-event symbols",
"far_off_count": 1,
"far_off_symbols": [
{
"symbol": "SPCX",
"events": 0,
"events_per_year": 0.0
}
]
},
"announcement_session": {
"recognised_bmo_amc_or_during": 11520,
"recognised_pct": 92.8,
"reliable": true,
"assessment": "usable"
},
"point_in_time_policy": "announce_date_plus_1_trading_day_for_all_events",
"sue_scaling": {
"primary": "eps_surprise_over_stdev_of_prior_8_surprises_min_4",
"fallback_trigger": "paired event coverage <50% or symbols with >=8 paired events <50%",
"fallback_needed": false,
"fallback_name": "not_used"
},
"backfill": {
"mode": "dolthub_public_bulk_clone",
"window": {
"from": "2020-01-22",
"to": "2026-07-17"
},
"coverage_amendment": {
"approved_by_user": true,
"reason": "FMP free tier blocks historical bulk earnings",
"original_start": "2016-01-04",
"amended_announcement_start": "2020-01-22"
},
"source": {
"repository": "https://www.dolthub.com/repositories/post-no-preference/earnings",
"commit": "9n0et3hpj9j7vue8f3qsldon3qa5sdjj",
"license": "CC-BY-SA-4.0",
"upstream_provider_documented": false
},
"bulk_windows_total": 1,
"bulk_windows_done": 1,
"bulk_requests_logged_total": 1,
"bulk_exports": 2,
"calendar": {
"raw_rows": 117482,
"universe_rows_in_window": 12342,
"deduped_rows_in_window": 12342,
"duplicate_rows": 0,
"restated_rows": 0
},
"eps_history": {
"raw_rows": 165050,
"universe_rows": 18515,
"deduped_rows": 18515,
"duplicate_rows": 0,
"restated_rows": 0,
"complete_actual_and_estimate": 18304
},
"pairing": {
"method": "minimum-cost monotonic alignment per symbol",
"allowed_announce_minus_period_end_days": [
-14,
90
],
"matched_calendar_events": 12271,
"unmatched_calendar_events": 71,
"unmatched_periods_in_pairing_window": 538,
"announce_minus_period_end_days": {
"min": -10,
"median": 30,
"max": 89
},
"pre_2020_eps_history_use": "trailing_surprise_stdev_only; never treated as an announcement or live signal event"
},
"duplicate_rows_logged_total": 0,
"restated_rows_logged_total": 940,
"conflicting_existing_rows": 940,
"conflicting_existing_fields": 1526,
"preserved_existing_fields": 2945,
"existing_enrichment_events_not_in_dolthub_calendar": 72,
"dedupe_policy": "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",
"events_in_window": 12414,
"events_with_actual_and_estimate": 12311,
"symbols_done": 506,
"symbols_universe": 506,
"symbols_with_dolthub_calendar": 504,
"symbols_without_dolthub_calendar": [
"RHM",
"SPCX"
],
"announce_date_range": {
"min": "2020-01-22",
"max": "2026-07-17"
},
"complete": true
}
},
"production_impact": "none",
"experiment": "2b",
"result": {
"verdict": "FAIL",
"verdict_detail": "SUE DEAD for this stack",
"grade_rule": {
"mean_ic_ge_0_03_positive": false,
"reliable_ge_12_windows": true,
"positive_sign_pre_and_post_2021": true,
"pass": false
},
"sue_unconditional": {
"signal": "sue_latest",
"weeks": 56,
"avg_cross_section": 451.4,
"mean_ic": 0.0151,
"ic_t_stat": 1.29,
"ic_positive_pct": 51.8,
"mean_quintile_spread": 0.0041,
"reliable": true
},
"era_split": {
"pre_2021": {
"signal": "sue_latest",
"weeks": 9,
"avg_cross_section": 398.3,
"mean_ic": 0.0286,
"ic_t_stat": 0.7,
"ic_positive_pct": 55.6,
"mean_quintile_spread": 0.0084,
"reliable": false
},
"post_2021": {
"signal": "sue_latest",
"weeks": 48,
"avg_cross_section": 461.9,
"mean_ic": 0.0172,
"ic_t_stat": 1.34,
"ic_positive_pct": 64.6,
"mean_quintile_spread": 0.0038,
"reliable": true
}
},
"signal_eval_identical_cross_sections": {
"sue_latest": {
"signal": "sue_latest",
"weeks": 56,
"avg_cross_section": 450.9,
"mean_ic": 0.0148,
"ic_t_stat": 1.27,
"ic_positive_pct": 51.8,
"mean_quintile_spread": 0.004,
"reliable": true
},
"mom_12_1": {
"signal": "mom_12_1",
"weeks": 56,
"avg_cross_section": 450.9,
"mean_ic": 0.0195,
"ic_t_stat": 0.74,
"ic_positive_pct": 58.9,
"mean_quintile_spread": 0.0104,
"reliable": true
},
"mom_12_1_resid": {
"signal": "mom_12_1_resid",
"weeks": 56,
"avg_cross_section": 450.9,
"mean_ic": 0.0262,
"ic_t_stat": 1.07,
"ic_positive_pct": 55.4,
"mean_quintile_spread": 0.0114,
"reliable": true
}
},
"identical_cross_section_definition": "same week-symbol-forward-return cells where sue_latest, mom_12_1, and mom_12_1_resid are all non-null",
"momentum_conditional_top_quintile": {
"mean_ic": 0.0213,
"ic_t_stat": 1.3,
"weeks": 56,
"avg_cross_section": 89.8,
"population": "top_mom_12_1_quintile_only"
},
"coverage": {
"symbols_with_live_sue": 501,
"avg_weekly_live_n_all_weeks": 453.1,
"avg_cross_section_n_scored_nonoverlap": 451.4,
"thin_cross_section_lt_100": false,
"warning": null
},
"scaling": {
"method": "eps_surprise_over_stdev_of_prior_8_surprises_min_4",
"fallback": "not_used",
"counts": {
"standard_scaled_events": 12149,
"events_scaled_from_period_history": 12149,
"price_fallback_events": 0,
"dropped_insufficient_trailing_history": 95,
"dropped_missing_period_alignment": 67,
"dropped_zero_stdev": 0
},
"pre_coverage_history_policy": "period-end EPS surprises may scale later events but are never treated as live signals without an announcement date",
"availability": "announce_date_plus_1_trading_day",
"carry_trading_days": 63
},
"universe_symbols": 505
}
}
@@ -0,0 +1,62 @@
# Earnings Task 2b - SUE / PEAD
### 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 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.
+72 -12
View File
@@ -1,15 +1,75 @@
{
"mode": "per_symbol",
"fmp_requests": 25,
"events_written_this_run": 2541,
"total_events": 5612,
"symbols_done": 48,
"symbols_universe": 506,
"announce_date_range": {
"min": "1985-08-31",
"max": "2026-07-16"
"mode": "dolthub_public_bulk_clone",
"window": {
"from": "2020-01-22",
"to": "2026-07-17"
},
"events_with_actual_and_estimate": 5018,
"budget": 25,
"complete": false
"coverage_amendment": {
"approved_by_user": true,
"reason": "FMP free tier blocks historical bulk earnings",
"original_start": "2016-01-04",
"amended_announcement_start": "2020-01-22"
},
"source": {
"repository": "https://www.dolthub.com/repositories/post-no-preference/earnings",
"commit": "9n0et3hpj9j7vue8f3qsldon3qa5sdjj",
"license": "CC-BY-SA-4.0",
"upstream_provider_documented": false
},
"bulk_windows_total": 1,
"bulk_windows_done": 1,
"bulk_requests_logged_total": 1,
"bulk_exports": 2,
"calendar": {
"raw_rows": 117482,
"universe_rows_in_window": 12342,
"deduped_rows_in_window": 12342,
"duplicate_rows": 0,
"restated_rows": 0
},
"eps_history": {
"raw_rows": 165050,
"universe_rows": 18515,
"deduped_rows": 18515,
"duplicate_rows": 0,
"restated_rows": 0,
"complete_actual_and_estimate": 18304
},
"pairing": {
"method": "minimum-cost monotonic alignment per symbol",
"allowed_announce_minus_period_end_days": [
-14,
90
],
"matched_calendar_events": 12271,
"unmatched_calendar_events": 71,
"unmatched_periods_in_pairing_window": 538,
"announce_minus_period_end_days": {
"min": -10,
"median": 30,
"max": 89
},
"pre_2020_eps_history_use": "trailing_surprise_stdev_only; never treated as an announcement or live signal event"
},
"duplicate_rows_logged_total": 0,
"restated_rows_logged_total": 940,
"conflicting_existing_rows": 940,
"conflicting_existing_fields": 1526,
"preserved_existing_fields": 2945,
"existing_enrichment_events_not_in_dolthub_calendar": 72,
"dedupe_policy": "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",
"events_in_window": 12414,
"events_with_actual_and_estimate": 12311,
"symbols_done": 506,
"symbols_universe": 506,
"symbols_with_dolthub_calendar": 504,
"symbols_without_dolthub_calendar": [
"RHM",
"SPCX"
],
"announce_date_range": {
"min": "2020-01-22",
"max": "2026-07-17"
},
"complete": true
}
@@ -1,331 +0,0 @@
{
"generated_at": "2026-07-19T09:31:29.078611",
"data_provenance": {
"snapshot": "C:\\Workspace\\signal-platform\\backtest_snapshots\\prod.sqlite",
"n_earnings_events": 5612,
"backfill_meta": {
"done": 48,
"universe_tickers": 506
},
"announce_range": {
"min": "1985-08-31",
"max": "2026-07-16"
},
"with_actual_and_estimate": 5018
},
"experiment_2a": {
"sim_summary": {
"sharpe": 2.09,
"sharpe_se": 0.497,
"cagr_pct": 51.6,
"max_drawdown_pct": 21.4,
"trades": 322,
"total_return_pct": 424.6
},
"n_trades_parsed": 322,
"q1_losses_worse_than_minus_1r": {
"n_losses_lt_minus_1r": 28,
"n_with_earnings_in_hold": 1,
"fraction_with_earnings": 0.0357,
"all_trades_with_earnings_in_hold": 14,
"fraction_all_trades_with_earnings": 0.0435
},
"q2_entry_within_3d_before_announce": {
"pre_earn_entries": {
"n": 4,
"mean": 1.9379,
"win_rate": 0.5,
"p05": -1.2428,
"p25": -0.8833,
"p50": 1.1209,
"p75": 3.942,
"p95": 6.2623,
"min": -1.3327,
"max": 6.8424
},
"other_entries": {
"n": 318,
"mean": 0.6965,
"win_rate": 0.3711,
"p05": -1.1052,
"p25": -1.0,
"p50": -0.8259,
"p75": 2.1053,
"p95": 6.077,
"min": -3.2587,
"max": 12.8654
},
"all_entries": {
"n": 322,
"mean": 0.7119,
"win_rate": 0.3727,
"p05": -1.1209,
"p25": -1.0,
"p50": -0.8251,
"p75": 2.1595,
"p95": 6.2246,
"min": -3.2587,
"max": 12.8654
},
"tail_trim_note": "Compare p95/max and mean of pre_earn vs other. Rising win_rate with falling mean/p95 = right-tail trim red flag."
},
"note": "REPORT-ONLY \u2014 no filter shipped."
},
"experiment_2b": {
"signal_eval_side_by_side": {
"mom_12_1": {
"signal": "mom_12_1",
"weeks": 35,
"avg_cross_section": 497.7,
"mean_ic": 0.0531,
"ic_t_stat": 1.61,
"ic_positive_pct": 65.7,
"mean_quintile_spread": 0.0206,
"reliable": true
},
"mom_12_1_resid": {
"signal": "mom_12_1_resid",
"weeks": 35,
"avg_cross_section": 497.7,
"mean_ic": 0.0552,
"ic_t_stat": 1.98,
"ic_positive_pct": 60.0,
"mean_quintile_spread": 0.0207,
"reliable": true
},
"mom_12_1_sector_resid": {
"signal": "mom_12_1_sector_resid",
"weeks": 35,
"avg_cross_section": 497.7,
"mean_ic": 0.0578,
"ic_t_stat": 2.34,
"ic_positive_pct": 65.7,
"mean_quintile_spread": 0.0245,
"reliable": true
},
"mom_12_1_sector_demeaned": {
"signal": "mom_12_1_sector_demeaned",
"weeks": 35,
"avg_cross_section": 496.7,
"mean_ic": 0.034,
"ic_t_stat": 1.32,
"ic_positive_pct": 62.9,
"mean_quintile_spread": 0.0154,
"reliable": true
},
"sue_latest": {
"signal": "sue_latest",
"weeks": 44,
"avg_cross_section": 47.4,
"mean_ic": 0.0172,
"ic_t_stat": 0.6,
"ic_positive_pct": 47.7,
"mean_quintile_spread": 0.0064,
"reliable": true
},
"fip_id": {
"signal": "fip_id",
"weeks": 35,
"avg_cross_section": 497.7,
"mean_ic": -0.045,
"ic_t_stat": -2.91,
"ic_positive_pct": 25.7,
"mean_quintile_spread": -0.0168,
"reliable": true
}
},
"signal_eval_identical_sue_subset": {
"mom_12_1": {
"signal": "mom_12_1",
"weeks": 35,
"avg_cross_section": 47.3,
"mean_ic": -0.0174,
"ic_t_stat": -0.42,
"ic_positive_pct": 45.7,
"mean_quintile_spread": 0.0077,
"reliable": true
},
"mom_12_1_resid": {
"signal": "mom_12_1_resid",
"weeks": 35,
"avg_cross_section": 47.3,
"mean_ic": -0.0104,
"ic_t_stat": -0.27,
"ic_positive_pct": 51.4,
"mean_quintile_spread": 0.0075,
"reliable": true
},
"sue_latest": {
"signal": "sue_latest",
"weeks": 44,
"avg_cross_section": 47.4,
"mean_ic": 0.0172,
"ic_t_stat": 0.6,
"ic_positive_pct": 47.7,
"mean_quintile_spread": 0.0064,
"reliable": true
}
},
"identical_subset_note": "Mom baselines re-scored only on (week, symbol) cells where SUE exists. Use this table when backfill is incomplete \u2014 full-universe mom N is not comparable.",
"full_signal_eval": [
{
"signal": "vol_6m",
"weeks": 39,
"avg_cross_section": 498.2,
"mean_ic": 0.0609,
"ic_t_stat": 1.48,
"ic_positive_pct": 64.1,
"mean_quintile_spread": 0.0337,
"reliable": true
},
{
"signal": "mom_12_1_sector_resid",
"weeks": 35,
"avg_cross_section": 497.7,
"mean_ic": 0.0578,
"ic_t_stat": 2.34,
"ic_positive_pct": 65.7,
"mean_quintile_spread": 0.0245,
"reliable": true
},
{
"signal": "mom_12_1_resid",
"weeks": 35,
"avg_cross_section": 497.7,
"mean_ic": 0.0552,
"ic_t_stat": 1.98,
"ic_positive_pct": 60.0,
"mean_quintile_spread": 0.0207,
"reliable": true
},
{
"signal": "mom_12_1",
"weeks": 35,
"avg_cross_section": 497.7,
"mean_ic": 0.0531,
"ic_t_stat": 1.61,
"ic_positive_pct": 65.7,
"mean_quintile_spread": 0.0206,
"reliable": true
},
{
"signal": "mom_12_1_sector_demeaned",
"weeks": 35,
"avg_cross_section": 496.7,
"mean_ic": 0.034,
"ic_t_stat": 1.32,
"ic_positive_pct": 62.9,
"mean_quintile_spread": 0.0154,
"reliable": true
},
{
"signal": "sue_latest",
"weeks": 44,
"avg_cross_section": 47.4,
"mean_ic": 0.0172,
"ic_t_stat": 0.6,
"ic_positive_pct": 47.7,
"mean_quintile_spread": 0.0064,
"reliable": true
},
{
"signal": "trend_200",
"weeks": 37,
"avg_cross_section": 497.9,
"mean_ic": 0.0161,
"ic_t_stat": 0.44,
"ic_positive_pct": 59.5,
"mean_quintile_spread": 0.006,
"reliable": true
},
{
"signal": "reversal_1m",
"weeks": 43,
"avg_cross_section": 498.7,
"mean_ic": 0.0059,
"ic_t_stat": 0.22,
"ic_positive_pct": 53.5,
"mean_quintile_spread": 0.0053,
"reliable": true
},
{
"signal": "mom_6_1",
"weeks": 39,
"avg_cross_section": 498.2,
"mean_ic": 0.0051,
"ic_t_stat": 0.21,
"ic_positive_pct": 56.4,
"mean_quintile_spread": 0.0087,
"reliable": true
},
{
"signal": "mom_3_1",
"weeks": 42,
"avg_cross_section": 498.5,
"mean_ic": -0.0064,
"ic_t_stat": -0.25,
"ic_positive_pct": 50.0,
"mean_quintile_spread": 0.0046,
"reliable": true
},
{
"signal": "high_52w",
"weeks": 35,
"avg_cross_section": 497.7,
"mean_ic": -0.0086,
"ic_t_stat": -0.26,
"ic_positive_pct": 54.3,
"mean_quintile_spread": -0.0088,
"reliable": true
},
{
"signal": "fip_id",
"weeks": 35,
"avg_cross_section": 497.7,
"mean_ic": -0.045,
"ic_t_stat": -2.91,
"ic_positive_pct": 25.7,
"mean_quintile_spread": -0.0168,
"reliable": true
}
],
"sue_grade": {
"green": false,
"checks": {
"mean_ic": 0.0172,
"sign_positive": true,
"abs_ge_0_03": false,
"reliable": true,
"ic_t_stat": 0.6,
"weeks": 44
},
"reason": "iron rule not met",
"row": {
"signal": "sue_latest",
"weeks": 44,
"avg_cross_section": 47.4,
"mean_ic": 0.0172,
"ic_t_stat": 0.6,
"ic_positive_pct": 47.7,
"mean_quintile_spread": 0.0064,
"reliable": true
}
},
"momentum_conditional_sue": {
"mean_ic": -0.0065,
"ic_t_stat": -0.1,
"weeks": 35,
"note": "IC of sue_latest within top mom_12_1 quintile (non-overlapping weeks)"
},
"sue_coverage": {
"symbols_with_sue": 48,
"avg_weeks_with_sue": 47.1,
"weeks_with_min_cross_section": 256
}
},
"verdict": "PARK",
"verdict_detail": "SUE IC=0.0172 below iron bar or unreliable; keep data, no wire.",
"human_next": "- No SUE book change.\n- Read 2a tails before considering any earnings-avoid filter.",
"report_path": "reports/earnings-gap-sue-20260719-093129.json",
"fmp_note": "Bulk earnings-calendar is paid (402 on free tier). Backfill used per-symbol /stable/earnings; see earnings-backfill-status.json."
}
-202
View File
@@ -1,202 +0,0 @@
# Earnings gap diagnostic + SUE / PEAD (Tier-1 alpha research)
**Status:** **PARK** (incomplete earnings coverage; SUE fails iron rule on available sample).
**Branch:** `research/earnings-gap-and-sue`
**Production impact:** none. Local research only. **No filters shipped from 2a.**
**Artifacts:** `reports/earnings-gap-sue-20260719-093129.json` (+ companion `.md`)
---
## Pre-registration (locked before first research run)
### Data
- Historical earnings calendar for the production universe over the full snapshot
window (and deeper if the feed provides it).
- Preferred source: FMP **date-range earnings-calendar** (bulk). If unavailable on
free tier, fall back to per-symbol `/stable/earnings` with request accounting.
- Store in a real local table `earnings_events` (symbol + announce_date key).
- Point-in-time: a surprise is usable only from **announce date + 1 trading day**
onward.
### Experiment 2a — earnings-gap risk (defense, report-only)
Join simulated production-config trades (`fill_mode=close`) with earnings dates.
**Pre-registered questions:**
1. What fraction of losses worse than **1R** occur with an earnings announcement
**between entry and exit** (inclusive of the holding window)?
2. What is the mean R of entries taken within **3 trading days BEFORE** an
announcement vs all other entries — report **both tails** of the R
distribution (rule 4: any earnings-avoid entry filter is presumed guilty of
right-tail trimming until the win distribution shows otherwise)?
**Output:** distributions and counts only.
**No filter is shipped.** If numbers argue for a filter → report and stop.
### Experiment 2b — SUE / PEAD (offense)
Signal `sue_latest`:
\[
\text{SUE} = \frac{\text{actual} - \text{estimate}}{\sigma(\text{trailing 8 surprises})}
\]
Fallback if estimate history is thin: scale surprise by price.
Carry forward from announce+1 for **63 trading days**, else NaN (name drops out
of that cross-section).
**Iron rule (IC harness):** mean weekly Spearman IC on non-overlapping weeks;
\|mean IC\| ≥ ~0.03, **positive** sign (drift), `reliable: true` (≥12 windows).
Always side-by-side with `mom_12_1` and `mom_12_1_resid` on **identical**
cross-sections.
Also report **momentum-conditional** IC (within top momentum quintile).
**If it passes iron rule:** STOP and report. Book-integration design is a
separate human-approved step — do not wire.
### Verdict labels
| label | meaning |
|---|---|
| **PROMOTE** | (2b only) iron rule cleared → human designs tilt/gate |
| **PARK** | Interesting but incomplete / weak |
| **DEAD** | No edge / diagnostic argues against action |
| **REPORT-ONLY** | (2a) always — never auto-filter |
---
## Data provenance
| item | result |
|---|---|
| Snapshot | `backtest_snapshots/prod.sqlite` (506 names) |
| FMP bulk `earnings-calendar` | **402 Premium** — not available on free tier |
| FMP per-symbol `/stable/earnings` | used; hit daily rate limit ~225 reqs |
| Alpha Vantage `EARNINGS` | used for +24 symbols (announce = `reportedDate`) |
| Symbols with events | **48 / 506 (9.5%)** |
| Total events | 5,612 (5,018 with actual+estimate) |
| Announce range | 1985-08-31 → 2026-07-16 |
| FMP requests (first day) | 260 FMP + 25 AV (see `reports/earnings-backfill-status.json`) |
**Incomplete backfill is first-class.** 2a under-detects earnings overlaps; 2b SUE
cross-section averages **~47 names**, not ~500. Resume:
```bash
# Day N (FMP free ~250/day; AV free ~25/day — prefer FMP after reset)
python scripts/backfill_earnings_events.py \
--snapshot backtest_snapshots/prod.sqlite \
--provider fmp --force-symbol --limit 250 --sleep 0.4
# When done==506:
python scripts/run_earnings_research.py \
--snapshot backtest_snapshots/prod.sqlite \
--workers 6 --allow-spawn
```
---
## Results
Generated: `2026-07-19T09:31:29`
### 2a — Earnings-gap risk (report-only)
Production book sim: Sharpe 2.09 (SE 0.497), CAGR 51.6%, max DD 21.4%, **322 trades**,
`fill_mode=close`.
#### Q1 — Losses worse than 1R with earnings in hold
| metric | value |
|---|---:|
| n losses &lt; 1R | 28 |
| of which earnings in hold | **1** |
| fraction | **3.6%** |
| all trades with earnings in hold | 14 / 322 (4.4%) |
**Read:** On incomplete earnings labels this is a **lower bound** on earnings
overlap, not a clean “earnings rarely hurt.” Do **not** conclude earnings risk is
immaterial until coverage ≥ ~95% of the books names.
#### Q2 — Entry within 3 trading days before announce (both tails)
| cohort | n | mean R | win rate | p05 | p50 | p95 | max |
|---|---:|---:|---:|---:|---:|---:|---:|
| pre-earn (≤3d before) | **4** | 1.94 | 50% | 1.24 | 1.12 | 6.26 | 6.84 |
| other | 318 | 0.70 | 37% | 1.11 | 0.83 | 6.08 | **12.87** |
| all | 322 | 0.71 | 37% | 1.12 | 0.83 | 6.22 | 12.87 |
**Tail-trim presumption:** n=4 is not a sample. Point estimate does **not** show
right-tail destruction of pre-earn entries (p95 similar; max actually higher in
“other”). **No earnings-avoid filter is supported.** Re-run after full backfill.
---
### 2b — SUE / PEAD IC
#### Full-universe harness (mom on ~500; SUE only where labeled)
| signal | mean_ic | ic_t_stat | weeks | avg_N | reliable |
|---|---:|---:|---:|---:|---|
| mom_12_1_sector_resid | 0.0578 | 2.34 | 35 | 497.7 | true |
| mom_12_1_resid | 0.0552 | 1.98 | 35 | 497.7 | true |
| mom_12_1 | 0.0531 | 1.61 | 35 | 497.7 | true |
| **sue_latest** | **0.0172** | **0.6** | 44 | **47.4** | true |
| fip_id | 0.045 | 2.91 | 35 | 497.7 | true |
#### Identical SUE subset (fair side-by-side — use this while coverage is thin)
| signal | mean_ic | ic_t_stat | weeks | avg_N |
|---|---:|---:|---:|---:|
| sue_latest | 0.0172 | 0.6 | 44 | 47.4 |
| mom_12_1 | 0.0174 | 0.42 | 35 | 47.3 |
| mom_12_1_resid | 0.0104 | 0.27 | 35 | 47.3 |
On the thin labeled subset, momentum itself is noise — so the subset is not yet
a meaningful PEAD test.
#### Momentum-conditional SUE (top mom quintile)
| metric | value |
|---|---:|
| mean IC | **0.0065** |
| t | 0.1 |
| weeks | 35 |
Wrong sign vs “ride positive surprises inside the momentum gate.”
**Iron rule:** fail (\|IC\| 0.017 &lt; 0.03; t 0.6). **No promote.**
---
## Verdict
| piece | verdict |
|---|---|
| **2a earnings-gap** | **REPORT-ONLY** — no filter. Coverage too thin for risk claims; tails do not argue for an avoid-filter on n=4. |
| **2b SUE** | **PARK** (effectively not green). Mild positive IC on ~48 names; fails iron bar; mom-conditional flat/negative. Re-score after full backfill before DEAD. |
| **Production** | **no change** |
---
## What a human must decide next
1. Resume multi-day earnings backfill to **506/506**, then re-run
`run_earnings_research.py` (heavy — MacBook OK).
2. Do **not** ship an earnings-avoid entry filter from 2a.
3. Do **not** wire SUE until a full-coverage IC clears the iron rule (and
preferably mom-conditional &gt; 0).
4. Do not merge into main strategy docs without review.
---
## Implementation notes
| piece | role |
|---|---|
| `scripts/backfill_earnings_events.py` | bulk attempt → FMP/AV per-symbol; `earnings_events` + meta on snapshot |
| `scripts/run_earnings_research.py` | 2a trade join + 2b SUE IC / mom-conditional |
| Snapshot table `earnings_events` | real table (not SystemSetting JSON) |