spb/hfmarketdata
Public
Open high-frequency market data platform — FirstRate full-history downloader, DuckDB/Parquet lake, open REST API and React docs platform (www.hfmarketdata.io)
JavaScript 53.7%
Python 38.3%
CSS 4.6%
TypeScript 3.1%
1---2name: hfmd-fundamentals-screen3description: Screen US stocks on fundamental ratios with HF Market Data (PE, PB, EV/EBITDA, FCF yield, ROE, margins, leverage, growth), enrich the hits with their latest ratios and recent quarterly statements, and document the point-in-time caveats (filing dates, restatements). Use when the user asks to "find stocks with…", "screen for…", or compare companies on fundamentals.4---56# hfmd-fundamentals-screen78Run a screener → pull ratios and statements for the survivors → produce a table the user can defend,9with the date each number became public.1011## When to use1213- "Screen US stocks with PE<15 and FCF yield>6% and show their last 3 quarters"14- "Cheapest software companies by EV/EBITDA with ROE > 20 %", "which of these tickers has the best balance sheet?"15- Historical: "what would this screen have returned on 2020-03-20?" (`--as-of`, point-in-time)1617## Filter syntax1819`filters="pe<15,roe>0.15,fcf_yield>0.06,market_cap>1e9"` — comma-separated `metric<op>value`, ops `< <= > >= =`.20Ratios are **decimals** (0.15 = 15 %). Known metrics: `pe pb ps ev_ebitda fcf_yield dividend_yield roe roa gross_margin operating_margin net_margin debt_to_equity current_ratio revenue_growth eps_growth market_cap sector`.21Sort: `--sort fcf_yield:desc`.2223## Steps24251. Translate the request into filters (ask for thresholds when vague: "cheap" → `pe<15`? `ev_ebitda<8`?). Convert percentages to decimals.262. Screen + enrich:27 `python3 scripts/screen.py --filters "pe<15,fcf_yield>0.06" --sort fcf_yield:desc --limit 25 --quarters 3 --out screen.csv`28 - calls `/v1/fundamentals/screener` (cost: 2 requests), then for each hit `/v1/fundamentals/{t}/ratios` and `/v1/fundamentals/{t}/statements?statement=income&period=quarterly&limit=3` (`--no-enrich` to skip; keyless quota allows ~10 tickers/hour — set `HFMD_API_KEY`).29 - prints the screen table, then per ticker the last N quarters (revenue, operating income, net income, EPS, filed_at) and a **point-in-time note**: latest `filed_at` used, days since, whether a newer period end exists without a filing yet.303. Present: one table sorted as requested, then the quarterly mini-tables, then caveats.3132## Point-in-time discipline (always say it)3334- Every fundamentals row carries `period_end` **and** `filed_at`. A number is knowable only from `filed_at` (10-Q ≈ 40 days, 10-K ≈ 60-90 days after period end). Screens with `--as-of` use what was filed by that date — this is what makes a backtest of the screen honest.35- Restatements: `facts/{concept}` returns every reported value for a period; the statements endpoint returns the latest. Mention it when a number looks off.36- Price-based ratios (PE, FCF yield…) use the close of `as_of` (or the latest) and the last **reported** TTM figures — not analyst estimates.37- Coverage differs by company (`/v1/fundamentals/{t}/coverage`): small caps and recent IPOs have short histories; missing = `null`, never imputed.3839## Examples4041```bash42# Classic value + quality43python3 scripts/screen.py --filters "pe<15,roe>0.15,debt_to_equity<1" --sort pe:asc --limit 204445# Point-in-time: what the screen showed at the March 2020 low46python3 scripts/screen.py --filters "fcf_yield>0.08,net_margin>0.1" --as-of 2020-03-20 --no-enrich4748# Only enrich a list you already have49python3 scripts/screen.py --tickers AAPL MSFT GOOGL --quarters 450```5152## Gotchas5354- A screener 404 means the fundamentals module is not deployed yet on the server; the script says so and exits 2.55- `sector` is a string filter (`sector=Technology`); everything else is numeric.56- Banks/insurers: EV/EBITDA and FCF yield are not meaningful — prefer PB, ROE.57- The screener costs 2 quota requests; with 30/h keyless, do not loop over many parameter sets without a key.58