factrix.AnalysisConfig
dataclass
¶
AnalysisConfig(scope: FactorScope, signal: Signal, metric: Metric | None, forward_periods: int = 5, estimator: HACEstimator = NeweyWest(), moment_estimator: MomentEstimator | None = None)
Three-axis spec for a single-factor analysis.
Construct via the four factory methods (the supported public API);
direct construction works but bypasses no validation — every path
runs through __post_init__.
Attributes:
| Name | Type | Description |
|---|---|---|
scope |
FactorScope
|
Factor scope axis. |
signal |
Signal
|
Signal type axis. |
metric |
Metric | None
|
Procedure metric axis. Only populated for
|
forward_periods |
int
|
Forward-return horizon in rows of the
panel's time axis, not calendar time. factrix never
inspects |
factrix.AnalysisConfig.individual_continuous
classmethod
¶
individual_continuous(*, metric: Metric = IC, forward_periods: int = 5, estimator: HACEstimator | None = None, moment_estimator: MomentEstimator | None = None) -> Self
Per-(date, asset) continuous factor.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
metric
|
Metric
|
|
IC
|
forward_periods
|
int
|
Forward-return horizon (rows of the time axis). |
5
|
estimator
|
HACEstimator | None
|
|
None
|
Returns:
| Type | Description |
|---|---|
Self
|
A validated |
Self
|
|
Examples:
>>> import factrix as fx
>>> cfg = fx.AnalysisConfig.individual_continuous(forward_periods=10)
>>> cfg.scope is fx.FactorScope.INDIVIDUAL
True
>>> cfg.signal is fx.Signal.CONTINUOUS
True
>>> cfg.metric is fx.Metric.IC
True
Switch metric to Fama-MacBeth λ:
factrix.AnalysisConfig.individual_sparse
classmethod
¶
individual_sparse(*, forward_periods: int = 5, estimator: HACEstimator | None = None, moment_estimator: MomentEstimator | None = None) -> Self
Per-(date, asset) sparse trigger ({-1, 0, +1}).
PANEL canonical procedure is the CAAR cross-event t-test; TIMESERIES (N=1) collapses to a dummy regression with Newey-West (NW) heteroskedasticity-and-autocorrelation-consistent (HAC) SE.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
forward_periods
|
int
|
Forward-return horizon (rows of the time axis). |
5
|
estimator
|
HACEstimator | None
|
|
None
|
Returns:
| Type | Description |
|---|---|
Self
|
A validated |
Self
|
|
Examples:
factrix.AnalysisConfig.common_continuous
classmethod
¶
common_continuous(*, forward_periods: int = 5, estimator: HACEstimator | None = None, moment_estimator: MomentEstimator | None = None) -> Self
Broadcast continuous factor (e.g. VIX).
Canonical procedure is the per-asset β estimate followed by a
cross-asset t-test on E[β].
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
forward_periods
|
int
|
Forward-return horizon (rows of the time axis). |
5
|
estimator
|
HACEstimator | None
|
|
None
|
Returns:
| Type | Description |
|---|---|
Self
|
A validated |
Self
|
|
Examples:
factrix.AnalysisConfig.common_sparse
classmethod
¶
common_sparse(*, forward_periods: int = 5, estimator: HACEstimator | None = None, moment_estimator: MomentEstimator | None = None) -> Self
Broadcast sparse trigger (FOMC, policy, index rebalance).
PANEL canonical: per-asset β on dummy + cross-asset t-test. TIMESERIES (N=1): TS dummy regression + Newey-West (NW) heteroskedasticity-and-autocorrelation-consistent (HAC) SE.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
forward_periods
|
int
|
Forward-return horizon (rows of the time axis). |
5
|
estimator
|
HACEstimator | None
|
|
None
|
Returns:
| Type | Description |
|---|---|
Self
|
A validated |
Self
|
|
Examples:
factrix.AnalysisConfig.to_dict ¶
Serialise to a JSON-compatible dict.
Returns:
| Type | Description |
|---|---|
dict[str, Any]
|
A dict with string-valued enums and integer |
dict[str, Any]
|
|
factrix.AnalysisConfig.from_dict
classmethod
¶
Reconstruct from to_dict's output.
Goes through __post_init__, so an invalid triple raises
IncompatibleAxisError instead of silently constructing.
estimator is rehydrated via factrix.stats.get_estimator
registry lookup; missing key falls back to the NeweyWest()
default for forward compatibility with v0.11 serialized configs.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
d
|
dict[str, Any]
|
Mapping in the shape produced by |
required |
Returns:
| Type | Description |
|---|---|
Self
|
A validated |
Raises:
| Type | Description |
|---|---|
IncompatibleAxisError
|
If the |
UnknownEstimatorError
|
If |
Use cases¶
-
Selecting a dispatch cell
Pick the factory whose
(scope, signal, metric)tuple matches your factor — see Choosing a factory below. Construct → pass toevaluate. -
Switching inference within a cell
Same factory, different
estimator=(e.g.HansenHodrick()instead of the defaultNeweyWest()) to swap the heteroskedasticity-and-autocorrelation-consistent (HAC) kernel. -
Persisting an analysis spec
Use
to_dict/from_dictto cache the config alongside results, or to keep a backtest reproducible after a code change. -
Failing fast on illegal cells
Every construction path runs
__post_init__. An illegal(scope, signal, metric)triple raisesIncompatibleAxisErrorat construction time, not atevaluatetime.
Choosing a factory¶
| Your factor | Factory | Resulting cell |
|---|---|---|
| Per-asset real-valued signal, want rank information coefficient (IC) | individual_continuous(metric=Metric.IC) |
(INDIVIDUAL, CONTINUOUS, IC) |
| Per-asset real-valued signal, want FM λ premium | individual_continuous(metric=Metric.FM) |
(INDIVIDUAL, CONTINUOUS, FM) |
Per-asset {0, R} event trigger (event flag or signed magnitude) |
individual_sparse() |
(INDIVIDUAL, SPARSE, None) |
| Broadcast real-valued factor (e.g. VIX) | common_continuous() |
(COMMON, CONTINUOUS, None) |
| Broadcast event dummy (FOMC, index rebalance) | common_sparse() |
(COMMON, SPARSE, None) |
Direct construction (AnalysisConfig(scope=..., signal=..., metric=...))
also works and runs the same validation, but the factories are the
documented public surface. Bypassing them buys nothing.
Worked example — construct, evaluate, inspect the cell¶
Build a config, evaluate, read the cell tuple back from the profile
import factrix as fx
cfg = fx.AnalysisConfig.individual_continuous(
metric=fx.Metric.IC, forward_periods=5,
)
print(cfg)
# AnalysisConfig(scope=<FactorScope.INDIVIDUAL>, signal=<Signal.CONTINUOUS>,
# metric=<Metric.IC>, forward_periods=5, ...)
profile = fx.evaluate(panel, cfg)
print(profile.diagnose()["cell"])
# {'scope': 'individual', 'signal': 'continuous', 'metric': 'ic', 'mode': 'panel'}
Illegal cells fail at construction:
# (COMMON, SPARSE, IC) is not a registered cell — Metric.IC is only legal
# for INDIVIDUAL × CONTINUOUS.
fx.AnalysisConfig(
scope=fx.FactorScope.COMMON,
signal=fx.Signal.SPARSE,
metric=fx.Metric.IC,
)
# IncompatibleAxisError: (common, sparse, ic) is not a legal analysis cell.
# Use one of the four factory methods:
# AnalysisConfig.individual_continuous(metric=Metric.IC|Metric.FM)
# AnalysisConfig.individual_sparse()
# AnalysisConfig.common_continuous()
# AnalysisConfig.common_sparse()
Persistence — round-trip via dict¶
to_dict / from_dict exist for caching configs alongside results and
keeping a backtest replayable across code revisions.
Serialise to JSON and rehydrate via from_dict
import json
cfg = fx.AnalysisConfig.individual_continuous(metric=fx.Metric.FM)
payload = cfg.to_dict()
# {'scope': 'individual', 'signal': 'continuous', 'metric': 'fm',
# 'forward_periods': 5, 'estimator': 'newey_west', 'moment_estimator': None}
with open("cfg.json", "w") as f:
json.dump(payload, f)
# ... later, possibly a different process / commit ...
with open("cfg.json") as f:
restored = fx.AnalysisConfig.from_dict(json.load(f))
assert restored == cfg
from_dict runs the same __post_init__ validation as the factories, so
a tampered or stale payload raises
IncompatibleAxisError or
UnknownEstimatorError up front rather
than failing silently later.
See also¶
-
evaluate— entry-point function
The function that consumes a validated
AnalysisConfigand returns aFactorProfile. -
Concepts — three-axis taxonomy
Scope × Signal × Metricaxes and the legal-cell lattice. -
Statistical methods
Per-cell procedure rationale and SE conventions.
-
list_estimators
Enumerate HAC / moment estimators applicable to a given
(scope, signal). -
suggest_config
Recommend the nearest legal config from panel shape; the recovery path for
MissingConfigErrorfromevaluate.