Python library for backtesting and analyzing trading strategies at scale
—
Advanced tools for time series analysis including range analysis, drawdown detection, and data splitting strategies for backtesting and cross-validation. The generic module provides foundational analysis capabilities used throughout VectorBT.
from vectorbt.generic import Ranges, Drawdowns
from vectorbt.generic import RangeSplitter, RollingSplitter, ExpandingSplitterAnalysis of value ranges and patterns in time series data with support for custom range definitions and statistics.
class Ranges:
"""
Range analysis for time series data.
Identifies and analyzes ranges in time series data with support
for various range definitions and statistical measures.
"""
@classmethod
def from_ts(cls, ts, **kwargs):
"""
Create ranges from time series.
Parameters:
- ts: pd.Series or pd.DataFrame, time series data
- range_func: callable, function to identify ranges
- range_args: tuple, arguments for range function
Returns:
Ranges: Range analysis instance
"""
@property
def start_idx(self):
"""Range start indices."""
@property
def end_idx(self):
"""Range end indices."""
@property
def status(self):
"""Range status codes."""
def count(self, **kwargs):
"""Count ranges by column."""
def duration(self, **kwargs):
"""Range durations."""
def coverage(self, **kwargs):
"""Time coverage percentage."""Comprehensive drawdown analysis with peak detection, valley identification, and recovery tracking.
class Drawdowns:
"""
Drawdown analysis for time series data.
Identifies drawdown periods, calculates drawdown statistics,
and provides recovery analysis capabilities.
"""
@classmethod
def from_ts(cls, ts, **kwargs):
"""
Create drawdowns from time series.
Parameters:
- ts: pd.Series or pd.DataFrame, time series data
- incl_active: bool, include active drawdowns
Returns:
Drawdowns: Drawdown analysis instance
"""
@property
def start_idx(self):
"""Drawdown start indices."""
@property
def valley_idx(self):
"""Valley (lowest point) indices."""
@property
def end_idx(self):
"""Drawdown end indices."""
@property
def start_val(self):
"""Starting values."""
@property
def valley_val(self):
"""Valley values."""
@property
def end_val(self):
"""Ending values."""
def max_drawdown(self, **kwargs):
"""Maximum drawdown percentage."""
def avg_drawdown(self, **kwargs):
"""Average drawdown percentage."""
def avg_duration(self, **kwargs):
"""Average drawdown duration."""
def recovery_factor(self, **kwargs):
"""Recovery factor calculation."""Advanced data splitting strategies for backtesting, cross-validation, and time series analysis with various splitting methods.
class RangeSplitter:
"""
Range-based data splitting.
Splits data into ranges based on custom criteria for analysis
and validation purposes.
"""
def __init__(self, n_splits, **kwargs):
"""
Initialize range splitter.
Parameters:
- n_splits: int, number of splits to create
- range_len: int, length of each range
- set_lens: tuple, lengths for train/test sets
"""
def split(self, X, **kwargs):
"""
Split data into ranges.
Parameters:
- X: pd.Series or pd.DataFrame, data to split
Yields:
tuple: (train_indices, test_indices) for each split
"""
class RollingSplitter:
"""
Rolling window data splitting.
Creates rolling windows for time series cross-validation
with configurable train/test window sizes.
"""
def __init__(self, n_splits, **kwargs):
"""
Initialize rolling splitter.
Parameters:
- n_splits: int, number of splits
- train_len: int, training window length
- test_len: int, testing window length
- step: int, step size between splits
"""
def split(self, X, **kwargs):
"""Split data using rolling windows."""
class ExpandingSplitter:
"""
Expanding window data splitting.
Creates expanding windows where training set grows while
maintaining fixed test set size.
"""
def __init__(self, n_splits, **kwargs):
"""
Initialize expanding splitter.
Parameters:
- n_splits: int, number of splits
- min_train_len: int, minimum training length
- test_len: int, testing window length
"""
def split(self, X, **kwargs):
"""Split data using expanding windows."""import vectorbt as vbt
import pandas as pd
# Create sample portfolio returns
returns = pd.Series([0.01, -0.02, 0.03, -0.05, 0.02, 0.01])
cumulative_returns = (1 + returns).cumprod()
# Analyze drawdowns
drawdowns = vbt.Drawdowns.from_ts(cumulative_returns)
# Get maximum drawdown
max_dd = drawdowns.max_drawdown()
print(f"Maximum drawdown: {max_dd:.2%}")
# Analyze drawdown periods
print(f"Number of drawdowns: {drawdowns.count()}")
print(f"Average drawdown duration: {drawdowns.avg_duration()}")# Analyze ranges in price data
price = vbt.YFData.download("AAPL")["Close"]
ranges = vbt.Ranges.from_ts(price, range_func=vbt.generic.nb.range_func_nb)
# Get range statistics
print(f"Number of ranges: {ranges.count()}")
print(f"Average range duration: {ranges.duration().mean()}")
print(f"Time coverage: {ranges.coverage():.2%}")# Set up rolling window cross-validation
splitter = vbt.RollingSplitter(
n_splits=5,
train_len=252, # 1 year training
test_len=63 # 3 months testing
)
# Split data for backtesting
price = vbt.YFData.download("AAPL")["Close"]
for train_idx, test_idx in splitter.split(price):
train_data = price.iloc[train_idx]
test_data = price.iloc[test_idx]
# Run strategy on train/test splits
# ... backtesting code here# Use expanding window for walk-forward analysis
splitter = vbt.ExpandingSplitter(
n_splits=10,
min_train_len=252,
test_len=21
)
results = []
for train_idx, test_idx in splitter.split(price):
# Train strategy on expanding window
# Test on fixed forward period
pass# Range status enumeration
from vectorbt.generic.enums import RangeStatus
class RangeStatus(IntEnum):
Open = 0
Closed = 1
# Drawdown status enumeration
from vectorbt.generic.enums import DrawdownStatus
class DrawdownStatus(IntEnum):
Active = 0
Recovered = 1Install with Tessl CLI
npx tessl i tessl/pypi-vectorbt