0
# Utilities & Configuration
1
2
Core utilities for configuration management, caching, plotting, template systems, and asynchronous operations. The utilities module provides the foundation for VectorBT's flexibility and extensibility.
3
4
## Capabilities
5
6
### Configuration Management
7
8
Comprehensive configuration system for managing global settings, caching behavior, and component-specific parameters.
9
10
```python { .api }
11
class Config:
12
"""
13
Configuration management class with dict-like interface.
14
15
Provides hierarchical configuration with validation, serialization,
16
and dynamic updates. Supports nested configurations and type checking.
17
"""
18
19
def __init__(self, config=None, **kwargs):
20
"""
21
Initialize configuration.
22
23
Parameters:
24
- config: dict, initial configuration values
25
- kwargs: additional configuration parameters
26
"""
27
28
def __getitem__(self, key):
29
"""Get configuration value."""
30
31
def __setitem__(self, key, value):
32
"""Set configuration value."""
33
34
def get(self, key, default=None):
35
"""Get configuration value with default."""
36
37
def update(self, other):
38
"""Update configuration from another config or dict."""
39
40
def copy(self):
41
"""Create a copy of the configuration."""
42
43
def reset(self):
44
"""Reset to default configuration."""
45
46
class Configured:
47
"""
48
Base class for configurable objects.
49
50
Provides automatic configuration inheritance and parameter management
51
for all VectorBT components.
52
"""
53
54
def __init__(self, **kwargs):
55
"""Initialize with configuration parameters."""
56
57
def configure(self, **kwargs):
58
"""Update configuration."""
59
60
def get_config(self):
61
"""Get current configuration."""
62
63
class AtomicConfig:
64
"""
65
Thread-safe configuration class.
66
67
Provides atomic operations for configuration updates in
68
multi-threaded environments.
69
"""
70
71
def __init__(self, config=None):
72
"""Initialize atomic configuration."""
73
74
def atomic_update(self, updates):
75
"""Atomically update multiple configuration values."""
76
77
# Global settings instance
78
vbt.settings: Config
79
```
80
81
### Caching System
82
83
Advanced caching mechanisms for performance optimization with automatic cache invalidation and memory management.
84
85
```python { .api }
86
class CacheCondition:
87
"""
88
Cache condition management for intelligent caching.
89
90
Determines when to cache results based on input parameters,
91
memory constraints, and computation complexity.
92
"""
93
94
def __init__(self, condition_func=None):
95
"""
96
Initialize cache condition.
97
98
Parameters:
99
- condition_func: callable, function determining cache eligibility
100
"""
101
102
def should_cache(self, *args, **kwargs):
103
"""Determine if result should be cached."""
104
105
def cached_property(func):
106
"""
107
Property caching decorator.
108
109
Caches property values on first access with automatic invalidation
110
when underlying data changes.
111
112
Parameters:
113
- func: callable, property getter function
114
115
Returns:
116
property: Cached property descriptor
117
"""
118
119
def cached_method(func):
120
"""
121
Method caching decorator.
122
123
Caches method results based on input parameters with intelligent
124
cache key generation and memory management.
125
126
Parameters:
127
- func: callable, method to cache
128
129
Returns:
130
callable: Cache-enabled method
131
"""
132
```
133
134
### Dictionary and Data Utilities
135
136
Utilities for data manipulation, merging, and atomic operations.
137
138
```python { .api }
139
def atomic_dict(*args, **kwargs):
140
"""
141
Create atomic dictionary for thread-safe operations.
142
143
Parameters:
144
- args: positional arguments for dict initialization
145
- kwargs: keyword arguments for dict initialization
146
147
Returns:
148
dict: Thread-safe atomic dictionary
149
"""
150
151
def merge_dicts(*dicts, **kwargs):
152
"""
153
Merge multiple dictionaries with conflict resolution.
154
155
Parameters:
156
- dicts: sequence of dictionaries to merge
157
- strategy: str, merge strategy ('override', 'keep_first', 'deep_merge')
158
- in_place: bool, modify first dictionary in place
159
160
Returns:
161
dict: Merged dictionary
162
"""
163
```
164
165
### Template System
166
167
Flexible template system for dynamic code generation and parameter substitution.
168
169
```python { .api }
170
class Sub:
171
"""
172
Template substitution class.
173
174
Provides framework for template-based code generation with
175
parameter validation and nested substitutions.
176
"""
177
178
def __init__(self, template, **kwargs):
179
"""
180
Initialize substitution template.
181
182
Parameters:
183
- template: str, template string with placeholders
184
- kwargs: substitution parameters
185
"""
186
187
def substitute(self, **kwargs):
188
"""Perform template substitution."""
189
190
class Rep:
191
"""
192
Template replacement class.
193
194
Advanced replacement system supporting conditional logic,
195
loops, and complex transformations.
196
"""
197
198
def __init__(self, pattern, replacement):
199
"""
200
Initialize replacement rule.
201
202
Parameters:
203
- pattern: str or regex, pattern to match
204
- replacement: str or callable, replacement value
205
"""
206
207
def apply(self, text):
208
"""Apply replacement to text."""
209
210
class RepEval:
211
"""
212
Evaluation-based replacement class.
213
214
Performs replacements based on evaluated expressions,
215
enabling dynamic template generation.
216
"""
217
218
def __init__(self, pattern, eval_expr):
219
"""
220
Initialize evaluation-based replacement.
221
222
Parameters:
223
- pattern: str, pattern to match
224
- eval_expr: str, expression to evaluate for replacement
225
"""
226
227
class RepFunc:
228
"""
229
Function-based replacement class.
230
231
Uses custom functions for complex replacement logic
232
with full access to match context.
233
"""
234
235
def __init__(self, pattern, func):
236
"""
237
Initialize function-based replacement.
238
239
Parameters:
240
- pattern: str or regex, pattern to match
241
- func: callable, replacement function
242
"""
243
244
def deep_substitute(obj, substitutions, **kwargs):
245
"""
246
Perform deep template substitution on nested objects.
247
248
Parameters:
249
- obj: object, nested structure to process
250
- substitutions: dict, substitution mappings
251
- max_depth: int, maximum recursion depth
252
253
Returns:
254
object: Object with substitutions applied
255
"""
256
```
257
258
### Asynchronous Operations
259
260
Framework for asynchronous job execution and scheduling with progress monitoring.
261
262
```python { .api }
263
class AsyncJob:
264
"""
265
Asynchronous job management.
266
267
Provides framework for long-running computations with progress tracking,
268
cancellation support, and result retrieval.
269
"""
270
271
def __init__(self, func, *args, **kwargs):
272
"""
273
Initialize async job.
274
275
Parameters:
276
- func: callable, function to execute asynchronously
277
- args: positional arguments for function
278
- kwargs: keyword arguments for function
279
"""
280
281
def start(self):
282
"""Start job execution."""
283
284
def cancel(self):
285
"""Cancel job execution."""
286
287
def is_running(self):
288
"""Check if job is running."""
289
290
def get_result(self, timeout=None):
291
"""Get job result with optional timeout."""
292
293
def get_progress(self):
294
"""Get job progress information."""
295
296
class AsyncScheduler:
297
"""
298
Job scheduling system.
299
300
Manages multiple asynchronous jobs with priority queues,
301
resource allocation, and dependency management.
302
"""
303
304
def __init__(self, max_workers=None):
305
"""
306
Initialize scheduler.
307
308
Parameters:
309
- max_workers: int, maximum concurrent workers
310
"""
311
312
def submit(self, func, *args, priority=0, **kwargs):
313
"""
314
Submit job for execution.
315
316
Parameters:
317
- func: callable, function to execute
318
- args: function arguments
319
- priority: int, job priority (higher = more urgent)
320
- kwargs: function keyword arguments
321
322
Returns:
323
AsyncJob: Job handle
324
"""
325
326
def shutdown(self, wait=True):
327
"""Shutdown scheduler."""
328
329
class ScheduleManager:
330
"""
331
Schedule management utilities.
332
333
Provides cron-like scheduling capabilities for recurring tasks
334
with timezone support and failure handling.
335
"""
336
337
def __init__(self):
338
"""Initialize schedule manager."""
339
340
def schedule(self, func, schedule_str, **kwargs):
341
"""
342
Schedule recurring task.
343
344
Parameters:
345
- func: callable, function to schedule
346
- schedule_str: str, schedule specification (cron-like)
347
- timezone: str, timezone for scheduling
348
- max_retries: int, maximum retry attempts
349
350
Returns:
351
str: Schedule ID
352
"""
353
354
def cancel(self, schedule_id):
355
"""Cancel scheduled task."""
356
357
def list_schedules(self):
358
"""List all active schedules."""
359
```
360
361
### Plotting Utilities
362
363
Enhanced plotting capabilities built on Plotly with VectorBT-specific customizations.
364
365
```python { .api }
366
class Figure:
367
"""
368
Enhanced Plotly figure with VectorBT customizations.
369
370
Provides additional functionality for financial plotting including
371
candlestick charts, volume profiles, and indicator overlays.
372
"""
373
374
def __init__(self, *args, **kwargs):
375
"""Initialize enhanced figure."""
376
377
def add_ohlc(self, ohlc_data, **kwargs):
378
"""Add OHLC candlestick chart."""
379
380
def add_volume(self, volume_data, **kwargs):
381
"""Add volume bars."""
382
383
def add_indicator(self, indicator_data, **kwargs):
384
"""Add technical indicator."""
385
386
def show(self, **kwargs):
387
"""Display figure."""
388
389
class FigureWidget:
390
"""
391
Enhanced Plotly figure widget for Jupyter notebooks.
392
393
Interactive plotting widget with real-time updates and
394
callback support for dynamic visualizations.
395
"""
396
397
def __init__(self, *args, **kwargs):
398
"""Initialize figure widget."""
399
400
def update(self, **kwargs):
401
"""Update widget data."""
402
403
def make_figure(**kwargs):
404
"""
405
Create enhanced figure with VectorBT defaults.
406
407
Parameters:
408
- kwargs: figure configuration parameters
409
410
Returns:
411
Figure: Enhanced Plotly figure
412
"""
413
414
def make_subplots(rows=1, cols=1, **kwargs):
415
"""
416
Create subplot layout with VectorBT styling.
417
418
Parameters:
419
- rows: int, number of subplot rows
420
- cols: int, number of subplot columns
421
- kwargs: subplot configuration
422
423
Returns:
424
Figure: Figure with subplot layout
425
"""
426
427
def save_animation(fig, filename, **kwargs):
428
"""
429
Save figure animation to file.
430
431
Parameters:
432
- fig: Figure, figure to animate
433
- filename: str, output filename
434
- fps: int, frames per second
435
- duration: float, animation duration
436
437
Returns:
438
str: Path to saved animation
439
"""
440
```
441
442
### Utility Functions
443
444
Miscellaneous utility functions for common operations.
445
446
```python { .api }
447
def set_seed(seed):
448
"""
449
Set random seed for reproducible results.
450
451
Parameters:
452
- seed: int, random seed value
453
"""
454
455
class CancelledError(Exception):
456
"""
457
Exception raised when async operation is cancelled.
458
459
Provides information about cancellation reason and timing.
460
"""
461
462
def __init__(self, message="Operation was cancelled"):
463
"""Initialize cancellation error."""
464
```
465
466
## Usage Examples
467
468
### Configuration Management
469
470
```python
471
import vectorbt as vbt
472
473
# Global settings access
474
print(vbt.settings['plotting']['width'])
475
print(vbt.settings['caching']['enabled'])
476
477
# Update global settings
478
vbt.settings.update({
479
'plotting': {
480
'width': 1000,
481
'height': 600,
482
'theme': 'plotly_dark'
483
},
484
'caching': {
485
'enabled': True,
486
'max_size': '1GB'
487
}
488
})
489
490
# Create custom configuration
491
custom_config = vbt.Config({
492
'indicators': {
493
'rsi_window': 14,
494
'ma_windows': [20, 50, 200]
495
},
496
'portfolio': {
497
'initial_cash': 100000,
498
'fees': 0.001
499
}
500
})
501
502
# Use configuration in components
503
class CustomStrategy(vbt.Configured):
504
def __init__(self, **kwargs):
505
super().__init__(**kwargs)
506
self.rsi_window = self.config['rsi_window']
507
self.ma_windows = self.config['ma_windows']
508
509
strategy = CustomStrategy(config=custom_config['indicators'])
510
```
511
512
### Caching System
513
514
```python
515
# Method caching
516
class DataProcessor:
517
@vbt.cached_method
518
def expensive_calculation(self, data, window):
519
# Expensive computation that benefits from caching
520
return data.rolling(window).apply(lambda x: x.sum() ** 2)
521
522
processor = DataProcessor()
523
524
# First call - computed and cached
525
result1 = processor.expensive_calculation(price_data, 20)
526
527
# Second call with same parameters - retrieved from cache
528
result2 = processor.expensive_calculation(price_data, 20)
529
530
# Property caching
531
class Portfolio:
532
@vbt.cached_property
533
def total_return(self):
534
# Expensive calculation cached until data changes
535
return self.value.iloc[-1] / self.value.iloc[0] - 1
536
537
portfolio = Portfolio()
538
return1 = portfolio.total_return # Computed
539
return2 = portfolio.total_return # Retrieved from cache
540
```
541
542
### Template System
543
544
```python
545
# Basic template substitution
546
template = vbt.Sub(
547
"Strategy: {strategy_name}, Window: {window}, Threshold: {threshold}"
548
)
549
550
strategy_desc = template.substitute(
551
strategy_name="RSI Oversold",
552
window=14,
553
threshold=30
554
)
555
556
# Advanced replacement system
557
code_template = """
558
def {func_name}(data, window={window}):
559
{indicator} = vbt.{indicator_class}.run(data, {window})
560
return {indicator}.{output_attr}
561
"""
562
563
replacements = {
564
'func_name': 'calculate_rsi',
565
'window': 14,
566
'indicator': 'rsi_result',
567
'indicator_class': 'RSI',
568
'output_attr': 'rsi'
569
}
570
571
generated_code = vbt.deep_substitute(code_template, replacements)
572
```
573
574
### Asynchronous Operations
575
576
```python
577
# Async job execution
578
def long_backtest(symbols, strategy_params):
579
results = {}
580
for symbol in symbols:
581
# Long-running backtest
582
data = vbt.YFData.download(symbol, period="5y")
583
portfolio = run_strategy(data, strategy_params)
584
results[symbol] = portfolio.total_return()
585
return results
586
587
# Submit async job
588
job = vbt.AsyncJob(
589
long_backtest,
590
symbols=["AAPL", "GOOGL", "MSFT", "TSLA"],
591
strategy_params={'rsi_window': 14, 'threshold': 30}
592
)
593
594
job.start()
595
596
# Check progress
597
while job.is_running():
598
progress = job.get_progress()
599
print(f"Progress: {progress}%")
600
time.sleep(1)
601
602
# Get results
603
results = job.get_result()
604
605
# Job scheduling
606
scheduler = vbt.AsyncScheduler(max_workers=4)
607
608
# Submit multiple jobs
609
jobs = []
610
for symbol in ["AAPL", "GOOGL", "MSFT"]:
611
job = scheduler.submit(
612
run_backtest,
613
symbol=symbol,
614
priority=1
615
)
616
jobs.append(job)
617
618
# Wait for all jobs
619
results = [job.get_result() for job in jobs]
620
scheduler.shutdown()
621
```
622
623
### Enhanced Plotting
624
625
```python
626
# Create enhanced figure
627
fig = vbt.make_figure(
628
width=1200,
629
height=800,
630
title="Portfolio Analysis"
631
)
632
633
# Add OHLC data
634
fig.add_ohlc(
635
ohlc_data=data.get(['Open', 'High', 'Low', 'Close']),
636
name="Price"
637
)
638
639
# Add volume
640
fig.add_volume(
641
volume_data=data.get('Volume'),
642
secondary_y=True
643
)
644
645
# Add indicators
646
fig.add_indicator(
647
indicator_data=rsi_values,
648
name="RSI",
649
secondary_y=True
650
)
651
652
fig.show()
653
654
# Subplot layout
655
fig = vbt.make_subplots(
656
rows=3, cols=1,
657
shared_xaxes=True,
658
subplot_titles=['Price', 'Volume', 'RSI']
659
)
660
661
# Animation
662
animated_fig = create_price_animation(price_data)
663
vbt.save_animation(
664
animated_fig,
665
"price_animation.gif",
666
fps=10,
667
duration=5
668
)
669
```
670
671
### Atomic Operations
672
673
```python
674
# Thread-safe dictionary
675
atomic_cache = vbt.atomic_dict()
676
677
# Safe concurrent access
678
def worker_function(data, cache_key):
679
if cache_key not in atomic_cache:
680
result = expensive_computation(data)
681
atomic_cache[cache_key] = result
682
return atomic_cache[cache_key]
683
684
# Multiple threads can safely access the cache
685
import threading
686
687
threads = []
688
for i in range(10):
689
t = threading.Thread(
690
target=worker_function,
691
args=(data, f"key_{i}")
692
)
693
threads.append(t)
694
t.start()
695
696
for t in threads:
697
t.join()
698
```
699
700
### Dictionary Merging
701
702
```python
703
# Merge configurations
704
base_config = {
705
'portfolio': {'initial_cash': 10000},
706
'indicators': {'rsi_window': 14}
707
}
708
709
user_config = {
710
'portfolio': {'fees': 0.001},
711
'plotting': {'width': 1000}
712
}
713
714
merged_config = vbt.merge_dicts(
715
base_config,
716
user_config,
717
strategy='deep_merge'
718
)
719
# Result: Complete merged configuration with all keys
720
```