Home / Libraries / ML4T Data / Docs
ML4T Data
ML4T Data Documentation
Unified market data acquisition from 19+ providers
Skip to content

Fundamental Data Sources

This page compares sources of equity fundamentals: financial statements, as-reported versus restated values, and analyst estimates. It covers the free SEC routes, retail APIs, and the institutional and academic databases, and says which ones ml4t-data can fetch.

Verified 2026-09

Vendor coverage, access terms, endpoint names and ownership change often. Every entry below was checked against the vendor's own documentation in September 2026. Confirm the current terms before you build a dataset on any of them.


Choosing a Source

Point-in-time first

A backtest must only see the value that was public at the decision date. Companies restate earlier periods, and vendors often overwrite the original figure with the restated one. A dataset that stores only the latest value leaks future information into every historical signal built from it, and the leak is invisible in the data itself.

A source is point-in-time when each value carries the date it became public and superseded versions are kept. The tables below use three grades:

Grade Meaning
Yes Each value carries its filing or release date, and earlier versions of a restated period remain available. The field that makes it so is named.
Partial A date is present but has a caveat, for example the date of the latest filing that included the period rather than the first, or point-in-time only in a paid dataset.
No Only the current (possibly restated) value, with no date of public availability.

Two further points apply even with a point-in-time source:

  • A filing date is not a trading date. Filings arrive during or after the session; use the acceptance timestamp where available and apply the value from the next session.
  • The SEC XBRL Frames API returns one value per company and period, the last one filed. It looks convenient for cross-sections and is not point-in-time.

Survivorship

The universe must include companies that were later delisted, acquired or went bankrupt. A source that covers only today's listed companies biases every cross-sectional result toward survivors. Sharadar, Zacks, Compustat and CRSP state delisted coverage explicitly; for the others, check before relying on it.

Identifier mapping

Tickers change and are reused. Fundamentals are keyed by the issuer (SEC CIK, Compustat GVKEY, vendor IDs); prices are usually keyed by the security (ticker, CRSP PERMNO, FIGI). Joining the two needs a dated mapping, and building one is usually more work than fetching either dataset.

In the book

  • Chapter 2, "A due diligence framework for data sourcing" (section 2.3): point-in-time correctness, survivorship bias, identifier integrity, vendor tiers, and a vendor due diligence checklist.
  • Chapter 4, "The point-in-time pipeline" (section 4.1): building a bitemporal fundamentals dataset from SEC EDGAR, and why the Frames API is not safe for backtests. "Entity resolution and mapping" (section 4.2) covers the identifier problem.

Free SEC Routes

The SEC publishes every XBRL financial statement that US registrants file. Detailed XBRL tagging phased in from 2009 (large filers first) to 2011. Access needs no key; requests must send a User-Agent header that identifies the caller, and the SEC's fair-access policy limits request rates.

Source What it returns Point-in-time Estimates ml4t-data
EDGAR companyfacts / companyconcept APIs Every XBRL fact for one company (all concepts, or one concept), from every filing that reported it Yes: each fact carries filed, accn (accession number) and form No No
EDGAR submissions API Filing history per company: forms, filing and acceptance dates, former names and tickers Filing metadata, used to date the facts above No No
EDGAR frames API One value per company for a concept and calendar period No: the last-filed value for each period No No
Financial Statement Data Sets and Financial Statement and Notes Data Sets Quarterly bulk files from 2009: submissions (sub), numeric values (num), tags, and for the Notes sets the footnote detail Yes: values are as filed; sub holds filed and accepted per submission No No

companyfacts.zip and submissions.zip provide the same content as the APIs in one nightly bulk download. Python wrappers such as edgartools parse filings and statements on top of these endpoints.


Retail and Developer APIs

