quantlab.backend.ranged.RangedStore#
- class quantlab.backend.ranged.RangedStore(path, owner, compute, *, guard=None, fill_values=None)[source]#
Bases:
objectA store written by date range, the range recorded beside it.
- Parameters:
- pathstr or None
The Zarr store.
Nonewhen the config names none: every method butstore_rangethen refuses.- ownerstr
What the store is called in error and timer messages: a factor’s class name (
"Momentum"), a risk model’sClass.part("Use4RiskModel.regression").- computecallable
compute(start, end)returning the rows of the range, both inclusive, as anxr.Datasetontimestamp(and its other axes). It reads its own warm-up.- guardcallable, optional
guard(method)raises when the store may not be written (methodis"build"or"extend"); it runs before anything is computed or written. A factor’s owner rule (ADR 0029).- fill_valuesmapping, optional
Per-variable fill values for cells a widening creates (see
XrBackend.widen_and_append).
- Attributes:
- store_pathstr or None
As
path.- ownerstr
As given.
Examples
>>> import numpy as np, pandas as pd, xarray as xr >>> def compute(start, end): ... times = pd.bdate_range(start, end) ... return xr.Dataset( ... {"x": (("timestamp", "symbol"), np.ones((len(times), 2)))}, ... coords={"timestamp": times, "symbol": ["a", "b"]}, ... ) >>> store = RangedStore("rows.zarr", "Rows", compute) >>> store.build("2024-01-01", "2024-01-10") >>> store.store_range() ('2024-01-01', '2024-01-10') >>> store.check_covers("2024-01-02", "2024-01-11") Traceback (most recent call last): ValueError: Rows.read(): the store at rows.zarr covers 2024-01-01 to 2024-01-10, which does not contain 2024-01-02 to 2024-01-11. Extend it with extend(end) or rebuild it with build(start, end).
- RANGE_SUFFIX = '.range.json'#
Appended to the store’s path to name the file recording its range.
- append(rows, end)[source]#
Append
rows, the bars after the recorded range up toend, and move its end.The write half of
extend, for rows computed elsewhere. Emptyrows(no bar in the range) only move the end.- Raises:
- ValueError
As
extendable_range.
Examples
>>> store.append(compute("2024-01-08", "2024-01-10"), "2024-01-10") >>> store.store_range() ('2024-01-01', '2024-01-10')
- build(start, end)[source]#
Compute
starttoendand write it as the store, recording the range.The store and its recorded range are replaced.
- Parameters:
- start, endstr, datetime.date or pd.Timestamp
The range the store covers.
- Raises:
- ValueError
If the store has no path, or the guard refuses the write.
Examples
>>> store.build("2024-01-01", "2024-01-10") >>> store.store_range() ('2024-01-01', '2024-01-10')
- check_covers(start, end)[source]#
Raise unless the recorded range contains
starttoend: a read’s refusals.- Parameters:
- start, endstr, datetime.date or pd.Timestamp
The range a reader asks for. A date-only
endincludes every bar of that day.
- Raises:
- ValueError
If the store has no path or no recorded range, or the recorded range does not contain the request.
Examples
>>> store.check_covers("2024-01-02", "2024-01-09") # inside: nothing happens >>> store.check_covers("2024-01-02", "2024-01-11") Traceback (most recent call last): ValueError: Rows.read(): the store at rows.zarr covers 2024-01-01 to 2024-01-10, ...
- extend(end)[source]#
Append the rows after the recorded range, up to
end, and move its end.The rows are computed from the first moment after the recorded end, so they are warmed from the inputs’ history; the store’s axes widen to fit.
- Parameters:
- endstr, datetime.date or pd.Timestamp
The new end of the store’s range.
- Raises:
- ValueError
As
extendable_range.
Examples
>>> store.extend("2024-01-31") >>> store.store_range() ('2024-01-01', '2024-01-31')
- extendable_range(end)[source]#
Return the recorded range, refusing an
extendtoend.- Raises:
- ValueError
If the store has no path, the guard refuses the write, the store has no recorded range, or the recorded range already reaches
end.
Examples
>>> store.extendable_range("2024-01-31") ('2024-01-01', '2024-01-10') >>> store.extendable_range("2024-01-05") Traceback (most recent call last): ValueError: Rows.extend(): the store at rows.zarr already covers 2024-01-01 to 2024-01-10; ...
- property range_path#
The file recording the store’s range,
<path>.range.json.Examples
>>> RangedStore("rows.zarr", "Rows", compute).range_path PosixPath('rows.zarr.range.json')
- rewind(end)[source]#
Drop the bars after
endand end the recorded range there: the inverse ofextend.The bars up to
endstay as they are, and the symbol and variable axes keep every label, so the nextextendcomputes the dropped bars again. The range is recorded first, then the store’s time axis shortened in place (XrBackend.shorten_axis): a rewind killed between the two leaves bars past the recorded end, which no read reaches and the nextextenddrops before it appends.- Parameters:
- endstr, datetime.date or pd.Timestamp
The new end of the store’s range, inside it and before its end.
- Raises:
- ValueError
If the store has no path, the guard refuses the write, the store has no recorded range,
endis not before the recorded end, orendis before the recorded start.
Examples
>>> store.build("2024-01-01", "2024-01-31") >>> store.rewind("2024-01-15") >>> store.store_range() ('2024-01-01', '2024-01-15') >>> store.rewind("2024-01-15") Traceback (most recent call last): ValueError: Rows.rewind(): the store at rows.zarr covers 2024-01-01 to 2024-01-15; ...
- store_range()[source]#
Return the
(start, end)the store was built for;Nonewhen none is recorded.Examples
>>> store.build("2024-01-01", "2024-01-10") >>> store.store_range() ('2024-01-01', '2024-01-10')
- write(rows, start, end)[source]#
Replace the store with
rows, computed overstarttoend, and record the range.The write half of
build, for rows computed elsewhere (a chunk computed in a worker process).- Raises:
- ValueError
If the store has no path, or the guard refuses the write.
Examples
>>> store.write(compute("2024-01-01", "2024-01-05"), "2024-01-01", "2024-01-05") >>> store.store_range() ('2024-01-01', '2024-01-05')