Walk-forward validation utilities for time-series ML: splits, purge/embargo, and evaluation helpers.
Project description
wfv-toolkit (wfvkit)
A tiny Python toolkit for walk-forward validation of time-ordered data with purge + embargo utilities to reduce label leakage (useful for trading/finance ML and any temporal prediction setup).
What you get
-
Naive time split (baseline):
naive_time_split -
Walk-forward splits (rolling windows):
walk_forward_splits -
Leakage guards
purge_overlap(train_idx, test_idx)— removes training indices that overlap the test windowembargo_after(test_idx, embargo)— blocks samples immediately after the test window
-
A runnable example:
examples/demo_naive_vs_purged.py -
Tests:
pytest
The core idea is common in financial ML: if labels use a forward horizon, nearby samples can “bleed” information between train/test. Purge and embargo help.
Install
Option A: from PyPI (recommended)
pip install wfvkit
Option B: editable install (development)
python -m venv .venv
.\.venv\Scripts\python.exe -m pip install -U pip
.\.venv\Scripts\python.exe -m pip install -e ".[dev]"
Option C: install from GitHub tag
pip install "git+https://github.com/Mohsentinal/wfv-toolkit.git@v0.1.3"
Quickstart
Minimal example
import datetime as dt
from wfvkit import (
naive_time_split,
walk_forward_splits,
purge_overlap,
embargo_after,
)
# 10 timestamps (toy example)
times = [dt.datetime(2025, 1, 1, 0, 0) + dt.timedelta(minutes=i) for i in range(10)]
# 1) naive split: pass an index cutoff OR a datetime cutoff
train_idx, test_idx = naive_time_split(times, train_end=6)
train_idx2, test_idx2 = naive_time_split(times, train_end=times[6])
print("naive_idx:", train_idx, test_idx)
print("naive_dt :", train_idx2, test_idx2)
# 2) walk-forward splits (rolling windows)
splits = list(walk_forward_splits(times, train_size=5, test_size=2, step=2, embargo=1))
print("splits:", splits)
# 3) purge + embargo helpers
tr, te = splits[0]
print("purged:", purge_overlap(tr, te))
print("embargo:", sorted(embargo_after(te, embargo=1)))
Run tests
.\.venv\Scripts\python.exe -m pytest -q
Run the demo
.\.venv\Scripts\python.exe examples\demo_naive_vs_purged.py
Usage
Import the public API
from wfvkit import (
naive_time_split,
walk_forward_splits,
purge_overlap,
embargo_after,
)
Naive split (baseline)
import datetime as dt
times = [dt.datetime(2025, 1, 1) + dt.timedelta(minutes=i) for i in range(10)]
# Cut by index
train_idx, test_idx = naive_time_split(times, train_end=6)
# Or cut by datetime
train_idx2, test_idx2 = naive_time_split(times, train_end=times[6])
Walk-forward splits + purge + embargo
import datetime as dt
times = [dt.datetime(2025, 1, 1) + dt.timedelta(minutes=i) for i in range(50)]
for train_idx, test_idx in walk_forward_splits(
times,
train_size=20,
test_size=5,
step=5,
embargo=2,
):
train_purged = purge_overlap(train_idx, test_idx)
embargo_idx = embargo_after(test_idx, embargo=2)
# Fit on `train_purged`, evaluate on `test_idx`,
# and avoid using indices in `embargo_idx` for training.
Concepts (plain English)
Purge
If a sample in train overlaps the test interval, it can leak information. Purging removes those overlapping training indices.
Embargo
Even after the test window ends, samples immediately after can still be contaminated if labels depend on future horizons. Embargo blocks a small number of samples after the test window.
Project layout
wfv-toolkit/
src/wfvkit/
__init__.py
splits.py
leakage.py
metrics.py
evaluate.py
tests/
examples/
Roadmap (next nice upgrades)
- Add purged k-fold / combinatorial purged CV
- Add utilities for event-based labels (start/end times per sample)
- Add richer evaluation helpers (rolling metrics and robustness checks)
- Provide a small CLI (optional)
License
MIT (see LICENSE).
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file wfvkit-0.1.7.tar.gz.
File metadata
- Download URL: wfvkit-0.1.7.tar.gz
- Upload date:
- Size: 10.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d1c31b9fab264b1ef143529a9d3d89f1d82a3b832ebd6e03108319fbe886daec
|
|
| MD5 |
90a316965cb911bf6bb119190ffdcd9b
|
|
| BLAKE2b-256 |
b3fa45d111a8f1b18dde97af76225caffb5b07f7b903f405efbde2670ff462d3
|
File details
Details for the file wfvkit-0.1.7-py3-none-any.whl.
File metadata
- Download URL: wfvkit-0.1.7-py3-none-any.whl
- Upload date:
- Size: 6.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dc823defe9992046c2aec387ffd0904048382702d740d0294e7d88a0bc7c827e
|
|
| MD5 |
a381b1550c56b732a3b9050022505000
|
|
| BLAKE2b-256 |
215851df2360b87b3bc43a08a69e4be97bb299ee73c5f97ed2420ccc724cf918
|