Source Coverage Point-in-time Estimates Access ml4t-data
Sharadar Core US Fundamentals (SF1) About 18,000 active and delisted US companies, from 1998 Yes: as-reported dimensions (ARQ, ARY, ART) are indexed by datekey, the SEC filing date. The most-recent dimensions (MRQ, MRY, MRT) are restated. No Paid. Sold direct at sharadar.com since July 2026; institutional access remains through Nasdaq Data Link. No
SimFin About 5,000 US stocks, from 2003 Partial: rows carry Publish Date and Restated Date, but the standard datasets hold the latest restated value. As-reported bulk datasets are on paid tiers. No Free tier (5 years of fundamentals, delayed bulk download); paid tiers extend history. No
Financial Modeling Prep Global, 70,000+ securities; up to 30+ years for large caps Partial: statements carry filingDate and acceptedDate; separate as-reported endpoints return the filed values. Confirm how a restatement is versioned. Yes Free tier (US only); paid tiers for global coverage and full history. No
EODHD 70+ exchanges; major US companies from 1985, non-US from 2000 Partial: each yearly and quarterly entry has filing_date; the documentation does not say whether values are restated. Yes: current consensus and revision trend Paid; fundamentals are not in the free plan. Yes: EODHDProvider.fetch_financials(), fetch_company_metrics()
Intrinio US SEC filers; annual from 2007, quarterly from 2009 Yes: each fundamental has filing_date, and is_latest marks whether a later filing superseded it. Both reported and standardized feeds. Yes: Zacks estimates, sold separately Paid No
Zacks US and Canada; 19,500+ companies including 9,000+ delisted on Nasdaq Data Link (ZFA); Zacks Data history from 1979 Yes in Zacks Data's point-in-time history; check the specific Nasdaq Data Link table before assuming it Yes: Zacks consensus is the core product Paid: Nasdaq Data Link, or Zacks Data for institutions No
Finnhub Global standardized statements; as-reported statements from SEC filings Partial: /stock/financials-reported returns each filing with filedDate and acceptedDate. The standardized /stock/financials endpoint has no filing date. Yes (premium) Free tier includes as-reported statements; standardized statements and estimates are premium. Yes: FinnhubProvider.fetch_financials() (standardized endpoint), fetch_company_metrics()
Massive (formerly Polygon.io) About 6,700 US companies, from 2009 Partial: filing_date is the date of the most recent SEC filing that included the period, not the original filing. Use the EDGAR filings index for the first filing date. No Paid: Stocks Advanced plan or the Financials & Ratios expansion. Partial: MassiveProvider.fetch_company_metrics() (ratios)
Tiingo 5,500+ US equities and ADRs, 20+ years Partial: asReported=true returns as-reported instead of restated values; date is the release date No Paid add-on; a free evaluation covers the Dow 30 for 3 years. No (the Tiingo provider covers prices)
Yahoo Finance, via yfinance (unofficial) Most listed tickers; about five annual and five quarterly periods No: latest values only, no filing date Yes: current consensus only Free, unofficial; Yahoo's terms restrict use. Yes: YahooFinanceProvider.fetch_financials(), fetch_company_metrics()

Institutional and Academic Databases

These are licensed by firms and universities. Students usually reach them through WRDS (Wharton Research Data Services) when their institution subscribes; which databases are available depends on the institution's licenses.

Source Coverage Point-in-time Estimates Access ml4t-data
Compustat (S&P Global Market Intelligence) North America and Global No in the standard annual and quarterly files, which hold restated values No (see Capital IQ) Institutional; academic via WRDS No
Compustat Point-in-Time and Compustat Snapshot North America, snapshots from 1987 Yes: every value as it was known at each snapshot date, including preliminary figures No Institutional; Snapshot via WRDS where licensed No
CRSP/Compustat Merged (CCM) US; links CRSP securities (PERMNO) to Compustat issuers (GVKEY) Inherits the Compustat file it is joined to; the link table itself is dated No Academic via WRDS. CRSP was acquired by Morningstar in February 2026. No
S&P Capital IQ Financials Global Yes: Premium Financials carries filing dates for the full history and product delivery dates from 2004 Yes: Capital IQ Estimates Institutional (Capital IQ Pro, Xpressfeed, Snowflake); some via WRDS No
FactSet Fundamentals Global Yes: FactSet Fundamentals Point-in-Time, from February 1999 Yes: FactSet Estimates, with point-in-time consensus Institutional No
LSEG Company Fundamentals (includes Worldscope) and I/B/E/S (formerly Refinitiv, Thomson Reuters) Fundamentals: 120,000+ companies on 150+ exchanges, US from the early 1980s, other markets from the 1990s. I/B/E/S: North America from 1976, other markets from 1987 Yes: point-in-time versions of fundamentals and estimates are offered Yes: I/B/E/S Institutional; academic via WRDS where licensed No
Bloomberg Global Yes: Company Financials, Estimates and Pricing Point-in-Time through Data License Yes: Bloomberg Estimates (BEst) Institutional (Terminal, Data License) No

Fundamentals in ml4t-data

The Yahoo, EODHD, Finnhub and Massive providers expose fetch_financials() and fetch_company_metrics(). Statements come back in one long-format schema:

from ml4t.data.providers import EODHDProvider

provider = EODHDProvider()  # reads EODHD_API_KEY
income = provider.fetch_financials("AAPL", statement="income", period="quarterly")
# columns: symbol, provider, statement_type, period_type, period_end, line_item, value,
#          currency, fiscal_year, fiscal_period, filed_at, source

filed_at is filled when the vendor response carries a filing date (filing_date, filingDate, filedDate or acceptedDate) and is empty otherwise. Treat period_end as the end of the reporting period, never as the date the value was known. When filed_at is empty, the frame is not point-in-time; use it for exploration, not for backtests.

MassiveProvider.fetch_financials() still targets the retired Financials endpoint; Massive now serves statements from /stocks/financials/v1/income-statements, balance-sheets and cash-flow-statements.


Name Changes and Closures

Then Now
Quandl Nasdaq Data Link (September 2021); legacy quandl names persist in URLs and code
Polygon.io Massive (October 30, 2025); api.polygon.io still answers alongside api.massive.com
Refinitiv (Thomson Reuters Financial & Risk) LSEG Data & Analytics
CRSP (University of Chicago) Owned by Morningstar since February 2, 2026; CRSP indexes are being renamed Morningstar indexes
Sharadar on Nasdaq Data Link only Also sold direct at sharadar.com since July 2026
IEX Cloud Retired August 31, 2024; its endpoints no longer answer

See Also