trail-fmp
Financial Modeling Prep data source for Trail, via the
aiofmp async client.
FMP returns already-normalized statement line items, so trail-fmp maps them directly onto
Trail's canonical schema and serves them at both annual and quarterly frequency - use the
frequency prefix to pick, or reference bare fields for the annual default:
model growth at quarterly {
export rev_ttm = ttm(quarterly.income.revenue)
export roe = fmp.roe
export pe = daily.price.adj_close / annual.income.eps_diluted
}
Provides
- Statements (annual + quarterly, 39 fields):
income.*: revenue, cogs, gross_profit, operating_income, net_income, interest_expense, income_tax_expense, income_before_tax, eps_diluted, weighted_average_shares_diluted, weighted_average_shares, ebitda, depreciation_amortization, sgabalance.*: total_assets, current_assets, current_liabilities, total_liabilities, long_term_debt, total_debt, total_equity, retained_earnings, accounts_receivable, inventory, accounts_payable, net_fixed_assets, cash_and_equivalents, cash_and_short_term_investments, minority_interest, common_stock, goodwillcash.*: cfo, capex, free_cash_flow, stock_issued, cfi, cff, net_change_in_cash, dividends_paid (capexanddividends_paidare normalized to positive magnitudes)
- Meta:
meta.sector,meta.exchange,meta.is_active,meta.countryare a current snapshot broadcast onto every period;meta.countryis normalized to ISO3, so it bridges to country-keyed sources liketrail-gmd.meta.market_capis real per-period data from key-metrics (naive placement - not filing-lag-adjusted). - Price:
price.adj_close- dividend-adjusted close, sampled at each period-end for statement frequencies, or one row per trading day atdaily. fmp.*ratio / metric / score vocabulary (49 fields):- margins & profitability:
gross_margin,net_margin,ebit_margin,ebitda_margin,operating_margin,pretax_margin,effective_tax_rate - liquidity & leverage:
current_ratio,quick_ratio,cash_ratio,debt_to_equity,debt_to_assets,financial_leverage,interest_coverage - turnover:
asset_turnover,inventory_turnover,receivables_turnover,payables_turnover - price multiples & dividends:
pe,pb,ps,price_to_fcf,peg,dividend_yield,dividend_per_share,payout_ratio - returns & valuation:
roe,roa,roic,roce,earnings_yield,ev_to_sales,ev_to_ebitda,ev_to_fcf,fcf_yield,enterprise_value,graham_number,graham_net_net,invested_capital,working_capital,income_quality,capex_to_revenue,capex_to_depreciation - operating cycle:
dso,dio,dpo,ccc - quality scores (current snapshot):
piotroski,altman_z
- margins & profitability:
- Entity dimension:
entity(tickers) - a plain entity-keyed source. - Frequencies:
annual,quarterlyfor statements/ratios/meta;dailyforprice.adj_closeonly (statements/ratios/meta have no daily axis). - Unavailable:
price.dividends- aiofmp has no historical per-share dividends endpoint; usefmp.dividend_yield/fmp.dividend_per_shareinstead.
Configure
# trail.yaml
sources:
fmp:
driver: fmp
options:
api_key: ${FMP_API_KEY} # or set the FMP_API_KEY environment variable
tickers: [AAPL, MSFT] # or let a model's universe scope the fetch
cached: true # optional: aiofmp's Parquet cache
limit: 20 # periods fetched per statement
precedence:
default: [fmp]
Options
| Option | Type | Default | Meaning |
|---|---|---|---|
api_key |
str | (required) | FMP API key; falls back to the FMP_API_KEY env var. Missing both raises E-FMP-KEY. |
tickers |
list[str] | [] |
The fetch universe (uppercased). A model's own universe (via request.entities) scopes a given load regardless of this setting. |
universe |
str | None |
Named-universe fallback. Accepted for parity with other sources but not currently consulted by this source's entities() - only tickers scopes the fetch today. |
cached |
bool | false |
Wrap the client in aiofmp's CachedClient (Parquet-backed) to avoid refetching across runs. |
cache_dir |
str | aiofmp's default | Parquet cache location, passed to ParquetStorage. Only read when cached: true. |
limit |
int | 20 |
Periods fetched per statement endpoint. Auto-expanded (with margin) to cover a requested period window, so it's never silently truncated. |
requests_per_minute |
int | None (aiofmp's default) |
Caps the request rate against FMP, to avoid 429s when many tickers are fetched concurrently. |
pit |
str | None |
Set to naive to disable point-in-time placement for this source - every field falls back to period-end. |
Point-in-time
Statement fields (income.*, balance.*, cash.*) and the fmp.* ratio/metric fields computed
from them (the ratios and metrics endpoints) carry a __date:filing_date coordinate - taken
from the statement's acceptedDate, falling back to filingDate - so the PIT engine places each
value by when it was actually knowable (lookahead-safe) rather than at period-end.
Snapshot fields (meta.* profile fields and the fmp.* quality scores) and price.adj_close
stay naive (period-end). Set options.pit: naive to disable PIT placement for this source
entirely.
Querying fmp.* ratio/metric fields without any statement field alongside them loses the
filing-date coordinate (only the statement loop attaches it) and falls back to naive placement -
include a statement field in the same query to get lookahead-safe placement for those fmp.*
fields too.
Notes
meta.*(profile) and thefmp.*quality scores are current snapshots broadcast onto each period - not point-in-time series.- Some balance/cash-flow wire names follow the standard FMP
/stablespelling; if a field returns null across the board, verify it against a live pull (pytest -m live). - A ticker that fails to load (paywalled endpoint, delisted symbol, transient error) is skipped with a warning rather than aborting the whole panel, unless every ticker fails or the error is auth/config-class.
Metadata
Release files for trail-fmp 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| trail_fmp-0.3.0.tar.gz | 168.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| trail_fmp-0.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 184.8 kB
Release files / trail_fmp-0.3.0.tar.gz
| Download URL | trail_fmp-0.3.0.tar.gz |
|---|---|
| Size | 168.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
cc64b68c7ed81cd399e1fc14b1a7c6e0f90cc0bf9fe5c2425a45bf5fc658b382
|
|
BLAKE2b-256 checksum How to use checksums |
db498fd71fe743b0f656c36dad1c4241d950eaa25570ef8bafb3636910a30e1d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 21, 2026.
Transparency logRelease files / trail_fmp-0.3.0-py3-none-any.whl
| Download URL | trail_fmp-0.3.0-py3-none-any.whl |
|---|---|
| Size | 16.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c206f8b348afdbdcb6e04d24db33c42868e0054a44d44d0d938e81ba589f380c
|
|
BLAKE2b-256 checksum How to use checksums |
bd3350531014822132259cb981991a3c3bff0e972e8adf0f19d15a74198363f0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 21, 2026.
Transparency log