quantlab.runs.record#

The run record: what a run read and which code it ran.

A run is reproducible from its config, its data and its code. This module records the last two and compares them with an earlier run’s record. Its interface:

  • DataRecorder, the context a run opens to learn what it read, and record_read, which the read seams (BaseDataset.panel, Factor.read and a factor risk model’s RiskStore.read) call; unrecorded hides reads from every open recorder;

  • code_record and code_of, the code a component tree ran;

  • compare, which compares two provenance records ({"data_fingerprint": ..., "code": ...}) and logs one warning per difference.

Data. Stores are appended to and adjusted prices are re-based retroactively, so a stored run is reproducible only if the data under it has not changed. Inside an open recorder a read is logged as a request (dataset, the first and last bar read, symbols, variables); outside one record_read returns at once. When the recorder closes, each distinct request is read again once and hashed: the time range, the axis sizes and a sha256 digest over the values of the variables read. NaN has many bit patterns, so every NaN is rewritten to one canonical NaN and every -0.0 to 0.0 before hashing; otherwise two reads of identical data could report different digests. The records are compared with an expected record when one is given, by digest alone.

Code. code_record records, for one component tree, the git commit of the quantlab repository (and whether its tracked files had uncommitted changes), a sha256 digest of the source file of every module that defines a class of the tree, and the versions of the libraries whose behaviour decides a run’s numbers. A quantlab module outside the shipped implementations is a framework module: each layer’s root class and extension framework, such as quantlab.factor.polars or quantlab.portfolio.decision_inputs. Every other recorded module is a component module: the shipped implementations (quantlab.<layer>.predefined, the datasets of quantlab.dataset, whose base, config and _support are framework) and a user’s own classes. Standard-library and installed third-party modules are not recorded, nor a class without a source file (one defined in a notebook); the libraries’ versions are. dirty reports uncommitted changes to tracked files only; git is None when quantlab is not imported from a git working tree. A code comparison compares module digests and library versions; the git commit is context only.

Nothing here raises on a difference: a run on changed data or code still runs.

Classes

DataRecorder

Record the data a run reads, hash it once per request, compare on close.

Functions

code_of

Return the code record of root and every component under it.

code_record

Return the code record of a component tree.

compare

Compare two provenance records, logging one warning per difference.

record_read

Log a read of source to the innermost open recorder, if there is one.

unrecorded

Keep the reads inside out of every open recorder, and hash nothing.