0
# Portfolio Optimization
1
2
Core portfolio optimization functionality providing classical mean-variance optimization, Black-Litterman models, factor models, worst-case optimization, and OWA (Ordered Weighted Averaging) optimization. The Portfolio class supports 4 objective functions and 24 risk measures for comprehensive portfolio construction.
3
4
## Capabilities
5
6
### Portfolio Class
7
8
Main portfolio optimization class with extensive configuration options and optimization methods.
9
10
```python { .api }
11
class Portfolio:
12
def __init__(self, returns=None, sht=False, uppersht=0.2, upperlng=1,
13
budget=1, budgetsht=0.2, nea=None, card=None, factors=None,
14
B=None, alpha=0.05, a_sim=100, beta=None, b_sim=None,
15
kappa=0.30, kappa_g=None, n_max_kurt=50, kindbench=True,
16
allowTO=False, turnover=0.05, allowTE=False, TE=0.05,
17
benchindex=None, benchweights=None, ainequality=None,
18
binequality=None, arcinequality=None, brcinequality=None,
19
afrcinequality=None, bfrcinequality=None, b=None,
20
network_sdp=None, cluster_sdp=None, network_ip=None,
21
cluster_ip=None, graph_penalty=0.05, acentrality=None,
22
bcentrality=None, lowerret=None, upperdev=None, upperkt=None,
23
uppermad=None, uppergmd=None, uppersdev=None, upperskt=None,
24
upperflpm=None, upperslpm=None, upperCVaR=None, uppertg=None,
25
upperEVaR=None, upperRLVaR=None, upperwr=None, uppercvrg=None,
26
uppertgrg=None, upperevrg=None, upperrvrg=None, upperrg=None,
27
uppermdd=None, upperadd=None, upperCDaR=None, upperEDaR=None,
28
upperRLDaR=None, upperuci=None, p_1=2, p_2=3, p_3=4, p_4=10, p_5=50):
29
"""
30
Initialize Portfolio object with comprehensive configuration options.
31
32
Core Parameters:
33
- returns (DataFrame): Assets returns data (n_samples x n_assets)
34
- sht (bool): Allow short positions. Default: False
35
- uppersht (float): Maximum absolute value of short positions. Default: 0.2
36
- upperlng (float): Maximum value of long positions. Default: 1
37
- budget (float): Maximum sum of long and short positions. Default: 1
38
- budgetsht (float): Maximum sum of absolute short positions. Default: 0.2
39
40
Asset Selection:
41
- nea (int): Minimum number of effective assets. Default: None
42
- card (int): Maximum number of assets (requires MIP solver). Default: None
43
44
Factor Model:
45
- factors (DataFrame): Factor returns data. Default: None
46
- B (DataFrame): Factor loadings matrix (n_assets x n_factors). Default: None
47
48
Risk Parameters:
49
- alpha (float): Significance level for CVaR, EVaR, CDaR, EDaR. Default: 0.05
50
- a_sim (int): Number of CVaRs for Tail Gini approximation. Default: 100
51
- beta (float): Significance level for gains. Default: None (uses alpha)
52
- b_sim (int): Number of CVaRs for gains approximation. Default: None (uses a_sim)
53
- kappa (float): Deformation parameter for RLVaR/RLDaR (0-1). Default: 0.30
54
- kappa_g (float): Deformation parameter for RLVaR gains. Default: None
55
- n_max_kurt (int): Max assets for Kurtosis SDP formulation. Default: 50
56
57
Benchmark:
58
- kindbench (bool): True if benchmark is portfolio, False if index. Default: True
59
- benchindex (DataFrame): Benchmark index returns. Default: None
60
- benchweights (DataFrame): Benchmark weights. Default: equally weighted
61
62
Turnover/Tracking:
63
- allowTO (bool): Enable turnover constraints. Default: False
64
- turnover (float): Maximum turnover deviation. Default: 0.05
65
- allowTE (bool): Enable tracking error constraints. Default: False
66
- TE (float): Maximum tracking error deviation. Default: 0.05
67
68
Linear Constraints:
69
- ainequality/binequality: Linear constraint matrices A ≤ b
70
- arcinequality/brcinequality: Risk contribution constraint matrices
71
- afrcinequality/bfrcinequality: Factor risk contribution constraints
72
- b: Risk budgeting constraint vector
73
74
Network/Graph Constraints:
75
- network_sdp/cluster_sdp: SDP-based network/cluster constraint matrices
76
- network_ip/cluster_ip: IP-based network/cluster constraint matrices
77
- graph_penalty (float): SDP network constraint weight. Default: 0.05
78
- acentrality/bcentrality: Centrality constraint matrices
79
80
Risk Upper Bound Constraints:
81
- lowerret: Minimum expected return constraint
82
- upperdev: Max standard deviation, upperkt: Max sqrt kurtosis
83
- uppermad: Max MAD, uppergmd: Max GMD, uppersdev: Max semi-deviation
84
- upperskt: Max semi-kurtosis, upperflpm/upperslpm: Max partial moments
85
- upperCVaR: Max CVaR, uppertg: Max Tail Gini, upperEVaR: Max EVaR
86
- upperRLVaR: Max RLVaR, upperwr: Max worst realization
87
- uppercvrg/uppertgrg/upperevrg/upperrvrg: Max range measures
88
- upperrg: Max range, uppermdd: Max drawdown, upperadd: Max avg drawdown
89
- upperCDaR: Max CDaR, upperEDaR: Max EDaR, upperRLDaR: Max RLDaR
90
- upperuci: Max Ulcer Index
91
92
P-norm Parameters (for GMD, TG, TGRG approximation):
93
- p_1, p_2, p_3, p_4, p_5: P-norm values. Defaults: 2, 3, 4, 10, 50
94
"""
95
```
96
97
### Statistics Calculation
98
99
Methods for calculating portfolio statistics using various estimation methods.
100
101
```python { .api }
102
def assets_stats(self, method_mu='hist', method_cov='hist', **kwargs):
103
"""
104
Calculate expected returns and covariance matrix.
105
106
Parameters:
107
- method_mu (str): Method for expected returns ('hist', 'ewma1', 'ewma2')
108
- method_cov (str): Method for covariance ('hist', 'ewma1', 'ewma2', 'ledoit', 'oas')
109
"""
110
111
def blacklitterman_stats(self, P, Q, delta=None, eq=True, **kwargs):
112
"""
113
Calculate Black-Litterman expected returns and covariance.
114
115
Parameters:
116
- P (DataFrame): Matrix of views
117
- Q (DataFrame): Vector of views
118
- delta (float): Risk aversion parameter
119
- eq (bool): Use equilibrium returns
120
"""
121
122
def factors_stats(self, method_mu='hist', method_cov='hist', **kwargs):
123
"""
124
Calculate factor model statistics.
125
126
Parameters:
127
- method_mu (str): Method for expected returns
128
- method_cov (str): Method for covariance matrix
129
"""
130
131
def wc_stats(self, box='S', ellip='E', **kwargs):
132
"""
133
Calculate worst-case statistics.
134
135
Parameters:
136
- box (str): Box uncertainty set type
137
- ellip (str): Elliptical uncertainty set type
138
"""
139
```
140
141
### Portfolio Optimization
142
143
Core optimization methods for different portfolio models and objectives.
144
145
```python { .api }
146
def optimization(self, model='Classic', rm='MV', obj='Sharpe', kelly=None, rf=0, l=2, hist=True):
147
"""
148
Optimize portfolio weights.
149
150
Parameters:
151
- model (str): Optimization model ('Classic', 'BL', 'FM', 'FC', 'WC', 'OWA')
152
- rm (str): Risk measure code
153
- obj (str): Objective function ('MinRisk', 'Utility', 'Sharpe', 'MaxRet')
154
- kelly (str): Mean return calculation (None, 'approx', 'exact')
155
- rf (float): Risk-free rate
156
- l (float): Risk aversion parameter (default: 2)
157
- hist (bool): Use historical scenarios
158
159
Returns:
160
DataFrame: Optimal portfolio weights
161
"""
162
163
def rp_optimization(self, model='Classic', rm='MV', rf=0, b=None, hist=True):
164
"""
165
Risk parity optimization.
166
167
Parameters:
168
- model (str): Optimization model
169
- rm (str): Risk measure
170
- rf (float): Risk-free rate
171
- b (DataFrame): Risk budgeting vector
172
- hist (bool): Use historical scenarios
173
174
Returns:
175
DataFrame: Risk parity portfolio weights
176
"""
177
178
def rrp_optimization(self, model='Classic', rm='MV', rf=0, b=None, hist=True):
179
"""
180
Relaxed risk parity optimization.
181
182
Parameters:
183
- model (str): Optimization model
184
- rm (str): Risk measure
185
- rf (float): Risk-free rate
186
- b (DataFrame): Risk budgeting vector
187
- hist (bool): Use historical scenarios
188
189
Returns:
190
DataFrame: Relaxed risk parity weights
191
"""
192
193
def wc_optimization(self, obj='Sharpe', rm='MV', rf=0, l=0):
194
"""
195
Worst-case optimization.
196
197
Parameters:
198
- obj (str): Objective function
199
- rm (str): Risk measure
200
- rf (float): Risk-free rate
201
- l (float): Risk aversion parameter
202
203
Returns:
204
DataFrame: Worst-case optimal weights
205
"""
206
207
def frc_optimization(self, rm='MV', rf=0, b=None):
208
"""
209
Factor risk constraint optimization.
210
211
Parameters:
212
- rm (str): Risk measure
213
- rf (float): Risk-free rate
214
- b (DataFrame): Factor risk budgets
215
216
Returns:
217
DataFrame: Factor risk constrained weights
218
"""
219
220
def owa_optimization(self, obj='Sharpe', owa_w=None, rm='MV', rf=0, l=0):
221
"""
222
OWA (Ordered Weighted Averaging) optimization.
223
224
Parameters:
225
- obj (str): Objective function
226
- owa_w (DataFrame): OWA weights vector
227
- rm (str): Risk measure
228
- rf (float): Risk-free rate
229
- l (float): Risk aversion parameter
230
231
Returns:
232
DataFrame: OWA optimal weights
233
"""
234
```
235
236
### Efficient Frontier
237
238
Methods for generating and analyzing efficient frontiers.
239
240
```python { .api }
241
def efficient_frontier(self, model='Classic', rm='MV', points=20, rf=0, hist=True):
242
"""
243
Generate efficient frontier.
244
245
Parameters:
246
- model (str): Optimization model
247
- rm (str): Risk measure
248
- points (int): Number of frontier points
249
- rf (float): Risk-free rate
250
- hist (bool): Use historical scenarios
251
252
Returns:
253
DataFrame: Efficient frontier weights matrix
254
"""
255
256
def frontier_limits(self, model='Classic', rm='MV', rf=0, hist=True):
257
"""
258
Calculate efficient frontier limits.
259
260
Parameters:
261
- model (str): Optimization model
262
- rm (str): Risk measure
263
- rf (float): Risk-free rate
264
- hist (bool): Use historical scenarios
265
266
Returns:
267
tuple: (min_risk_weights, max_return_weights)
268
"""
269
```
270
271
### Portfolio Properties
272
273
Key properties for accessing and modifying portfolio data and constraints.
274
275
```python { .api }
276
@property
277
def returns(self):
278
"""Get/set assets returns DataFrame."""
279
280
@property
281
def factors(self):
282
"""Get/set risk factors DataFrame."""
283
284
@property
285
def assetslist(self):
286
"""Get list of asset names."""
287
288
@property
289
def numassets(self):
290
"""Get number of assets."""
291
292
@property
293
def B(self):
294
"""Get/set factor loadings matrix."""
295
296
@property
297
def benchweights(self):
298
"""Get/set benchmark weights."""
299
300
@property
301
def ainequality(self):
302
"""Get/set inequality constraints matrix A."""
303
304
@property
305
def binequality(self):
306
"""Get/set inequality constraints vector b."""
307
308
@property
309
def kappa(self):
310
"""Get/set RLVaR/RLDaR deformation parameter."""
311
```
312
313
Usage Example:
314
315
```python
316
import riskfolio as rp
317
import pandas as pd
318
319
# Load returns data
320
returns = pd.read_csv('returns.csv', index_col=0, parse_dates=True)
321
322
# Create portfolio
323
port = rp.Portfolio(returns=returns)
324
325
# Calculate statistics
326
port.assets_stats(method_mu='hist', method_cov='hist')
327
328
# Optimize for maximum Sharpe ratio
329
w_sharpe = port.optimization(model='Classic', rm='MV', obj='Sharpe', rf=0.02)
330
331
# Generate efficient frontier
332
frontier = port.efficient_frontier(model='Classic', rm='MV', points=20)
333
334
# Risk parity portfolio
335
w_rp = port.rp_optimization(model='Classic', rm='MV', rf=0.02)
336
337
print("Sharpe Optimal Weights:")
338
print(w_sharpe.T)
339
print("\nRisk Parity Weights:")
340
print(w_rp.T)
341
```