factrix.EvaluationResult
dataclass
¶
EvaluationResult(factor: str, cell: tuple[FactorScope, FactorDensity, DataStructure], forward_periods: int, n_periods: int, n_pairs: int, n_assets: int, metrics: Mapping[str, MetricResult], plan: str, params: Mapping[str, Hashable] = dict(), metadata: Mapping[str, Any] = dict(), warnings: list[Warning] = list())
Bundle-level result for one factor.
Attributes:
| Name | Type | Description |
|---|---|---|
factor |
str
|
Factor column name from the source panel. |
cell |
tuple[FactorScope, FactorDensity, DataStructure]
|
|
forward_periods |
int
|
The data's overlap horizon — read from the panel's
|
n_periods |
int
|
Number of unique dates in the factor panel where the factor column is non-null. A panel structural property — independent of any individual metric's estimator. |
n_pairs |
int
|
Number of non-null |
n_assets |
int
|
Unique assets in the panel (cell-invariant;
|
metrics |
Mapping[str, MetricResult]
|
Read-only |
params |
Mapping[str, Hashable]
|
Caller-supplied hypothesis parameters — the sweep knobs
that decide which hypothesis this result is (e.g.
|
metadata |
Mapping[str, Any]
|
Caller-supplied bookkeeping labels that do not define
the hypothesis (e.g. |
warnings |
list[Warning]
|
Flat list of :class: |
plan |
str
|
Multi-line DAG execution plan (topological order,
|
unexpected_warnings
property
¶
unexpected_warnings: list[Warning]
Warnings the caller did not declare via expected_warnings.
The alert view for pipelines and humans: :attr:warnings is the
complete record (declared regimes included, flagged
expected=True); this subset is what still deserves attention.
metric ¶
metric(label: str) -> MetricResult
Return the :class:MetricResult for label.
Convenience over result.metrics[label] — the same lookup with a
message that lists the available labels on a miss, so a typo in an
interactive session fails loudly instead of with a bare KeyError.
to_dict ¶
JSON-friendly nested dict view.
Layout (top-level keys, stable order):
factor/cell/forward_periods/n_periods/n_pairs/n_assets/params/metadatametrics:label -> {value, p_value, alternative, stat, n_obs, n_obs_axis, is_applicable, reason, metadata}warnings: list of{code, source, message, expected}plan
Float NaN / Inf are emitted as None.
to_frame ¶
One row per produced metric, prefixed with bundle identity.
Schema (column order is stable):
| column | dtype | source |
|---|---|---|
factor |
str | :attr:factor |
n_assets |
i64 | :attr:n_assets |
metric_name |
str | MetricResult.name |
value |
f64 | null | MetricResult.value |
p_value |
f64 | null | MetricResult.p_value |
alternative |
str | null | MetricResult.alternative |
stat |
f64 | null | MetricResult.stat |
n_obs |
i64 | null | MetricResult.n_obs — estimator effective sample size |
n_obs_axis |
str | null | MetricResult.n_obs_axis — axis n_obs counts along (periods / events / pairs / assets) |
is_applicable |
bool | false for strict=False short-circuits |
reason |
str | null | short-circuit reason when not applicable |
warning_codes |
list[str] | per-metric warning codes |
Designed for stacking across factors:
pl.concat([r.to_frame() for r in results.values()])
Serialization Methods¶
EvaluationResult provides two main methods to serialize evaluation outputs:
to_frame()¶
Converts the metric results into a stable, long-form Polars pl.DataFrame. This makes it easy to stack results across multiple factors using pl.concat([r.to_frame() for r in results]) before writing to disk (e.g., Parquet).
Schema:
- factor (str): The factor column name.
- n_assets (i64): Total unique assets.
- metric_name (str): The metric identifier.
- value (f64 | null): The calculated metric value (NaN/Inf are normalized to null).
- p_value (f64 | null): The p-value, if applicable.
- alternative (str | null): The tested alternative (two-sided, greater, or less), present exactly when p_value is present.
- stat (f64 | null): The underlying test statistic, if applicable.
- n_obs (i64 | null): Effective sample size the metric's estimator used. null only where a single integer count is not meaningful (e.g. a multi-window CAAR series).
- n_obs_axis (str | null): The dimension n_obs counts along — periods / events / pairs / assets. A bare count is uninterpretable without it (a Fama-MacBeth n_obs is periods; a pooled-OLS one is (date, asset) pairs). null exactly when n_obs is.
- is_applicable (bool): false when strict=False returned a short-circuit placeholder for an unsupported metric/input combination.
- reason (str | null): Short-circuit reason when is_applicable is false.
- warning_codes (list[str]): List of warnings attached to the metric.
to_dict()¶
Converts the result into a JSON-friendly nested dictionary. It normalizes floats (e.g., NaN and Inf to None) so that it can be serialized directly using standard json.dumps without raising errors.
The metrics mapping¶
EvaluationResult.metrics is a read-only Mapping[str, MetricResult] (a MappingProxyType) keyed by the caller-supplied metric label, including short-circuit NaN outputs. Access it like any dict — result.metrics["ic"] returns the MetricResult for "ic", and keys() / values() / items() / get() / in / len() / iteration all work as usual. The mapping is immutable; attempting to assign into it raises TypeError.
result.metric("ic") is a convenience over result.metrics["ic"]: the same lookup, but a miss raises KeyError listing the available labels (no metric 'sharpe' on this result; available: ic, ic_ir) instead of a bare key — handy in interactive sessions where a typo would otherwise fail opaquely.
factrix.MetricResult
dataclass
¶
MetricResult(value: float, p_value: float | None = None, alternative: PValueAlternative | None = None, n_obs: int | None = None, n_obs_axis: SampleAxis | None = None, stat: float | None = None, metadata: dict[str, object] = dict(), warning_codes: tuple[str, ...] = (), name: str = '')
Single-metric result produced by a factrix.metrics.* primitive.
Attributes:
| Name | Type | Description |
|---|---|---|
value |
float
|
Raw metric value. |
p_value |
float | None
|
P-value for the metric's hypothesis test. |
alternative |
PValueAlternative | None
|
Alternative-hypothesis direction used to construct
|
n_obs |
int | None
|
Effective sample size the estimator actually used
(e.g. number of non-overlapping IC periods, number of
events, number of bootstrap windows). |
n_obs_axis |
SampleAxis | None
|
Sample dimension |
stat |
float | None
|
Test statistic (t, z, W, chi2, ...), when applicable. |
metadata |
dict[str, object]
|
Estimator-specific context beyond the top-level fields
( |
warning_codes |
tuple[str, ...]
|
Per-metric advisory :class: |
name |
str
|
Metric name stamped by the DAG executor at dispatch time. Empty string for outputs constructed outside the registry. |
is_applicable
property
¶
Whether the metric produced a usable result for this input.
strict=False short-circuits unsupported metrics into placeholder
outputs with metadata["reason"]. This flag lets reporting and
grid-search code filter those rows without relying on metadata shape.
reason
property
¶
Stable short-circuit reason, when the metric did not run cleanly.
Key Fields¶
MetricResult represents the outcome of a single metric calculation. Its primary fields are:
value(float): The calculated numeric output of the metric.p_value(float|None): The calibrated statistical p-value. It must be finite and in[0, 1].alternative(str|None): The corresponding alternative hypothesis (two-sided,greater, orless).p_valueandalternativemust either both be present or both beNone. > [!IMPORTANT] >p_valueis the canonical field for metric p-values.stat(float|None): The test statistic (e.g. t-statistic, z-statistic).n_obs(int|None): Effective sample size the estimator used in this specific metric calculation.n_obs_axis(str|None): Sample dimensionn_obscounts along — one ofperiods/events/pairs/assets. Stamped by the producer alongsiden_obs;Noneexactly whenn_obsis.is_applicable(bool):Falseforstrict=Falseshort-circuit placeholders, so reporting code can filter them without inspectingmetadata["reason"].reason(str|None): Stable short-circuit reason, copied frommetadata["reason"]when present.metadata(dict): Underlying dictionary of metric-specific metadata.warning_codes(tuple[str, ...]): Advisory warnings attached to the metric.name(str): The name of the metric, automatically populated during dispatch.
factrix.Warning
dataclass
¶
Warning(code: WarningCode, source: str | None = None, message: str = '', expected: bool = False)
Flat per-evaluation diagnostic record.
Source convention: a per-metric warning carries
source == <metric label>; a panel-level / cross-metric warning
carries source is None.
Attributes:
| Name | Type | Description |
|---|---|---|
code |
WarningCode
|
The :class: |
source |
str | None
|
Metric label that emitted the warning, or |
message |
str
|
Human-readable detail. |
expected |
bool
|
|
Fields¶
A Warning object represents a warning emitted during data inspection or metric evaluation:
code(WarningCode): The enum identifier for the warning type (e.g.WarningCode.UNRELIABLE_SE_SHORT_PERIODS).source(str|None): The name of the metric that generated the warning. If the warning is data-level or cross-metric,sourceisNone.message(str): A human-readable detail message describing the issue.