Features
Time-series cross-validation
Validate strategies across rolling, expanding, split, and purged time windows
✅ Added support for walk-forward cross-validation (CV) with purging, as well as combinatorial CV with purging and embargoing, based on Marcos Lopez de Prado's Advances in Financial Machine Learning.
splitter = vbt.Splitter.from_purged_kfold(
vbt.date_range("2024", "2025"),
n_folds=10,
n_test_folds=2,
purge_td="3 days",
embargo_td="3 days"
)
splitter.plots().show()✅ Most cross-validation tasks involve testing a grid of parameter combinations on the training data, selecting the best parameter combination, and validating it on the test data. This process must be repeated for each split. The cross-validation decorator combines the parameterized and split decorators to automate this task.
@vbt.cv_split(
splitter="from_rolling",
splitter_kwargs=dict(length=365, split=0.5, set_labels=["train", "test"]),
takeable_args=["data"],
parameterized_kwargs=dict(random_subset=100, seed=42),
merge_func="concat"
)
def sma_crossover_cv(data, fast_period, slow_period, metric):
fast_sma = data.run("sma", fast_period, hide_params=True)
slow_sma = data.run("sma", slow_period, hide_params=True)
entries = fast_sma.real_crossed_above(slow_sma)
exits = fast_sma.real_crossed_below(slow_sma)
pf = vbt.PF.from_signals(data, entries, exits, direction="both")
return pf.deep_getattr(metric)
sma_crossover_cv(
vbt.YFData.pull("BTC-USD", start="4 years ago"),
vbt.Param(np.arange(20, 50), condition="x < slow_period"),
vbt.Param(np.arange(20, 50)),
"trades.expectancy"
)split set fast_period slow_period
0 train 20 25 8.015725
test 20 23 0.573465
1 train 40 48 -4.356317
test 39 40 5.666271
2 train 24 45 18.253340
test 22 36 111.202831
3 train 20 31 54.626024
test 20 25 -1.596945
4 train 25 48 41.328588
test 25 30 6.620254
5 train 26 32 7.178085
test 24 29 4.087456
6 train 22 23 -0.581255
test 22 31 -2.494519
dtype: float64Tutorial
Learn more in the Cross-validation tutorial.
✅ Normally, to run a function on each split, you need to build a splitter specifically targeted at the input data provided to the function. This means that each time the input data changes, you must recreate the splitter. The split decorator automates this process by wrapping the function, giving it access to all arguments so it can make splitting decisions as needed. Essentially, it can "infect" any Python function with splitting functionality 🦠
@vbt.split(
splitter="from_grouper",
splitter_kwargs=dict(by="Q"),
takeable_args=["data"],
merge_func="concat"
)
def get_quarter_return(data):
return data.returns.vbt.returns.total()
data = vbt.YFData.pull("BTC-USD")
get_quarter_return(data.loc["2021"])Date
2021Q1 1.005805
2021Q2 -0.407050
2021Q3 0.304383
2021Q4 -0.037627
Freq: Q-DEC, dtype: float64get_quarter_return(data.loc["2022"])Date
2022Q1 -0.045047
2022Q2 -0.572515
2022Q3 0.008429
2022Q4 -0.143154
Freq: Q-DEC, dtype: float64Tutorial
Learn more in the Cross-validation tutorial.
✅ Splitters in scikit-learn are not ideal for validating ML-based
and rule-based trading strategies. VBT provides a juggernaut class that supports many splitting
schemes that are safe for backtesting, including rolling windows, expanding windows, time-anchored windows,
random windows for block bootstraps, and even Pandas-native groupby and resample instructions such as
"M" for monthly frequency. As a bonus, the produced splits can be easily analyzed and
visualized! For example, you can detect any split or set overlaps, convert all splits into a single
boolean mask for custom analysis, group splits and sets, and analyze their distribution relative to each other.
This class contains more lines of code than the entire backtesting.py
package, so do not underestimate the new king in town! 🦏
data = vbt.YFData.pull("BTC-USD", start="4 years ago")
splitter = vbt.Splitter.from_rolling(
data.index,
length="360 days",
split=0.5,
set_labels=["train", "test"],
freq="daily"
)
splitter.plots().show()Tutorial
Learn more in the Cross-validation tutorial.
Copyright © 2021–2026 Oleg Polakow. All rights reserved.
Site content and documentation are provided for using and evaluating VectorBT PRO and for educational purposes. Any other use, including building or supporting competing products or services, requires prior written consent.