US Earnings Surprises — Actual Vs Estimate, 10y (2016–2025)
Ten years of US earnings surprises — actual EPS and revenue versus consensus estimate at the time — for every USD-reporting US-listed issuer FMP indexes. 313,626 reported earnings events as a single gzipped CSV. Computed surprise columns (eps_surprise, eps_surprise_pct, revenue_surprise, revenue_surprise_pct) are derived in the build for convenience. Read with pandas.read_csv(path, compression='gzip', parse_dates=['report_date', 'last_updated']) or duckdb.read_csv('earnings_2016_2025.csv.gz'). Foundational dataset for: post-earnings-announcement-drift (PEAD) studies, beat / miss base-rate research, earnings-quality scoring, surprise-magnitude factor construction, and tracking which sectors / size buckets systematically beat or disappoint.
Use Cases
- Post-earnings announcement drift (PEAD) backtests
- Beat / miss base-rate analysis by sector and market-cap bucket
- Earnings-momentum factor construction
- Sell-side estimate accuracy tracking over time
- Quality control on consensus expectations vs realized fundamentals
Methodology
Universe: every USD-reporting US-listed issuer (no foreign exchange suffix) from FMP's financial-statement-symbol-list (~17,500). For each, fetched up to 80 reported earnings events from FMP's /earnings?symbol= endpoint. Filtered to events with non-null epsActual and report_date >= 2016-01-01. Surprise columns derived in the build: eps_surprise = eps_actual - eps_estimated, eps_surprise_pct = eps_surprise / |eps_estimated| * 100 (and same for revenue).
Update Schedule
Static snapshot. Reflects what FMP had indexed as of the build date.
Attribution
Source: SEC EDGAR earnings + sell-side consensus estimates via Financial Modeling Prep.
Schema
| name | type |
|---|---|
| symbol | string |
| report_date | date |
| eps_actual | number |
| eps_estimated | number |
| eps_surprise | number |
| eps_surprise_pct | number |
| revenue_actual | number |
| revenue_estimated | number |
| revenue_surprise | number |
| revenue_surprise_pct | number |
| last_updated | date |
Sample Data
| symbol | eps_actual | report_date | eps_surprise | last_updated | eps_estimated | revenue_actual | eps_surprise_pct | revenue_surprise | revenue_estimated | revenue_surprise_pct |
|---|---|---|---|---|---|---|---|---|---|---|
| RLJE | -3.14812 | 2016-03-31 | -1.1207 | 2023-04-03 | -2.02741 | 22806000 | -55.28 | -5179757 | 27985757 | -18.51 |
| RLJE | -0.03768 | 2016-06-30 | -0.0040 | 2023-04-03 | -0.03365 | 15790000 | -11.98 | 55703 | 15734297 | 0.35 |
| RLJE | -0.85345 | 2016-09-30 | -0.3535 | 2023-04-03 | -0.49991 | 18351000 | -70.72 | 449439 | 17901561 | 2.51 |
Get this via API
# 1. Add dAgentBase once, in any MCP client. No install, no vendor keys.
# Claude.ai / Claude Desktop: Settings -> Connectors -> Add custom connector
# Cursor / Claude Code / others: mcp.json
{
"mcpServers": {
"dagentbase": {
"url": "https://dagentbase.com/api/mcp",
"headers": { "Authorization": "Bearer dm_live_YOUR_KEY" }
}
}
}
# 2. Then ask your agent, in plain language:
# "Preview 'US Earnings Surprises — Actual vs Estimate, 10y (2016–2025)' and, if it fits, claim it and download the files."
# Tools it will use: search_listings -> preview_listing -> purchase_listing -> get_download_urls
# 1. Add dAgentBase once, in any MCP client. No install, no vendor keys.
# Claude.ai / Claude Desktop: Settings -> Connectors -> Add custom connector
# Cursor / Claude Code / others: mcp.json
{
"mcpServers": {
"dagentbase": {
"url": "https://dagentbase.com/api/mcp",
"headers": { "Authorization": "Bearer dm_live_YOUR_KEY" }
}
}
}
# 2. Then ask your agent, in plain language:
# "Preview 'US Earnings Surprises — Actual vs Estimate, 10y (2016–2025)' and, if it fits, claim it and download the files."
# Tools it will use: search_listings -> preview_listing -> purchase_listing -> get_download_urlsone time · open license
Details
Available formats