Cross-validation that respects the clock
Cross-validation reuses the data: it cuts it into folds, tests on one fold and trains on the rest. For independent rows that works, but financial labels overlap in time. If the label of row is the return from to , its window is . A test fold that covers rows to has labels covering . Any training row whose window touches that range, which means , shares returns with the test labels. Keeping such rows lets the model see part of the answer.
Purging removes the overlapping training rows. An embargo removes a further stretch of rows after the test fold, because returns are autocorrelated and volatility clusters, so the first rows after a test block still carry information about it. In a walk-forward scheme training only comes before the test, and the same idea becomes a gap: train on rows up to , so the gap is (plus ). scikit-learn's TimeSeriesSplit has a gap argument for this. On the monthly stock panel with , the walk-forward information coefficient is with no embargo and with months of embargo: the cleaning changes little because the label overlap is short, but you cannot know that without doing it.
- Purge, then embargo: drop training rows whose labels touch the test labels, then a few more after the test.
- A gap in walk-forward: train only on rows at least before the test.
- Do it even if it changes little: a clean evaluation costs a few rows, a leak can cost a strategy.
Lab · what's graded
- Rows purged before the fold10 pts
- Rows purged after the fold15 pts
- The training size that remains15 pts
- A walk-forward fold with a gap10 pts
- Which rows are purged10 pts
- A purged split10 pts
- Match the vocabulary15 pts
- Why an embargo as well15 pts