0
# Generic Time Series Tools
1
2
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.
3
4
## Core Imports
5
6
```python
7
from vectorbt.generic import Ranges, Drawdowns
8
from vectorbt.generic import RangeSplitter, RollingSplitter, ExpandingSplitter
9
```
10
11
## Capabilities
12
13
### Range Analysis
14
15
Analysis of value ranges and patterns in time series data with support for custom range definitions and statistics.
16
17
```python { .api }
18
class Ranges:
19
"""
20
Range analysis for time series data.
21
22
Identifies and analyzes ranges in time series data with support
23
for various range definitions and statistical measures.
24
"""
25
26
@classmethod
27
def from_ts(cls, ts, **kwargs):
28
"""
29
Create ranges from time series.
30
31
Parameters:
32
- ts: pd.Series or pd.DataFrame, time series data
33
- range_func: callable, function to identify ranges
34
- range_args: tuple, arguments for range function
35
36
Returns:
37
Ranges: Range analysis instance
38
"""
39
40
@property
41
def start_idx(self):
42
"""Range start indices."""
43
44
@property
45
def end_idx(self):
46
"""Range end indices."""
47
48
@property
49
def status(self):
50
"""Range status codes."""
51
52
def count(self, **kwargs):
53
"""Count ranges by column."""
54
55
def duration(self, **kwargs):
56
"""Range durations."""
57
58
def coverage(self, **kwargs):
59
"""Time coverage percentage."""
60
```
61
62
### Drawdown Analysis
63
64
Comprehensive drawdown analysis with peak detection, valley identification, and recovery tracking.
65
66
```python { .api }
67
class Drawdowns:
68
"""
69
Drawdown analysis for time series data.
70
71
Identifies drawdown periods, calculates drawdown statistics,
72
and provides recovery analysis capabilities.
73
"""
74
75
@classmethod
76
def from_ts(cls, ts, **kwargs):
77
"""
78
Create drawdowns from time series.
79
80
Parameters:
81
- ts: pd.Series or pd.DataFrame, time series data
82
- incl_active: bool, include active drawdowns
83
84
Returns:
85
Drawdowns: Drawdown analysis instance
86
"""
87
88
@property
89
def start_idx(self):
90
"""Drawdown start indices."""
91
92
@property
93
def valley_idx(self):
94
"""Valley (lowest point) indices."""
95
96
@property
97
def end_idx(self):
98
"""Drawdown end indices."""
99
100
@property
101
def start_val(self):
102
"""Starting values."""
103
104
@property
105
def valley_val(self):
106
"""Valley values."""
107
108
@property
109
def end_val(self):
110
"""Ending values."""
111
112
def max_drawdown(self, **kwargs):
113
"""Maximum drawdown percentage."""
114
115
def avg_drawdown(self, **kwargs):
116
"""Average drawdown percentage."""
117
118
def avg_duration(self, **kwargs):
119
"""Average drawdown duration."""
120
121
def recovery_factor(self, **kwargs):
122
"""Recovery factor calculation."""
123
```
124
125
### Data Splitting
126
127
Advanced data splitting strategies for backtesting, cross-validation, and time series analysis with various splitting methods.
128
129
```python { .api }
130
class RangeSplitter:
131
"""
132
Range-based data splitting.
133
134
Splits data into ranges based on custom criteria for analysis
135
and validation purposes.
136
"""
137
138
def __init__(self, n_splits, **kwargs):
139
"""
140
Initialize range splitter.
141
142
Parameters:
143
- n_splits: int, number of splits to create
144
- range_len: int, length of each range
145
- set_lens: tuple, lengths for train/test sets
146
"""
147
148
def split(self, X, **kwargs):
149
"""
150
Split data into ranges.
151
152
Parameters:
153
- X: pd.Series or pd.DataFrame, data to split
154
155
Yields:
156
tuple: (train_indices, test_indices) for each split
157
"""
158
159
class RollingSplitter:
160
"""
161
Rolling window data splitting.
162
163
Creates rolling windows for time series cross-validation
164
with configurable train/test window sizes.
165
"""
166
167
def __init__(self, n_splits, **kwargs):
168
"""
169
Initialize rolling splitter.
170
171
Parameters:
172
- n_splits: int, number of splits
173
- train_len: int, training window length
174
- test_len: int, testing window length
175
- step: int, step size between splits
176
"""
177
178
def split(self, X, **kwargs):
179
"""Split data using rolling windows."""
180
181
class ExpandingSplitter:
182
"""
183
Expanding window data splitting.
184
185
Creates expanding windows where training set grows while
186
maintaining fixed test set size.
187
"""
188
189
def __init__(self, n_splits, **kwargs):
190
"""
191
Initialize expanding splitter.
192
193
Parameters:
194
- n_splits: int, number of splits
195
- min_train_len: int, minimum training length
196
- test_len: int, testing window length
197
"""
198
199
def split(self, X, **kwargs):
200
"""Split data using expanding windows."""
201
```
202
203
## Usage Examples
204
205
### Drawdown Analysis
206
207
```python
208
import vectorbt as vbt
209
import pandas as pd
210
211
# Create sample portfolio returns
212
returns = pd.Series([0.01, -0.02, 0.03, -0.05, 0.02, 0.01])
213
cumulative_returns = (1 + returns).cumprod()
214
215
# Analyze drawdowns
216
drawdowns = vbt.Drawdowns.from_ts(cumulative_returns)
217
218
# Get maximum drawdown
219
max_dd = drawdowns.max_drawdown()
220
print(f"Maximum drawdown: {max_dd:.2%}")
221
222
# Analyze drawdown periods
223
print(f"Number of drawdowns: {drawdowns.count()}")
224
print(f"Average drawdown duration: {drawdowns.avg_duration()}")
225
```
226
227
### Range Analysis
228
229
```python
230
# Analyze ranges in price data
231
price = vbt.YFData.download("AAPL")["Close"]
232
ranges = vbt.Ranges.from_ts(price, range_func=vbt.generic.nb.range_func_nb)
233
234
# Get range statistics
235
print(f"Number of ranges: {ranges.count()}")
236
print(f"Average range duration: {ranges.duration().mean()}")
237
print(f"Time coverage: {ranges.coverage():.2%}")
238
```
239
240
### Cross-Validation Splitting
241
242
```python
243
# Set up rolling window cross-validation
244
splitter = vbt.RollingSplitter(
245
n_splits=5,
246
train_len=252, # 1 year training
247
test_len=63 # 3 months testing
248
)
249
250
# Split data for backtesting
251
price = vbt.YFData.download("AAPL")["Close"]
252
for train_idx, test_idx in splitter.split(price):
253
train_data = price.iloc[train_idx]
254
test_data = price.iloc[test_idx]
255
256
# Run strategy on train/test splits
257
# ... backtesting code here
258
```
259
260
### Expanding Window Analysis
261
262
```python
263
# Use expanding window for walk-forward analysis
264
splitter = vbt.ExpandingSplitter(
265
n_splits=10,
266
min_train_len=252,
267
test_len=21
268
)
269
270
results = []
271
for train_idx, test_idx in splitter.split(price):
272
# Train strategy on expanding window
273
# Test on fixed forward period
274
pass
275
```
276
277
## Types
278
279
```python { .api }
280
# Range status enumeration
281
from vectorbt.generic.enums import RangeStatus
282
283
class RangeStatus(IntEnum):
284
Open = 0
285
Closed = 1
286
287
# Drawdown status enumeration
288
from vectorbt.generic.enums import DrawdownStatus
289
290
class DrawdownStatus(IntEnum):
291
Active = 0
292
Recovered = 1
293
```