factrix.inference ¶
Curated inference methods for tests on a per-period series mean.
NON_OVERLAPPING strides the series, NEWEY_WEST applies a Bartlett-
kernel HAC variance to the full series, and STATIONARY_BOOTSTRAP resamples
blocks from the full series. Each member exposes the same compute contract
and returns an :class:InferenceResult containing the tested alternative,
p-value, estimate, sample size, diagnostics, and warnings.
The inference= parameter is intentionally a closed, per-metric allowlist.
It is available on ic, quantile_spread, quantile_spread_vw, and
k_spread; other metrics use an estimator fixed by their statistical shape.
Passing a method outside a metric's allowlist raises
:class:~factrix.IncompatibleInferenceError rather than falling back.
HansenHodrick is available only from factrix.inference.series_mean for
standalone comparisons. Its rectangular kernel has no positive-semidefinite
guarantee, so no registered metric admits it.
See Inference selection for why the union is closed and what the per-metric allowlist records, Statistical methods for selection guidance, and the calibration reference for measured regimes and known limits.
Inference ¶
Bases: Protocol
Statistical inference method identity.
Implementations are frozen dataclasses that additionally carry a
compute whose signature is fixed per target shape (series-mean
members share compute(data, *, value_col, overlap_periods,
alternative="two-sided")).
compute is intentionally absent here — see module docstring.
InferenceResult
dataclass
¶
InferenceResult(stat: float, p_value: float, alternative: PValueAlternative, metadata: Mapping[str, Any], warnings: frozenset[WarningCode], estimate: float | None = None, n_obs: int | None = None)
Harmonized return shape for an Inference.compute call.
stat / p_value are the test statistic and its requested-tail p-value;
alternative names that tail on the same result, and all three feed a
MetricResult directly. metadata is a flat
str -> Any map (non-overlapping emits stride / sample counts;
Newey-West emits newey_west_lags). warnings carries soft-floor /
kernel-clamp signals.
NeweyWest
dataclass
¶
Newey-West HAC t-test on the full series with a Bartlett kernel.
The bandwidth uses the LLSW (2018) 1.3·√T rule, floored
at 3(h - 1) and capped at T/3. The variance is scaled by
T/(T - L - 1), and the statistic uses effective degrees of freedom
bounded by T/h - 1. All three are derived from the input sample, so
this class carries no lag parameter; the resolved bandwidth and degrees of
freedom are reported as metadata["newey_west_lags"] and
metadata["hac_dof"].
This method retains observations that NonOverlapping drops, but it is
not uniformly more powerful or better calibrated. Persistence that remains
after striding at overlap_periods raises
WarningCode.SERIAL_CORRELATION_DETECTED. See the statistical-methods
and inference-calibration references for selection guidance and measured
limits.
min_input_periods ¶
Minimum input series length (periods) below which the HAC t-test cannot run.
NonOverlapping
dataclass
¶
Non-overlapping stride subsample inference: OLS t-test on every overlap_periods-th observation.
Sub-samples the cleaned series at a stride equal to overlap_periods
to break the MA(h-1) autocorrelation that overlapping h-period forward
returns induce (Hansen-Hodrick 1980), then runs
a textbook OLS t-test on the survivors. The most conservative
overlap-aware path — it discards h-1 of every h observations rather
than correcting the SE; NeweyWest is the less-lossy HAC
alternative on the full series.
min_input_periods ¶
Minimum input series length (periods): need base · h rows to land base after striding.
StationaryBootstrap
dataclass
¶
Stationary-bootstrap empirical-p inference on a series mean.
Resamples geometric-length blocks (Politis-Romano 1994)
from the series, centred under \(H_0: \mathbb{E}[x] = 0\), and reports the
empirical p-value from a studentized bootstrap-t root. Block length is
selected automatically per Politis-White (2004) and
cannot be shorter than overlap_periods. This is a second read for an
adequately long, stationary series with distributional doubt; it is not a
short-sample or strong-persistence remedy.
Metadata records the resolved block length, seed, usable resample count,
and Monte Carlo standard error. If studentization is impossible, the method
uses a raw-mean root and raises WarningCode.DEGENERATE_VARIANCE. See the
inference-calibration reference for measured limits.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_resamples
|
int
|
Number of bootstrap draws. Must be at least
|
999
|
rng
|
Rng
|
An |
None
|
min_input_periods ¶
Minimum input series length (periods); no overlap-specific floor.
Direct compute result¶
Every series-mean member has the same direct-call shape:
from datetime import date, timedelta
import numpy as np
import polars as pl
from factrix.inference import NEWEY_WEST
data = pl.DataFrame(
{
"date": [date(2024, 1, 1) + timedelta(days=i) for i in range(60)],
"value": np.linspace(-0.1, 0.2, 60),
}
)
result = NEWEY_WEST.compute(
data,
value_col="value",
overlap_periods=5,
alternative="greater",
)
assert result.alternative == "greater"
Direct calls require a non-null Polars Date or Datetime column named
date, exactly one observation per date, a numeric column named by value_col,
and a positive integer overlap_periods. Missing or non-numeric value columns
raise UserInputError. If the source contains multiple observations in one
period, aggregate them explicitly before calling compute; factrix does not
guess whether mean, last, or another reduction represents the series.
InferenceResult.p_value is always paired with
InferenceResult.alternative, which is the validated "two-sided",
"greater", or "less" tail passed to the statistical kernel. Read these
two fields together; metadata contains method-specific diagnostics such as
bandwidth, effective degrees of freedom, or bootstrap seed.