quantlab.dataset.crsp.tickers.CrspTickerLookup#
- class quantlab.dataset.crsp.tickers.CrspTickerLookup(sidecar_path)[source]#
Bases:
TickerLookupLook up the ticker a PERMNO had on a given day, from one
{zarr}.crsp_tickers.json.The file is read lazily, on first use. The callers are display code deep inside a backtest or a log call that only has a store path; if the constructor read the disk, creating a lookup “just in case” would cost a file read at every such place.
- Parameters:
- sidecar_pathstr or Path
Path of the ticker sidecar. A CRSP or NBBO dataset’s
ticker_lookup()builds one over its own sidecar, andbeside_storederives it from a store path.
- Attributes:
- sidecar_pathPath
The sidecar path.
Examples
>>> from datetime import date >>> from quantlab.dataset.crsp.tickers import CrspTickerLookup >>> lookup = CrspTickerLookup.beside_store("data/data/us_equity/1d/crsp.zarr") >>> lookup.as_of(13407, date(2022, 6, 8)), lookup.as_of(13407, date(2022, 6, 9)) ('FB', 'META') >>> lookup.label([13407, 14593, 99999], date(2020, 1, 1)) ['FB', 'AAPL', '99999'] >>> lookup.names([13407], date(2022, 6, 9)) [SymbolName(ticker='META', company=None)]
- as_of(permno, day)[source]#
Return the ticker
permnohad onday, orNone.Both ends of an interval are inclusive. PERMNO 13407’s FB interval ends on 2022-06-08 and its META interval starts on 2022-06-09, so each day belongs to exactly one of them.
Nonemeans either “no interval covers this day” or “this sidecar does not know this PERMNO”; no caller needs to tell the two apart.The intervals are searched one by one: a security’s whole naming history is only a handful of intervals, so an index would cost more than it saves.
- Parameters:
- permnoint
The PERMNO, as an int or anything
int()accepts.- daydate
The date to look up; anything whose
str()starts with an ISO date works.
- Raises:
- FileNotFoundError
If the sidecar is absent.
- ValueError
If it cannot be parsed or has the wrong shape (top level,
intervals, or an interval withoutstart,endorticker).
Examples
>>> lookup.as_of(13407, date(2022, 6, 8)) 'FB' >>> lookup.as_of(13407, date(2000, 1, 1)) is None True
- classmethod beside_store(zarr_file_path)[source]#
Return the lookup for the sidecar written next to
zarr_file_path.For a caller holding only a store path. A caller holding the dataset asks it instead (
CrspStockDataset.ticker_lookup()), which is how a backtest and a membership report get it.The import is inside the function on purpose.
quantlab.dataset.crspdefines the constant and also loads polars and the whole converter, which a log line does not need. It is also this module’s own parent package, and importing it is only safe at call time, when the parent is fully initialized.- Parameters:
- zarr_file_pathstr or Path
Path of the CRSP Zarr store.
- Returns:
- CrspTickerLookup
A lookup over
<zarr_file_path>.crsp_tickers.json.
Examples
>>> CrspTickerLookup.beside_store("data/data/us_equity/1d/crsp.zarr") CrspTickerLookup('data/data/us_equity/1d/crsp.zarr.crsp_tickers.json')
- names(permnos, day)[source]#
Return the ticker of each of
permnosonday, in order.This is the entry point for display code (see
TickerLookup). It takes a batch because every caller prints a list (a missing-member report, a dropped-symbol warning, the settlement records of one date).companyis alwaysNone: the sidecar records no company name.It never raises. An unknown PERMNO falls back to its own digits, and so does every PERMNO when the sidecar is missing, unparseable or wrongly shaped. Every fallback caused by the file goes through
_degrade, which warns once per object. A value that is not an integer at all (a string symbol from another vendor) is passed through unchanged and does not count as a fallback.Errors are caught in two places because a damaged file can fail at two points:
{"intervals": [1, 2, 3]}fails while the table is read, while{"intervals": {"13407": [{"ticker": "FB"}]}}reads as a good table and only fails insideas_of. Both places catch_UNUSABLEand nothing wider.except Exceptionis avoided on purpose, so a real bug in this module still reaches the caller instead of being printed as digits that look like a genuine “no name on that day” answer.- Parameters:
- permnosSequence
PERMNOs as ints or digit strings, or plain string symbols.
- daydate
The date whose tickers to use.
- Returns:
- list of SymbolName
One name per input, in the input’s order.
Examples
>>> lookup.names([13407, 99999], date(2022, 6, 8)) [SymbolName(ticker='FB', company=None), SymbolName(ticker='99999', company=None)] >>> lookup.names(["AAPL"], date(2020, 1, 1)) [SymbolName(ticker='AAPL', company=None)]
- property payload#
Return the sidecar as parsed JSON, read at most once per instance.
- Raises:
- FileNotFoundError
If the sidecar is missing. The message names the class, the path and the fix (a rebuild), because the file is written by a conversion and cannot be created by hand.
- ValueError
If the file cannot be read or parsed. This includes a
RecursionErrorfrom JSON nested deeper than the parser allows, which would otherwise escape as aRuntimeErrorwithout the explanatory message.
Examples
>>> sorted(lookup.payload) ['generated_from', 'intervals', 'vintage_product_end']
- property product_end#
Return the last date of the CRSP data the sidecar was built from, or
None.CRSP publishes data in versions, each ending on a product end date.
Nonemeans the sidecar records no version, which is a valid state, not damage. Only a payload whose top level is not a JSON object is refused, with the same erroras_ofgives; a broken interval table does not affect this property.- Raises:
- FileNotFoundError
If the sidecar is absent.
- ValueError
If it cannot be parsed or its top level is not an object.
Examples
>>> lookup.product_end datetime.date(2025, 12, 31)