quantlab.backend.base.DataBackend#
- class quantlab.backend.base.DataBackend[source]#
Bases:
ABCContract for a storage medium that holds one tabular or panel dataset.
A backend owns a single in-memory object, exposed as
data, and knows how to move it to and from a path, narrow it in place, and convert it to the two exchange formats used across the pipeline: anxarray.Datasetand apolars.LazyFrame. Every mutating method returnsselfso calls can be chained.Two details of the contract are easy to get wrong when implementing it.
filter_by_dateandfilter_by_symbolnarrowdatain place, and every object sharing the backend instance sees the result.headmust do the opposite: open the store at the given path, read at mostnrows without materialising the whole store, and leavedatauntouched.Examples
>>> backend = XrBackend().read("prices.zarr") >>> panel = backend.filter_by_date("timestamp", "2022-01-01", ... "2022-12-31") >>> ds = panel.get_xarray_dataset(["timestamp", "symbol"])
- property data#
The object this backend currently holds.
- Raises:
- AttributeError
If nothing has been loaded yet. Accessing an unpopulated backend fails immediately rather than returning an empty dataset that downstream code would mistake for “no data in this range”.
Examples
>>> XrBackend().to_internal(panel).data is panel True >>> XrBackend().data Traceback (most recent call last): AttributeError: Please call 'read' or 'to_internal' first.
- abstractmethod filter_by_date(col, start_date, end_date)[source]#
Narrow
datain place tostart_date..end_dateoncol.- Parameters:
- colstr
The date column or dimension to filter on.
- start_datestr
First date to keep, inclusive.
- end_datestr
Last date to keep, inclusive.
Examples
>>> backend.filter_by_date("timestamp", "2024-01-02", "2024-01-03") XrBackend() >>> backend.data["timestamp"].values.astype("datetime64[D]") array(['2024-01-02', '2024-01-03'], dtype='datetime64[D]')
- abstractmethod filter_by_symbol(col, symbols)[source]#
Narrow
datain place to the rows whosecolis insymbols.- Parameters:
- colstr
The symbol column or dimension to filter on.
- symbolstuple[str, …]
The symbols to keep.
Examples
>>> backend.filter_by_symbol("symbol", ("BBB",)) XrBackend() >>> backend.data["symbol"].values.tolist() ['BBB']
- abstractmethod get_lazyframe()[source]#
Return the held data as a
polars.LazyFrame.Examples
>>> backend.get_lazyframe().collect().columns ['timestamp', 'symbol', 'close']
- abstractmethod get_xarray_dataset(indexes=None)[source]#
Return the held data as an
xarray.Dataset.- Parameters:
- indexeslist[str], optional
The dimensions the returned dataset must be indexed by, in order.
Noneasks for no particular shape.
Examples
>>> backend = XrBackend().to_internal(panel) >>> tuple(backend.get_xarray_dataset(["timestamp", "symbol"]).dims) ('timestamp', 'symbol')
- abstractmethod head(path, n)[source]#
Return at most
nrows from the store atpath.Implementations must not materialise the whole store, must not touch
data, and must raiseFileNotFoundErrorwhenpathdoes not exist rather than deferring the failure to a later collect.- Parameters:
- pathstr
Location of the store.
- nint
Maximum number of rows to return.
Examples
>>> XrBackend().head("prices.zarr", 2).collect().shape (2, 3)
- abstractmethod read(path, **kwargs)[source]#
Load the store at
pathintodataand returnself.- Parameters:
- pathstr
Location of the store.
- **kwargs
Options for the underlying reader.
Examples
>>> dict(XrBackend().read("prices.zarr").data.sizes) {'timestamp': 4, 'symbol': 2}
- abstractmethod resample(labels, how)[source]#
Aggregate
dataonto the coarser time gridlabelsdescribes.labelsmaps every source timestamp (its index) to the timestamp of the bar it belongs to (its value); the caller works those out, so the backend knows nothing about clocks or trading sessions.hownames oneResampleMethodfor every variable. Each variable is reduced over the timestamps sharing a label, NaN cells skipped, and the result replacesdatain place, sorted by the new timestamps.- Parameters:
- labelspd.Series
Source timestamp to target timestamp, covering every timestamp
dataholds.- howdict[str, str]
Variable name to aggregation method.
Examples
>>> labels = pd.Series(minutes.floor("D"), index=minutes) >>> backend.resample(labels, {"close": "last", "volume": "sum"}) >>> dict(backend.data.sizes) {'timestamp': 2, 'symbol': 3}