Skip to main content

Crate pomelo_fmp

Crate pomelo_fmp 

Source
Expand description

Bring-your-own-key FMP (Financial Modeling Prep) data sync + snapshot-factor formulas (issue #52 / #132).

Direct HTTP, no third-party FMP SDK. Given the user’s own API key, fetch adjusted daily bars (and optionally annual fundamentals, a symbol → sector industry map, and snapshot-factor panels) and write a docs/data-layout.md tree:

<out>/prices/{SYM}.csv.gz        adjusted OHLCV                 (always)
<out>/fundamentals/{SYM}.csv.gz  dense forward-filled factors   (--include-fundamentals)
<out>/tracked/universe.csv.gz    symbol,sector,market_cap       (--include-industry)
<out>/panels/{name}.csv.gz       snapshot-factor panels         (--include-snapshot-factors)

§Reuse across CLI and service

sync writes to a local path; sync_into is the storage-agnostic core over any ObjectSink + ObjectSource, so the CLI and a backend service produce byte-identical trees whether the destination is local disk or an S3/R2 bucket (pomelo-s3’s S3Source). The pure [factors] formulas are the single source of truth a Rust service links directly (and wasm/PyO3 bindings can expose later).

The key never leaves the machine; we neither host nor redistribute FMP data. FMP stays out of yuzu-core / pomelo-data / WASM — the HttpClient indirection keeps networking optional (build with --no-default-features) and testable.

§MVP scope

Enough to backtest price-based strategies over a short US window: close / OHLC TA and cross-section ops on a modest symbol list. Fundamentals are best-effort from the annual ratios/key-metrics/growth endpoints (plus income-statement for filing-date visibility, #131); richer fundamentals, full-universe, and point-in-time index membership are out of scope (see #53 / #125). Delisted names can be unioned into the universe with --include-delisted for survivorship-honest backtests (#124 / #26) — see [delisted]. Which library features an FMP Starter key can honestly support — and which panels are missing — is documented in docs/fmp-data-source.md (#51).

Structs§

DelistedSymbol
A delisted security from FMP’s delisted-companies endpoint.
IndexMembership
The reconstructor: the current constituent set plus the change log (ascending).
SymbolFilter
Filters for build_symbol_list — a screened market universe.
SyncConfig
Knobs for one [sync] run.
SyncSummary
What a [sync] run produced.
UreqClient
The real ureq-backed client — only with the fmp-sync feature. A dependent that supplies its own HttpClient can build with the feature off. The real ureq-backed client — only with the fmp-sync feature. The real ureq-backed client — only with the ureq feature.

Enums§

HttpError
A classified HTTP failure so the retry loop knows whether to back off.
Index
An index we can reconstruct PIT membership for. Each maps to FMP’s current-snapshot + historical-change-log endpoints and a membership series name (in_<index>).
WriteMode
How an already-present symbol tree is treated by a sync run.

Constants§

MEMBERSHIP_SERIES
Membership series names auto-loaded by the CLI (load_ctx) from panels/, so signal * in_sp500 works on the run / sweep path. Kept in sync with Index::series_name (asserted in tests).
US_EXCHANGES
The default exchange filter — the three US major exchanges. (AMEX is now NYSE American, but FMP still labels it AMEX.)

Traits§

HttpClient
Minimal blocking HTTP GET, abstracted so sync logic is tested with a mock.

Functions§

build_symbol_list
Build a screened symbol universe from FMP’s screener (/stable/company-screener) — the “establish the sync list first” step so a whole-market backtest has a persisted, reviewable symbol list to sync. The filters are pushed to the API and re-applied client-side as a safety net. Returns tickers, sorted and de-duplicated.
fetch_delisted
Fetch the delisted universe, paging delisted-companies until an empty page or [MAX_DELISTED_PAGES]. exchanges filters client-side (comma-separated FMP codes; None / empty / "all" keeps every exchange — note that delisted-companies carries no market cap, so a --min-market-cap floor cannot apply to these names). Returns rows sorted and de-duplicated by symbol.
parse_market_cap
Parse a market-cap threshold with an optional magnitude suffix — k, m, b, t (thousand / million / billion / trillion), case-insensitive. Plain numbers and scientific notation pass through. Examples: 1b → 1e9, 500m → 5e8, 2.5t → 2.5e12, 1e9 → 1e9, 0 → 0.
parse_symbols_list
Parse a symbols-list file into tickers. One ticker per line; the first comma-separated field is taken (so a symbol,... CSV works), and blank lines, # comments, and a literal symbol header are skipped.
sync
Sync symbols from FMP into the local out tree per SyncConfig — a thin convenience wrapper over sync_into for the common on-disk case.
sync_into
Storage-agnostic core: sync symbols from FMP into any store — local disk (LocalSource) or an S3/R2 bucket (pomelo-s3’s S3Source) — so the CLI and a backend service produce byte-identical trees for the same inputs. Prices are always fetched; fundamentals and industry are opt-in. Progress and per-symbol failures are logged to stderr (API key redacted); a per-symbol failure is recorded and the batch continues.
write_index_membership
Reconstruct and write an index membership panel (panels/in_sp500.csv.gz, etc.) over the synced tree’s trading calendar. Columns are the index’s ever_members(from, to) — the same universe you should have synced. Returns (days, symbols) in the written panel.