Skip to main content

numeraire

A research framework for backtesting, comparing, and replicating empirical asset-pricing and financial-econometrics methods.

PyPI Python versions CI Documentation License: BSD-3-Clause

Documentation · Quickstart · API Reference · PyPI · Citation


numeraire provides a stable, representation-agnostic spine for empirical asset pricing: a point-in-time data view, a walk-forward out-of-sample engine, a library of evaluators and statistical tests, and a tidy result schema. Its core never encodes a specific method's internal form — it defines capabilities (what a model can produce: portfolio weights, return forecasts, a priced cross-section), and dispatches on them. Linear-factor, nonlinear, neural, and distributional methods are therefore all first-class, and each plugs into the same views, the same engine, and the same schema as a peer.

The numéraire is the reference unit against which all prices are measured. The framework is oriented toward reproducible empirical asset pricing: results are produced out of sample, on a recorded data vintage, and scored with a metric matched to the model.

Why numeraire

Empirical asset-pricing results are sensitive to a few well-known failure modes: a signal that overlaps the return it predicts, a headline metric mismatched to the model, or preprocessing that is not recorded. numeraire is designed so these are addressed by the structure of the framework.

  • Out-of-sample by construction. A point-in-time view exposes only the data available at each decision date, and the walk-forward engine computes realised returns from the original data rather than from a model's output. A conformance test perturbs future data and verifies that earlier outputs do not change.
  • The metric matches the object. Evaluators dispatch on what a model produces — a timing strategy is scored by its Sharpe ratio, a return forecast by its out-of-sample R², a pricing model by its cross-sectional fit.
  • Every result carries its provenance. Each result row records the data vintage, a hash of the method and preprocessing configuration, and whether the number is in-sample or out-of-sample.

Underlying this, the core describes a model by its capabilities — the outputs it can produce (portfolio weights, return forecasts, a priced cross-section) — not by any specific internal form. Methods as different as linear factor models, neural predictors, and stochastic discount factors run through the same engine, evaluators, and result schema.

Installation

pip install numeraire

numeraire requires Python 3.11+. The base install is the spine plus the native evaluators; opt into the companion packages and integrations through extras:

pip install "numeraire[all]"        # + the plotting and data companion packages
pip install "numeraire[graphics]"   # + numeraire-graphics (grammar-of-graphics figures)
pip install "numeraire[data]"       # + numeraire-dataset (data loaders and builders)
pip install "numeraire[skfolio]"    # + the skfolio portfolio-optimizer adapter

Using uv:

uv add numeraire            # or: uv add "numeraire[all]"

Quickstart

Build a point-in-time view, run a walk-forward out-of-sample backtest, and evaluate it — on synthetic data, no external source required:

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)
splitter = WalkForwardSplitter(min_train=60, test_size=12)
result = backtest(EqualWeight(), view, splitter, method="equal_weight")

print(SharpeEvaluator().evaluate(result)[["method", "metric", "value", "protocol"]])

backtest reads the fitted model's capability and the view type and dispatches to the right typed driver; SharpeEvaluator emits rows of the standard tidy schema. See the quickstart for the full walk-through, including a forecasting example.

The ecosystem

numeraire is the spine of a small, deliberately decoupled family of packages. The core ships only tiny public example slices and no bundled methods; everything else is an optional, first-class peer.

Package Role Install
numeraire The spine: views, engine, evaluators, result schema, statistical tests. pip install numeraire
numeraire-graphics Grammar-of-graphics figures over the result schema and Output objects. pip install numeraire-graphics
numeraire-dataset Open, reproducible data loaders and point-in-time builders. pip install numeraire-dataset

Reproductions of published methods, and a lab's own unpublished methods, live in separate packages that register through the numeraire.methods entry-point group and pin numeraire — they are discovered at install time without any edit to core. A public reproduction collection is in preparation.

What you can do with it

  • Research — reproduce a published result within a tolerance band, and compare competing pricing models on one shared panel of test assets in the Fama–French / GRS tradition, with the corresponding significance tests.
  • Backtesting — construct portfolios and score them out of sample, turn a target-weight stream into realised net returns through an accounting simulator with explicit cost conventions, and evaluate with risk-adjusted, information-coefficient, and exposure measures.

Documentation

Full documentation — installation, a runnable quickstart, the architecture, the extension guide, and the API reference — is at https://numeraire.py-numeraire.org/.

How to cite

If you use numeraire in your research, a citation is appreciated. The repository ships a CITATION.cff (GitHub renders a Cite this repository button from it), and the equivalent BibTeX is:

@software{wu_numeraire,
  author  = {Wu, Yuheng},
  title   = {{numeraire: a research framework for backtesting, comparing,
             and replicating empirical asset-pricing methods}},
  year    = {2026},
  version = {0.2.1},
  url     = {https://github.com/py-numeraire/numeraire},
  license = {BSD-3-Clause}
}

Contributing

Contributions to the spine — evaluators, statistical tests, and engine or view improvements — are welcome. Methods are distributed as separate packages rather than added to core: a method is any object with fit(view) -> model that advertises a capability, registered through the numeraire.methods entry point and self-certified with numeraire.testing.check_estimator (see the extension guide).

Development uses uv, ruff, basedpyright (strict on core), and import-linter for the architecture boundary:

uv sync --extra dev
uv run ruff check . && uv run ruff format --check .
uv run basedpyright src/numeraire/core     # strict types on the spine
uv run lint-imports                        # architecture boundary
uv run pytest                              # tests (public / synthetic data only)

License

BSD-3-Clause. Author: Yuheng Wu. Tests use public or synthetic data only; never commit CRSP / WRDS / proprietary data or credentials.

Metadata

Release files for numeraire 0.2.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for numeraire 0.2.2
File Size Uploaded Provenance Actions
numeraire-0.2.2.tar.gz 364.3 kB With provenance Details for numeraire-0.2.2.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for numeraire 0.2.2
File Interpreter ABI Platform Actions
numeraire-0.2.2-py3-none-any.whl Python 3 none any Details for numeraire-0.2.2-py3-none-any.whl

Total release size: 446.0 kB

Release files / numeraire-0.2.2.tar.gz

Download URL numeraire-0.2.2.tar.gz
Size 364.3 kB
Tags Source
SHA-256 checksum
How to use checksums
b9569c1916cb7ef0bc0c0d113f36440c9bb6f3923fb26d72a69903bcd4284133
BLAKE2b-256 checksum
How to use checksums
a5b93c32428ed070c37efbc69d00a7e94c8ba41a73ec95eb8c5ec5b651f3035e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 6, 2026.

Transparency log

Release files / numeraire-0.2.2-py3-none-any.whl

Download URL numeraire-0.2.2-py3-none-any.whl
Size 81.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2d4fd7e554b6ceab9489a734c11618a98db5d847eb8d57e3c64d07466bf42eea
BLAKE2b-256 checksum
How to use checksums
5de57fa88ec8928e9adcd8a437d666c68055d68a88965349f81ea1e33c946f93
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 6, 2026.

Transparency log

Security for numeraire 0.2.2

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for numeraire-0.2.2.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 6, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page