Backtest paths¶
Reconstruct CPCV predictions and summarise return paths. Predictions are not returns. Define the strategy and its costs before applying return metrics. See splitters for CPCV and statistical metrics for Sharpe inference.
purgedcv.PathMetricFn
module-attribute
¶
A path metric: maps one path's 1-D return series to a name -> value mapping.
Pass this callback as metric_fn to path_metrics.
Each mapping key becomes a column in the result. The default callback is
default_backtest_metrics; supply your
own to choose different statistics or a different return convention.
purgedcv.reconstruct_paths ¶
reconstruct_paths(fold_predictions: Sequence[NDArrayAny], fold_test_indices: Sequence[NDArrayAny], n_splits: int, n_test_groups: int, n_samples: int) -> NDArrayAny
Assemble Combinatorial Purged CV fold predictions into backtest paths.
Given the predictions and test indices for all C(N, K) folds produced by
CombinatorialPurgedCV, returns a (n_paths, n_samples) array
where each row is a complete time-ordered out-of-sample prediction
sequence built from a different combination of the folds.
n_paths = C(n_splits - 1, n_test_groups - 1). Each sample is
predicted in every path (no missing entries). The assignment of fold
to path for each group is the canonical greedy positional rule: for
group g, the k-th fold (in fold-iteration order) that contains
g as a test group contributes g's predictions to path k.
NaN predictions in any fold propagate only to the paths that use that fold for the affected group(s).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
fold_predictions
|
Sequence[NDArrayAny]
|
One array per fold; |
required |
fold_test_indices
|
Sequence[NDArrayAny]
|
One array per fold; the per-fold test_idx as
yielded by |
required |
n_splits
|
int
|
Number of CPCV group blocks. |
required |
n_test_groups
|
int
|
Number of test groups per fold. |
required |
n_samples
|
int
|
Total number of samples in the dataset. |
required |
Returns:
| Type | Description |
|---|---|
NDArrayAny
|
|
Raises:
| Type | Description |
|---|---|
ValueError
|
on fold count or fold-prediction length mismatch. |
Examples:
>>> import numpy as np
>>> from purgedcv import reconstruct_paths
>>> # Synthetic 4-fold output: 4 samples per fold's test set,
>>> # predictions equal to the fold index.
>>> fold_test = [
... np.array([0, 1, 2, 3, 4, 5, 6, 7]), # combo (0, 1)
... np.array([0, 1, 2, 3, 8, 9, 10, 11]), # combo (0, 2)
... np.array([0, 1, 2, 3, 12, 13, 14, 15]), # combo (0, 3)
... np.array([4, 5, 6, 7, 8, 9, 10, 11]), # combo (1, 2)
... np.array([4, 5, 6, 7, 12, 13, 14, 15]), # combo (1, 3)
... np.array([8, 9, 10, 11, 12, 13, 14, 15]), # combo (2, 3)
... ]
>>> fold_preds = [
... np.full(len(ti), float(f)) for f, ti in enumerate(fold_test)
... ]
>>> paths = reconstruct_paths(fold_preds, fold_test, 4, 2, 16)
>>> paths.shape
(3, 16)
purgedcv.path_metrics ¶
path_metrics(paths: NDArrayAny, metric_fn: PathMetricFn | None = None, *, bars_per_year: int | None = None) -> pd.DataFrame
Reduce an (n_paths, n_samples) matrix to per-path metrics.
Applies metric_fn to each row and stacks the results into a
DataFrame with one row per path and one column per metric.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
paths
|
NDArrayAny
|
|
required |
metric_fn
|
PathMetricFn | None
|
Maps a 1-D path to a name -> value mapping. Defaults to
|
None
|
bars_per_year
|
int | None
|
Forwarded to |
None
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
DataFrame indexed |
DataFrame
|
one column per metric. With the default |
DataFrame
|
|
DataFrame
|
drawdown), so the worst path is |
DataFrame
|
|
Raises:
| Type | Description |
|---|---|
ValueError
|
if |
Examples:
purgedcv.default_backtest_metrics ¶
Summarise one path of per-period returns.
Non-finite entries (for example NaN from a fold that could not be fit) are dropped before the statistics are computed. A path with fewer than two finite returns yields all-NaN metrics.
Returns are treated as additive (equity curve = cumulative sum), the convention for log returns. For simple returns supply a custom metric.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
NDArrayAny
|
1-D per-period return series. |
required |
bars_per_year
|
int | None
|
If given, the Sharpe ratio is annualised by
|
None
|
Returns:
| Type | Description |
|---|---|
dict[str, float]
|
Dict with |
dict[str, float]
|
|
dict[str, float]
|
signed value: |
dict[str, float]
|
|
dict[str, float]
|
|
Examples: