0
# Portfolio Simulation & Analysis
1
2
Comprehensive backtesting engine for strategy evaluation with detailed performance metrics, trade analysis, and risk management. The portfolio module provides the core functionality for simulating trading strategies and analyzing their performance.
3
4
## Capabilities
5
6
### Portfolio Construction
7
8
Create portfolios from trading signals or custom order functions with flexible configuration options for initial capital, fees, slippage, and execution logic.
9
10
```python { .api }
11
class Portfolio:
12
"""
13
Main class for portfolio simulation and analysis.
14
15
Provides static methods for portfolio construction and instance methods
16
for performance analysis and visualization.
17
"""
18
19
@classmethod
20
def from_signals(cls, close, entries, exits, **kwargs):
21
"""
22
Create portfolio from entry and exit signals.
23
24
Parameters:
25
- close: pd.Series or pd.DataFrame, closing prices
26
- entries: pd.Series or pd.DataFrame, boolean entry signals
27
- exits: pd.Series or pd.DataFrame, boolean exit signals
28
- init_cash: float, initial capital (default: 100)
29
- size: float or array-like, position size (default: inf)
30
- fees: float, trading fees as percentage (default: 0)
31
- slippage: float, slippage as percentage (default: 0)
32
- freq: str, frequency for calculations (default: 'D')
33
34
Returns:
35
Portfolio: Configured portfolio instance
36
"""
37
38
@classmethod
39
def from_orders(cls, close, orders, **kwargs):
40
"""
41
Create portfolio from order records.
42
43
Parameters:
44
- close: pd.Series or pd.DataFrame, closing prices
45
- orders: structured array, order records with fields like size, price
46
- init_cash: float, initial capital
47
48
Returns:
49
Portfolio: Configured portfolio instance
50
"""
51
52
@classmethod
53
def from_order_func(cls, close, order_func, **kwargs):
54
"""
55
Create portfolio from custom order function.
56
57
Parameters:
58
- close: pd.Series or pd.DataFrame, closing prices
59
- order_func: callable, function generating orders
60
61
Returns:
62
Portfolio: Configured portfolio instance
63
"""
64
65
@classmethod
66
def from_holding(cls, close, **kwargs):
67
"""
68
Create buy-and-hold portfolio.
69
70
Parameters:
71
- close: pd.Series or pd.DataFrame, closing prices
72
- init_cash: float, initial capital
73
74
Returns:
75
Portfolio: Buy-and-hold portfolio instance
76
"""
77
78
@classmethod
79
def from_random_signals(cls, close, n, **kwargs):
80
"""
81
Create portfolio from random signals.
82
83
Parameters:
84
- close: pd.Series or pd.DataFrame, closing prices
85
- n: int or list, number of random signals to generate
86
- seed: int, random seed for reproducibility
87
88
Returns:
89
Portfolio: Portfolio with random signals
90
"""
91
92
@property
93
def orders(self):
94
"""Access to order records."""
95
96
@property
97
def trades(self):
98
"""Access to trade records."""
99
100
@property
101
def positions(self):
102
"""Access to position records."""
103
104
@property
105
def drawdowns(self):
106
"""Access to drawdown records."""
107
108
def value(self):
109
"""Portfolio value over time."""
110
111
def cash(self):
112
"""Cash balance over time."""
113
114
def asset_value(self):
115
"""Asset value over time."""
116
```
117
118
### Performance Metrics
119
120
Comprehensive suite of performance and risk metrics for strategy evaluation including returns, volatility, and risk-adjusted measures.
121
122
```python { .api }
123
def total_return(self):
124
"""
125
Calculate total return of the portfolio.
126
127
Returns:
128
float or pd.Series: Total return as percentage
129
"""
130
131
def annualized_return(self, freq=None):
132
"""
133
Calculate annualized return.
134
135
Parameters:
136
- freq: str, frequency for annualization
137
138
Returns:
139
float or pd.Series: Annualized return percentage
140
"""
141
142
def volatility(self, freq=None):
143
"""
144
Calculate volatility (standard deviation of returns).
145
146
Returns:
147
float or pd.Series: Volatility as percentage
148
"""
149
150
def sharpe_ratio(self, risk_free_rate=0, freq=None):
151
"""
152
Calculate Sharpe ratio.
153
154
Parameters:
155
- risk_free_rate: float, risk-free rate (default: 0)
156
- freq: str, frequency for calculations
157
158
Returns:
159
float or pd.Series: Sharpe ratio
160
"""
161
162
def max_drawdown(self):
163
"""
164
Calculate maximum drawdown.
165
166
Returns:
167
float or pd.Series: Maximum drawdown as percentage
168
"""
169
170
def calmar_ratio(self):
171
"""
172
Calculate Calmar ratio (annualized return / max drawdown).
173
174
Returns:
175
float or pd.Series: Calmar ratio
176
"""
177
178
def sortino_ratio(self, risk_free_rate=0):
179
"""
180
Calculate Sortino ratio.
181
182
Parameters:
183
- risk_free_rate: float, risk-free rate
184
185
Returns:
186
float or pd.Series: Sortino ratio
187
"""
188
```
189
190
### Portfolio State Access
191
192
Access detailed portfolio state including cash, shares, value, and position information throughout the simulation period.
193
194
```python { .api }
195
def cash(self):
196
"""
197
Get cash balances over time.
198
199
Returns:
200
pd.Series or pd.DataFrame: Cash balances
201
"""
202
203
def shares(self):
204
"""
205
Get share holdings over time.
206
207
Returns:
208
pd.Series or pd.DataFrame: Share quantities
209
"""
210
211
def value(self):
212
"""
213
Get total portfolio value over time.
214
215
Returns:
216
pd.Series or pd.DataFrame: Portfolio values
217
"""
218
219
def returns(self):
220
"""
221
Get portfolio returns.
222
223
Returns:
224
pd.Series or pd.DataFrame: Period returns
225
"""
226
227
def cumulative_returns(self):
228
"""
229
Get cumulative returns.
230
231
Returns:
232
pd.Series or pd.DataFrame: Cumulative returns
233
"""
234
```
235
236
### Trade Analysis
237
238
Detailed analysis of individual trades including entry/exit points, holding periods, profit/loss, and trade statistics.
239
240
```python { .api }
241
class Trades:
242
"""
243
Trade record analysis providing detailed trade statistics.
244
"""
245
246
def count(self):
247
"""Get number of trades."""
248
249
def pnl(self):
250
"""Get profit/loss for each trade."""
251
252
def returns(self):
253
"""Get returns for each trade."""
254
255
def duration(self):
256
"""Get duration of each trade."""
257
258
def win_rate(self):
259
"""Calculate win rate percentage."""
260
261
def profit_factor(self):
262
"""Calculate profit factor (gross profit / gross loss)."""
263
264
class EntryTrades:
265
"""Analysis of entry trades (long positions)."""
266
267
class ExitTrades:
268
"""Analysis of exit trades (short positions)."""
269
```
270
271
### Order Analysis
272
273
Analysis of order execution including fill rates, rejected orders, and execution statistics.
274
275
```python { .api }
276
class Orders:
277
"""
278
Order record analysis for examining execution details.
279
"""
280
281
def count(self):
282
"""Get number of orders."""
283
284
def size(self):
285
"""Get order sizes."""
286
287
def price(self):
288
"""Get order prices."""
289
290
def fees(self):
291
"""Get trading fees paid."""
292
293
def side(self):
294
"""Get order sides (buy/sell)."""
295
296
class Logs:
297
"""Execution log analysis for detailed order processing information."""
298
```
299
300
### Position Analysis
301
302
Analysis of position holdings including position sizes, duration, and exposure metrics.
303
304
```python { .api }
305
class Positions:
306
"""
307
Position analysis providing insights into holdings and exposure.
308
"""
309
310
def count(self):
311
"""Get number of positions."""
312
313
def size(self):
314
"""Get position sizes."""
315
316
def duration(self):
317
"""Get position durations."""
318
319
def pnl(self):
320
"""Get position profit/loss."""
321
```
322
323
### Drawdown Analysis
324
325
Detailed drawdown analysis including underwater curves, recovery periods, and drawdown statistics.
326
327
```python { .api }
328
def drawdown(self):
329
"""
330
Calculate drawdown series.
331
332
Returns:
333
pd.Series or pd.DataFrame: Drawdown percentages
334
"""
335
336
def drawdowns(self):
337
"""
338
Get drawdown periods analysis.
339
340
Returns:
341
Drawdowns: Drawdown analysis object
342
"""
343
```
344
345
## Enums and Constants
346
347
```python { .api }
348
class InitCashMode(IntEnum):
349
"""Initial cash calculation modes."""
350
Auto = 0
351
AutoAlign = 1
352
353
class CallSeqType(IntEnum):
354
"""Order call sequence types."""
355
Default = 0
356
Reversed = 1
357
Random = 2
358
Auto = 3
359
360
class SizeType(IntEnum):
361
"""Position sizing types."""
362
Amount = 0
363
Value = 1
364
Percent = 2
365
TargetAmount = 3
366
TargetValue = 4
367
TargetPercent = 5
368
369
class Direction(IntEnum):
370
"""Trade direction."""
371
LongOnly = 0
372
ShortOnly = 1
373
Both = 2
374
375
class OrderStatus(IntEnum):
376
"""Order execution status."""
377
Filled = 0
378
Ignored = 1
379
Rejected = 2
380
381
class OrderSide(IntEnum):
382
"""Order side."""
383
Buy = 0
384
Sell = 1
385
386
class TradeDirection(IntEnum):
387
"""Trade direction classification."""
388
Long = 0
389
Short = 1
390
391
class TradeStatus(IntEnum):
392
"""Trade status."""
393
Open = 0
394
Closed = 1
395
```
396
397
## Usage Examples
398
399
### Basic Strategy Backtesting
400
401
```python
402
import vectorbt as vbt
403
import pandas as pd
404
405
# Get data
406
data = vbt.YFData.download("AAPL", start="2020-01-01", end="2023-01-01")
407
close = data.get("Close")
408
409
# Simple moving average strategy
410
fast_ma = vbt.MA.run(close, 20)
411
slow_ma = vbt.MA.run(close, 50)
412
413
entries = fast_ma.ma_crossed_above(slow_ma.ma)
414
exits = fast_ma.ma_crossed_below(slow_ma.ma)
415
416
# Create portfolio
417
portfolio = vbt.Portfolio.from_signals(
418
close=close,
419
entries=entries,
420
exits=exits,
421
init_cash=10000,
422
fees=0.001 # 0.1% fees
423
)
424
425
# Analyze performance
426
print(f"Total Return: {portfolio.total_return():.2%}")
427
print(f"Sharpe Ratio: {portfolio.sharpe_ratio():.2f}")
428
print(f"Max Drawdown: {portfolio.max_drawdown():.2%}")
429
print(f"Number of Trades: {portfolio.trades.count()}")
430
print(f"Win Rate: {portfolio.trades.win_rate():.2%}")
431
```
432
433
### Multi-Asset Portfolio
434
435
```python
436
# Download multiple assets
437
symbols = ["AAPL", "GOOGL", "MSFT", "TSLA"]
438
data = vbt.YFData.download(symbols, start="2020-01-01", end="2023-01-01")
439
close = data.get("Close")
440
441
# Equal weight rebalancing strategy
442
rebalance_freq = "ME" # Monthly
443
target_weights = pd.Series([0.25, 0.25, 0.25, 0.25], index=symbols)
444
445
# Create custom order function for rebalancing
446
def rebalance_orders(close, target_weights):
447
# Implementation for rebalancing logic
448
pass
449
450
portfolio = vbt.Portfolio.from_order_func(
451
close=close,
452
order_func=rebalance_orders,
453
init_cash=100000
454
)
455
```