numeraire.testing#
Conformance suite — a reusable check_estimator any method self-certifies against.
Extension authors (in numeraire-zoo, numeraire-yourlab, or a standalone
numeraire-<method> package) run check_estimator() on their estimator to prove it is a
well-behaved framework citizen before wiring it into the engine. It is the sklearn-style
analogue of sklearn.utils.estimator_checks.check_estimator: plain functions that raise
AssertionError on the first violation, no base class to inherit.
This module is core infrastructure, not a method — it is exempt from the boundary rule’s
methods/adapters import ban (it lives in numeraire proper, not numeraire.core, and imports
only numeraire.core + numpy/pandas). It knows the two concrete core view types
(TimeSeriesView, CrossSectionView) so
the no-look-ahead check can build a future-perturbed twin generically.
The checks#
Given an estimator and a deterministic view_factory (a zero-arg callable returning an
equivalent view each call — synthetic data with a fixed seed):
check_capabilities()—fitreturns aModelwhosecapabilities()intersect the core set{to_weights, to_forecast, to_pricing}, and every crystallized capability it declares has its method (to_weights/forecast/expected_returns).check_output_shapes()— weights columns ⊆view.assetsand index ⊆view.calendar(wide) or a[date, asset]MultiIndex (panel); a forecast is apd.Seriesindexed byview.assets; pricingexpected_returnsis a(date x asset)frame with columns ⊆view.assetsand index ⊆view.calendar.check_determinism()— same estimator + same view ⇒ identical output, twice.check_no_lookahead()— the property test for ``to_weights`` and ``expected_returns``. Both hand the model a multi-date view and require it to window internally, so its rows up totmust be invariant to mutating data strictly after ``t``; a model that peeks past a prediction date fails here (one leak channel, shared by a weight stream and a priced cross-section).to_forecastis deliberately not probed: the forecast-origin engine only ever handsforecast()a prefix-truncatedview.window(origin), so a forecast at origindis structurally incapable of seeing data afterd— perturbing the future can’t change it, so a probe here can never fail (it would be dead code). That PIT guarantee is exercised where a leak actually surfaces: the zoo’s mandatory engine ≡ vectorized equality test, where a contemporaneous / off-by-one forecast leak makes the hand-written full-sample path disagree with the prefix-truncated engine path (seetests/test_testing.pyfor the mechanism).check_engine_roundtrip()— the estimator runs through the matching walk-forward driver without error and an evaluator emits rows conforming to the result schema.
A pricing method (to_pricing, e.g. an IPCA adapter) now exercises the full suite: its
expected_returns surface is crystallized, so the shape, determinism, no-look-ahead, and
engine-round-trip checks all apply to it exactly as they do to a weights method.
Run the full conformance suite; raise |
|
|
|
Weights/forecast outputs obey the shape contracts (columns ⊆ assets; forecast index). |
|
Same estimator + same (deterministic) view ⇒ bit-identical extractable output, twice. |
|
|
|
The estimator runs through its matching walk-forward driver; result rows validate. |