or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

constraints-advanced.mdhierarchical-clustering.mdindex.mdparameter-estimation.mdplotting-visualization.mdportfolio-optimization.mdreports.mdrisk-functions.md

portfolio-optimization.mddocs/

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

```