combinatorial_purged_cv¶
Defined in fynance.data
- combinatorial_purged_cv(T, n_groups=6, n_test_groups=2, purge=0, embargo=0)[source]
Generate combinatorial purged cross-validation (CPCV) folds.
A single walk-forward path (or a plain purged K-fold) gives exactly one out-of-sample (OOS) performance estimate, so its variance from the particular split chosen is never measured – a lucky or unlucky path looks identical to a robust one. CPCV instead splits
[0, T)inton_groupscontiguous groups and, for every combination ofn_test_groupsgroups held out as test, purges/embargoes the remainder and yields it as one train/test fold. That producesn_splits = math.comb(n_groups, n_test_groups)folds – versus the single path ofwalk_forward– whose paths can be reassembled into many distinct OOS return series, turning one backtest into a distribution of OOS Sharpe ratios (and letting one estimate the probability of backtest overfitting, PBO).- Parameters:
- Tint
Number of observations.
- n_groupsint, optional
Number of contiguous groups to split
[0, T)into (sizes as equal as possible; any remainder bars go to the first groups, i.e. the same convention asnumpy.array_split). Default 6.- n_test_groupsint, optional
Number of groups held out as test in each fold. Default 2.
- purgeint, optional
Number of bars removed from train on both sides of every test group’s boundary (immediately before its start and immediately after its end), so that no train observation straddles a test boundary. Default 0.
- embargoint, optional
Number of bars additionally removed from train immediately after each test group’s end (beyond
purge), to absorb serial correlation that would otherwise leak test information forward into a subsequent train block. Default 0.
- Yields:
- (train_idx, test_idx)tuple of numpy.ndarray
Sorted, unique
int64index arrays, same convention aswalk_forward.test_idxis the union of the chosen test groups;train_idxis every other index minus the purge/embargo windows.
- Raises:
- ValueError
If
n_test_groupsis not strictly between0andn_groups, or ifn_groupsexceedsT(a group would then be empty).
See also
train_test_split,walk_forward
Notes
Combinations are generated in the deterministic order of
itertools.combinationsapplied torange(n_groups). By a standard counting argument, each of then_groupsgroups appears in the test set of exactlymath.comb(n_groups - 1, n_test_groups - 1)of themath.comb(n_groups, n_test_groups)folds.References
[1]Lopez de Prado, M. (2018). Advances in Financial Machine Learning. Wiley. Chapter 7, “Cross-Validation in Finance”.
Examples
>>> import math >>> folds = list(combinatorial_purged_cv(12, n_groups=4, n_test_groups=1, purge=1)) >>> len(folds) == math.comb(4, 1) True >>> train_idx, test_idx = folds[0] >>> test_idx array([0, 1, 2]) >>> train_idx # bar 3 purged (1 bar after the test group's end) array([ 4, 5, 6, 7, 8, 9, 10, 11])