Source code for numeraire.core.schema
"""The standard tidy, long-format result schema.
Every evaluator emits rows in this schema; downstream plotting (plotnine / R) consumes it,
so the plotting choice stays decoupled. Stability is promised on this schema (semver).
"""
from __future__ import annotations
import pandas as pd
RESULT_COLUMNS: tuple[str, ...] = (
"run_id",
"method",
"date",
"metric",
"value",
"universe",
"capability",
"protocol",
"config_hash",
"data_vintage",
)
"""Minimum columns every result table must carry (in any order).
``protocol`` labels the evaluation discipline the row was produced under: ``"walk_forward"`` (the
framework's out-of-sample walk-forward path, which every weights/forecast evaluator emits) or
``"in_sample"`` (a single full-sample fit, the paper cross-sectional-pricing tradition). It makes an
explanatory in-sample number unconfusable with an out-of-sample one.
"""
[docs]
def validate_result(df: pd.DataFrame) -> None:
"""Raise ``ValueError`` if ``df`` is missing any required result-schema column.
Extra columns are allowed; only the presence of :data:`RESULT_COLUMNS` is enforced.
"""
present = {str(c) for c in df.columns}
missing = [c for c in RESULT_COLUMNS if c not in present]
if missing:
raise ValueError(f"result table missing required columns: {missing}")