numeraire#
A research framework providing a stable bedrock for backtesting, comparing, and replicating empirical asset-pricing and financial-econometrics methods.
The numéraire is the reference unit against which all prices are measured. The framework’s core stays representation-agnostic: it defines capabilities — what a model can produce (portfolio weights, return forecasts, a priced cross-section) — never a specific method’s internal form. Linear-factor, nonlinear, neural, and distributional methods are therefore all first-class citizens, and each plugs into the same point-in-time views, the same walk-forward out-of-sample engine, and the same tidy result schema.
Three ideas organise the whole framework:
- Point-in-time views
A
TimeSeriesVieworCrossSectionViewaligns returns and predictors on an explicit calendar and hands a model only the information available at each decision date. Look-ahead bias is made structurally difficult rather than left to author discipline.- Capabilities
A model advertises what it can produce —
TO_WEIGHTS,TO_FORECAST,TO_PRICING— and the engine and evaluators dispatch on those capabilities. The metric always matches the object.- The boundary rule
numeraire.coredepends on no specific method, and every method depends on core. Methods, adapters, and reference libraries never leak into the spine. The rule is enforced in CI byimport-linter.
Installation#
pip install numeraire
The base install is the spine plus the native evaluators; the companion packages and optional
integrations live behind extras (numeraire[all], [graphics], [data], [skfolio]). See
Installation for the full matrix.
A first backtest#
import numpy as np
import pandas as pd
from numeraire import SharpeEvaluator, TimeSeriesView, WalkForwardSplitter, backtest
from numeraire.baselines import EqualWeight
rng = np.random.default_rng(0)
dates = pd.date_range("2000-01-31", periods=120, freq="ME")
returns = pd.DataFrame(rng.normal(0.01, 0.05, (120, 4)), index=dates, columns=list("ABCD"))
view = TimeSeriesView(returns)
result = backtest(EqualWeight(), view, WalkForwardSplitter(min_train=60, test_size=12),
method="equal_weight")
print(SharpeEvaluator().evaluate(result)[["method", "metric", "value", "protocol"]])
Where to go next#
Getting Started — install and a runnable, end-to-end walk-through on synthetic data.
User Guide — the mental model: views, capabilities, the engine family, evaluators, the result schema, the simulator, and method comparison.
Extending: write your own method — write and self-certify your own method.
The ecosystem — the companion packages and how they fit together.
Related projects and scope — how numeraire relates to statsmodels, linearmodels, skfolio, and others.
API reference — the full API reference.