data_updater_v2.data_clients.papers
papers.py — what a listing IS: its kind (AssetClass) and its paper (SecurityType), from
what FMP, OpenFIGI and EODHD say about it, and an ETF’s gearing from its name.
PORTED from nc-feeds, not rewritten (nc-core libs/feeds, the tree of 2026-10-06): the
tables are verbatim from nc_feeds/normalizers/symbols.py (SPELLING 424-457, FIFTH 459-473,
the EODHD lines 480-488, ETN … NAME 527-721, NOT_A_VENUE 333-350, the OpenFIGI and EODHD
blocks of TYPE 372-416) and nc_feeds/normalizers/profiles.py (MULTIPLIER … BRAND_WORDS
686-731, with the census fix of 2026-10-06); the readers are its _kind_fmp,
_kind_openfigi, _kind_eodhd / _kind_eodhd_typed, paper, _leverage_text and
_gearing, census-checked there (every Nasdaq listing, every US ETF name). The vocabulary is
nc-feeds’ own: AssetClass, SecurityType, a paper.
OUR symbol is nc-feeds’ spelling (spell_fmp / spell_eodhd / spell_bitstamp):
^GSPC -> GSPC, BTCUSD -> BTC-USD, GCUSD -> GC, ABR-P-D -> ABR-PD;
a listing’s dashes stay (BRK-B). The tables key on it and keep each vendor’s own spelling
beside it, so any vendor is asked in its own words. Not ported: the fund-objective and N-CEN
gearing readers (FMP serves neither, so a fund’s NAME is all there is: gearing).
Each reader returns (kind, paper), either None when the line cannot tell, and raises
ValueError for a line that is not a listing (a fund class code, a temporary line, a
foreign suffix), so a caller drops it by that reason.
Classes
AssetClass
Bases: StrEnum
The broad kind of instrument (nc-feeds contracts/symbols.py).
ETF covers every exchange-traded product; the paper distinguishes
funds, notes, vehicles, and commodities.
Form
One spelling of a ticker (nc-feeds schemas/normalizers/configs.py): the pattern,
our spelling’s template, the paper the spelling carries, and who spells this way
(empty = everyone).
read
read(raw: str, source: str | None) -> dict[str, Any] | NoneGrammar
The ordered spellings of a ticker; the first form the source is allowed wins.
read
read(raw: str, source: str | None) -> dict[str, Any] | NoneSecurityType
Bases: StrEnum
The paper an instrument is issued as (nc-feeds contracts/symbols.py).
Listed equities and exchange-traded products carry one; indices, mutual funds, crypto, forex, and commodities carry none. For a stock universe: COMMON, ADR, and LP_UNITS. For an ETF universe: the asset class alone.
Functions
coinmetrics_asset
coinmetrics_asset(symbol: str) -> strCoin Metrics’ asset code for one of OUR coin symbols: the base in lowercase (BTC-USD -> btc; a Bitstamp-only coin’s TRUMP-USD-BITSTAMP -> trump).
eodhd_kind
eodhd_kind(row: Mapping[str, Any]) -> tuple[AssetClass | None, SecurityType | None]The kind and paper of one EODHD ticker-list or bulk row (nc-feeds _line_eodhd +
_kind_eodhd + _kind_eodhd_typed): the spelling first (a pair, an index, a
marker), then its Type read with the venue and the name. FUND is a closed-end fund on a
venue and a mutual fund off one; ETF defers to the name for ETNs and term trusts; a
Common Stock that is named an ETF is one. ValueError for a fund class code, a
temporary trading line (when-issued, called, Nasdaq’s test symbols) or an unknown Type.
fmp_kind
fmp_kind(row: Mapping[str, Any]) -> tuple[AssetClass | None, SecurityType | None]The kind and paper of one FMP line — a profile, a screener row, an etf/info row, a
list row (nc-feeds _line_fmp + _kind_fmp): the spelling first, then FMP’s three
flags (isEtf, isFund, isAdr) where the line carries them, then the name. isFund covers
two kinds: a mutual fund on NASDAQ with an X ticker, a closed-end fund anywhere else. A
BDC is a closed-end fund (INVESTMENT_COMPANIES, Sam’s ruling 2026-09-10). A list row
without flags or name tells only what its spelling says. ValueError for a line that
is not a US listing (a foreign suffix, a when-issued line).
gearing
gearing(name: str | None) -> tuple[float | None, bool | None]A fund’s signed daily multiplier and whether it is geared, from its NAME (nc-feeds
parse_leverage for a source that tells only a name: _leverage_text then
_gearing): the duration and strategy phrases scrubbed, ProShares’ gearing words
scrubbed from every other issuer’s name. A plain fund never says it is plain: 1 when the
name says nothing; “Leveraged” with no number is geared, the number unknown (None, True).
(None, None) when there is no name.
gearing_from_objective
gearing_from_objective(objective: str | None) -> tuple[float | None, bool | None]A fund’s signed daily multiplier from its stated OBJECTIVE (the prospectus text the SEC’s Risk/Return summary carries), read from the sentence that names the benchmark’s performance; an income multiple is not gearing and lands nothing. (None, None) when the objective states no multiple.
openfigi_kind
openfigi_kind(record: Mapping[str, Any]) -> tuple[AssetClass | None, SecurityType | None]The kind and paper of one OpenFIGI record (nc-feeds _line_openfigi +
_kind_openfigi): its securityType, one of ours each; an ETP is an ETN when its
name says so; a sector beside Equity is its own kind (an index, a currency or coin, a
commodity). ValueError for a type or sector nc-feeds’ census never met.
paper
paper(name: str) -> SecurityTypeThe paper a security name declares; a plain company name is common stock.
spell_bitstamp
spell_bitstamp(pair: str) -> strOUR spelling of a Bitstamp pair (BTC/USD or its url symbol btcusd): BTC-USD.
spell_eodhd
spell_eodhd(row: Mapping[str, Any]) -> strOUR spelling of an EODHD ticker (nc-feeds’ symbol, _line_eodhd): its code without
the market suffix (AAPL.US -> AAPL, GSPC.INDX -> GSPC, BTC-USD.CC -> BTC-USD), a dead
era’s marker dropped (FB_old -> FB), a preferred in our form (ABR-P-D -> ABR-PD).
spell_finra
spell_finra(symbol: Any, name: Any = None, market_class: Any = None) -> strOUR spelling of a ticker as FINRA’s short-interest dataset or its daily short-volume
file spells it, or as the SEC’s fails file (the same glued convention) does: the file’s
own marks first (ABRpD a preferred, ALUB/WS a warrant, AAC/U a unit, AKO/A
a class: the grammar’s FINRA forms), then the glued suffix of a code longer than five
letters (ABRPRD -> ABR-PD, ACHRWS -> ACHR-WT, AIIART -> AIIA-RI), then a
five-letter code on the NYSE family (market_class in FINRA_NYSE) whose name
says unit, right or warrant (AACU -> AAC-UN when the name says Units) or whose name
says the class its last letter spells (BRKB “Class B” -> BRK-B); else the code as it
is. Without a market class (the fails file) a five-letter code is never read as glued:
the fails file’s CUSIP anchors its row. ValueError for a spelling that is not a US
ticker (BCATRTWI, a when-issued right).
spell_fmp
spell_fmp(row: Mapping[str, Any]) -> strOUR spelling of an FMP line’s ticker (nc-feeds’ symbol, _line_fmp): a listing as
FMP dashes it (BRK-B; a preferred ABR-PD, an ACT ABR$D too), an index without its
caret (^GSPC -> GSPC; DX-Y.NYB -> DX-Y), a coin as BASE-USD (BTCUSD -> BTC-USD), a
commodity as its root (GCUSD -> GC, KEUSX -> KE: the currency, USD or USX, is the
line’s). ValueError for a line that is not a US listing.
spell_for
spell_for(listing: Any, vendor: Vendor, kind: Kind | None = None, currency: str | None = None) -> str | NoneHow vendor spells one of OUR symbols, so it is asked in its own words. listing
is our symbol (kind then says the family; a commodity needs its currency, USD
or USX) or a universe row, whose own vendor column is read. None: the vendor does not
carry the family (EODHD has no continuous futures; Bitstamp only coins).
etf, equity FMP SPY, BRK-B (ours as is) · EODHD SPY.US · SEC SPY (ours as is)index FMP ^GSPC (DX-Y -> DX-Y.NYB) · EODHD GSPC.INDXcrypto FMP BTCUSD · EODHD BTC-USD.CC · Bitstamp btcusd · Coin Metrics btccommodity FMP GCUSD / KEUSXCoin Metrics names an asset by its lowercase code (btc), the base of our pair; the
crypto catalog carries no column for it, so it is read from our symbol.
spell_ib
spell_ib(symbol: Any) -> strOUR spelling of a ticker as IB’s shortable file spells it: a class with a space
(BRK B -> BRK-B), a preferred as ABR PRD (ABR-PD), a unit as AAC U (AAC-UN):
the grammar’s IB forms; a bare code as it is. ValueError for a spelling that is not a
US ticker (AAGH.OLD1, a dead era’s marker; 2777456Q; GHMLUSD).
spell_sec
spell_sec(row: Mapping[str, Any]) -> strOUR spelling of a ticker as the SEC’s directories spell it (company_tickers_exchange:
ticker, exchange; company_tickers_mf: symbol): dashed as we dash (BRK-B, JPM-PC,
VAL-WT, KCAC-UN, CELG-RI), or Nasdaq’s fifth letter on a Nasdaq listing (BEATW, a
warrant). ValueError for a spelling that is not a US ticker.
with_kind
with_kind(reader: Callable[[Mapping[str, Any]], tuple[AssetClass | None, SecurityType | None]], row: Mapping[str, Any]) -> dict[str, Any]The row with what the reader says it IS: asset_class, security_type, and
refused (None, or why it is not a listing).