edgarfundamentals provides a simple, ticker-based
interface for retrieving fundamental financial ratios directly from SEC
EDGAR 10-K filings. No API key or paid subscription is required. All
data comes from the SEC’s official XBRL API at
data.sec.gov, which is free, stable, and
government-maintained.
The package provides four functions:
get_cik() – translates a ticker to its SEC Central
Index Keyget_fundamentals() – retrieves ratios for a single
stockget_fundamentals_batch() – retrieves ratios for a
portfolio of stocksget_filing_history() – retrieves recent SEC filing
history for a stockBefore making any API calls, set your User-Agent string. The SEC requests that automated tools identify themselves so they can contact you if your scripts cause issues with their servers.
Replace the name and email with your own. You only need to do this once per R session.
Every EDGAR API call requires a CIK number. get_cik()
handles this translation automatically inside the other functions, but
you can call it directly if you need the CIK for other purposes.
get_fundamentals() returns a named vector of key
financial ratios derived from the most recent 10-K filing on or before
to_date.
The returned vector contains:
| Name | Description |
|---|---|
CIK |
SEC Central Index Key |
EPS |
Diluted Earnings Per Share (USD) |
NetIncome |
Net Income (USD) |
Revenue |
Total Revenue (USD) |
ROE |
Return on Equity (%) |
ROA |
Return on Assets (%) |
DE |
Debt-to-Equity ratio |
CurrentRatio |
Current Assets / Current Liabilities |
GrossMargin |
Gross Profit as a percentage of Revenue (%) |
OperatingMargin |
Operating Income as a percentage of Revenue (%) |
NetMargin |
Net Income as a percentage of Revenue (%) |
PE |
Price-to-Earnings ratio |
PB |
Price-to-Book ratio |
DIV |
Dividend Yield (%) |
Because ratios come from annual 10-K filings, they reflect the most recently completed fiscal year – not real-time values. The PE ratio is the only computed value that uses a live market price (via Yahoo Finance), so it will change daily even when the underlying 10-K data does not.
get_fundamentals_batch() accepts a vector of tickers and
returns a tidy data frame with one row per stock. If retrieval fails for
any ticker, that row contains NA values and a message is
printed – the batch continues rather than stopping.
healthcare <- c("UNH", "PFE", "MRK", "ABT", "LLY", "CVS", "AMGN")
defense <- c("LMT", "RTX", "NOC", "GD", "HII", "LHX", "LDOS")
healthcare.fund <- get_fundamentals_batch(healthcare, to_date = "2024-12-31")
defense.fund <- get_fundamentals_batch(defense, to_date = "2024-12-31")
healthcare.fund
defense.fundExpect retrieval to take approximately 20–30 seconds for 14 stocks. A 0.5 second pause is inserted after each API call to respect the SEC rate limit.
Once you have the data frame, standard dplyr operations
apply directly.
library(dplyr)
# Growth screen: high EPS stocks relative to peers signal strong earnings
healthcare.fund |> arrange(desc(EPS))
# Value screen: low PE and low PB suggest the market is pricing the stock cheaply
# High dividend yield is also characteristic of value stocks
defense.fund |> filter(PE < 20 & PB < 3) |> select(symbol, PE, PB, DIV, ROE)
# GARP screen (Growth at a Reasonable Price): PE below EPS
# Stocks where the market is not overcharging for growth
healthcare.fund |> filter(EPS > 0 & PE < EPS) |> select(symbol, PE, EPS)
# Profitability screen: strong margins signal pricing power and operational efficiency
bind_rows(healthcare.fund, defense.fund) |>
filter(GrossMargin > 40 & OperatingMargin > 15) |>
arrange(desc(NetMargin)) |>
select(symbol, GrossMargin, OperatingMargin, NetMargin, ROA)
# Liquidity screen: current ratio above 1.5 and low leverage
bind_rows(healthcare.fund, defense.fund) |>
filter(CurrentRatio > 1.5 & DE < 1) |>
arrange(desc(CurrentRatio)) |>
select(symbol, CurrentRatio, DE, ROE)get_filing_history() retrieves recent EDGAR filings for
a company, which is useful for verifying data availability or for
finding the accession numbers needed to access the full text of specific
reports.
EDGAR XBRL data is only as good as what companies report. A small
number of companies use non-standard XBRL tag names for common concepts.
The package automatically tries fallback tags when the primary tag
returns no data, but in rare cases a ratio may still be NA.
When this occurs, verifying the company’s most recent 10-K directly on
edgar.sec.gov will confirm whether the data exists under a
different tag name.
Additionally, EDGAR does not provide market-based ratios directly.
Price-to-Book and Dividend Yield both require a current share price,
which comes from Yahoo Finance via tidyquant. This means
PE, PB, and DIV all reflect today’s price against the most recent annual
filing data, which is standard practice for trailing ratios.