US Company Fundamentals
AvailablePoint-in-time income statement, balance sheet and cash flow figures from every 10-K and 10-Q.
One row for every 10-K and 10-Q a company files with the SEC, built from the XBRL financial data in EDGAR. Each row holds about 30 normalized fields: revenue, margins, earnings per share, cash flow and the main balance sheet lines.
The data is point-in-time. A row reaches your algorithm when the filing became public, with the values the company reported then. Restatements arrive later as their own rows and never rewrite history, so backtests see what investors could actually see.
How the data works
- Rows become available at 17:30 New York time on the filing date. EDGAR dates a filing accepted after 17:30 as the next business day, so this is never earlier than the real release, and up to a day later.
- Income statement fields cover the filing's quarter (10-Q) or full year (10-K). Cash flow fields ending in _ytd are fiscal year to date, as companies report them.
- Amendments (10-K/A, 10-Q/A) arrive as new rows on their own filing date.
- A field the filing doesn't report is None. Banks and insurers, for example, have no gross profit.
- Tickers resolve through SEC's list of current tickers. For a delisted or renamed company, pass its CIK instead, for example "1288776" for Google before Alphabet.
Fields
36 columns| Field | Description |
|---|---|
| available_time | When the row becomes visible to an algorithm: 17:30 New York time on the filing date |
| accession | SEC accession number of the filing, unique per filing |
| form | 10-K, 10-Q, 10-K/A or 10-Q/A |
| fiscal_year | Fiscal year the company assigns to the filing |
| fiscal_period | FY, Q1, Q2 or Q3 |
| period_end | Last day of the period the filing reports |
| revenue | Revenue for the quarter (10-Q) or year (10-K) |
| cost_of_revenue | Cost of revenue for the period |
| gross_profit | Gross profit for the period |
| research_and_development | Research and development expense for the period |
| selling_general_admin | Selling, general and administrative expense for the period |
| operating_income | Operating income or loss for the period |
| interest_expense | Interest expense for the period |
| pretax_income | Income before income taxes for the period |
| income_tax | Income tax expense or benefit for the period |
| net_income | Net income or loss for the period |
| eps_basic | Basic earnings per share for the period |
| eps_diluted | Diluted earnings per share for the period |
| weighted_shares_basic | Weighted average basic shares for the period |
| weighted_shares_diluted | Weighted average diluted shares for the period |
| dividends_per_share | Dividends declared per share for the period |
| operating_cash_flow_ytd | Cash from operations, fiscal year to date |
| capex_ytd | Purchases of property, plant and equipment, fiscal year to date |
| depreciation_ytd | Depreciation and amortization, fiscal year to date |
| dividends_paid_ytd | Dividends paid, fiscal year to date |
| buybacks_ytd | Share repurchases, fiscal year to date |
| cash | Cash and cash equivalents at period end |
| receivables | Accounts receivable at period end |
| inventory | Inventory at period end |
| current_assets | Total current assets at period end |
| total_assets | Total assets at period end |
| current_liabilities | Total current liabilities at period end |
| total_liabilities | Total liabilities at period end |
| long_term_debt | Long-term debt at period end |
| shareholders_equity | Shareholders' equity at period end |
| shares_outstanding | Common shares outstanding, from the filing's cover page |
Example algorithm
# region imports
from AlgorithmImports import *
# endregion
from lean_platform_data import SecFundamentals
class FundamentalsAlgorithm(QCAlgorithm):
def initialize(self):
self.set_start_date(2014, 1, 1)
self.set_end_date(2021, 1, 1)
self.aapl = self.add_equity("AAPL", Resolution.DAILY).symbol
# A ticker or a CIK. Rows arrive at 17:30 New York time on the filing date.
self.fundamentals = self.add_data(SecFundamentals, "AAPL").symbol
def on_data(self, slice):
if self.fundamentals in slice:
f = slice[self.fundamentals]
self.debug(f"{f.form} {f.fiscal_period} {f.period_end}: revenue {f.revenue}, EPS {f.eps_diluted}")
if f.net_income and f.revenue and f.net_income / f.revenue > 0.2:
self.set_holdings(self.aapl, 1)
else:
self.liquidate(self.aapl)
Public data from the U.S. Securities and Exchange Commission. Free for backtesting on MarketsCoder.