Skip to content

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] | None

Grammar

The ordered spellings of a ticker; the first form the source is allowed wins.

read

read(raw: str, source: str | None) -> dict[str, Any] | None

SecurityType

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) -> str

Coin 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) -> SecurityType

The paper a security name declares; a plain company name is common stock.

spell_bitstamp

spell_bitstamp(pair: str) -> str

OUR spelling of a Bitstamp pair (BTC/USD or its url symbol btcusd): BTC-USD.

spell_eodhd

spell_eodhd(row: Mapping[str, Any]) -> str

OUR 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) -> str

OUR 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]) -> str

OUR 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 | None

How 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.INDX
crypto FMP BTCUSD · EODHD BTC-USD.CC · Bitstamp btcusd · Coin Metrics btc
commodity FMP GCUSD / KEUSX

Coin 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) -> str

OUR 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]) -> str

OUR 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).