factrix.list_metrics ¶
list_metrics(scope: FactorScope, signal: Signal, *, format: Literal['text', 'json'] = 'text', with_import: bool = False) -> list[str] | list[dict[str, Any]]
Return standalone metrics applicable to (scope, signal).
Mode is intentionally not an input — applicability does not change
across PANEL / TIMESERIES (per docs/reference/metric-applicability.md).
Source of truth is the Matrix-row: tag in each metric module's
docstring, parsed by :mod:factrix._metric_index.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
scope
|
FactorScope
|
Cell axis to filter on ( |
required |
signal
|
Signal
|
Cell axis to filter on ( |
required |
format
|
Literal['text', 'json']
|
|
'text'
|
with_import
|
bool
|
|
False
|
Raises:
| Type | Description |
|---|---|
IncompatibleAxisError
|
|
Notes
Filter input_kind == "panel" on the JSON form to find
candidates for the date-slicing dispatcher
:func:factrix.by_slice; "scalar" rows
(breakeven_cost, net_spread) consume pre-aggregated
scalars and are not eligible.
Examples:
Discover standalone metrics for an INDIVIDUAL × CONTINUOUS cell:
>>> import factrix as fx
>>> names = fx.list_metrics(
... fx.FactorScope.INDIVIDUAL, fx.Signal.CONTINUOUS,
... )
JSON form (for tooling — adds module / cell / import_path keys):
Programmatic discovery of standalone metrics applicable to a given
analysis cell. Complements describe_analysis_modes — that helper enumerates the
primary procedure per cell (IC / FM / CAAR / TS-β); list_metrics
returns the full set of standalone callables under
factrix.metrics that the user can additionally
invoke once evaluate() has produced a FactorProfile.
Mode axis is not an input¶
Mode is intentionally not a parameter — applicability does not
change across PANEL / TIMESERIES (see
Metric applicability for the
underlying matrix). See the docstring Examples block above for the
canonical text-list and JSON-form calls.
Discover-then-import workflow¶
Pass with_import=True to render a copy-paste-ready two-column view
that pairs each metric with its submodule path:
print("\n".join(fx.list_metrics(
fx.FactorScope.INDIVIDUAL, fx.Signal.CONTINUOUS, with_import=True,
)))
# ic → factrix.metrics.ic
# ic_ir → factrix.metrics.ic
# fama_macbeth → factrix.metrics.fama_macbeth
# breakeven_cost → factrix.metrics.tradability
# ...
Every name on the right is also re-exported from factrix.metrics,
so the canonical wire-up is always:
The submodule path is shown so you know where the implementation
lives — useful when reading source, jumping in an IDE, or checking
the module-level Matrix-row: tag.
Structured output for tooling¶
fx.list_metrics(
fx.FactorScope.INDIVIDUAL,
fx.Signal.CONTINUOUS,
format="json",
)
# -> [
# {
# "name": "ic",
# "module": "ic",
# "cell": "(INDIVIDUAL, CONTINUOUS, IC, PANEL)",
# "agg_order": "cs-first",
# "inference_se": "NW HAC / cross-asset t",
# "import_path": "factrix.metrics.ic",
# "input_kind": "panel",
# },
# ...
# ]
The JSON form is the single-source-of-truth row produced by parsing
the Matrix-row: tag in each metric module's docstring (the same
parser MkDocs uses to render
the cross-metric matrix). Keys:
| Key | Meaning |
|---|---|
name |
Function name as exported under factrix.metrics |
module |
Submodule stem (e.g. ic, fama_macbeth) |
cell |
Raw cell string from the Matrix-row: tag |
agg_order |
Aggregation order (cs-first, ts-first, ts-only, static-cs, per-event) |
inference_se |
Inference / SE method or no formal H₀ for descriptive metrics |
import_path |
Fully-qualified submodule (factrix.metrics.<module>) — also re-exported from factrix.metrics |
input_kind |
"panel" for the standard (date-keyed DataFrame, **kwargs) -> MetricOutput contract; "scalar" for pre-aggregated-scalar utilities |
panel vs scalar — and why it matters¶
Most metrics take a date-keyed DataFrame as their first positional
argument; a few (breakeven_cost, net_spread in
factrix.metrics.tradability) consume pre-aggregated scalars
(gross_spread: float, turnover: float, …) and return a
MetricOutput directly. The date-slicing dispatcher
by_slice only accepts the panel shape — there is
no date column in a scalar to slice on.
Filter the JSON output to enumerate by_slice-eligible metrics:
panel_metrics = [
r for r in fx.list_metrics(
fx.FactorScope.INDIVIDUAL, fx.Signal.CONTINUOUS, format="json",
)
if r["input_kind"] == "panel"
]
Errors¶
IncompatibleAxisError is raised when (scope, signal) matches no
registered metric. All four real combinations are populated, so this
is defensive — surfaced for symmetry with the rest of the API.
Source of truth¶
list_metrics and the docs matrix share one parser
(factrix._metric_index). Adding a new metric only requires adding a
Matrix-row: tag to the new module's docstring; both surfaces pick it
up automatically.