-
Notifications
You must be signed in to change notification settings - Fork 0
/
portfolio.py
172 lines (133 loc) · 4.84 KB
/
portfolio.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
# Databricks notebook source
import numpy as np
import pandas as pd
import yfinance as yf
import warnings
warnings.filterwarnings("ignore")
#pd.options.display.float_format = '{:.4%}'.format
# Date range
start = '2007-01-01'
end = '2021-12-31'
# Tickers of assets
assets = ['XLB', 'XLV', 'XLC', 'XLK', 'XLF', 'XLP', 'XLI', 'XLU',
'XLY', 'XLRE', 'XLE'
]
assets.sort()
# Downloading data
data = yf.download(assets, start = start, end = end)
data = data.loc[:,('Adj Close', slice(None))]
data.columns = assets
# COMMAND ----------
# Calculating returns
Y = data[assets].pct_change().dropna()
display(Y.head())
# COMMAND ----------
import riskfolio as rp
# Plotting Assets Clusters
ax = rp.plot_dendrogram(returns=Y,
codependence='pearson',
linkage='single',
k=None,
max_k=10,
leaf_order=True,
ax=None)
# COMMAND ----------
# Building the portfolio object
port = rp.HCPortfolio(returns=Y)
# Estimate optimal portfolio:
model='HRP' # Could be HRP or HERC
codependence = 'pearson' # Correlation matrix used to group assets in clusters
rm = 'MV' # Risk measure used, this time will be variance
rf = 0 # Risk free rate
linkage = 'single' # Linkage method used to build clusters
max_k = 10 # Max number of clusters used in two difference gap statistic, only for HERC model
leaf_order = True # Consider optimal order of leafs in dendrogram
w = port.optimization(model=model,
codependence=codependence,
rm=rm,
rf=rf,
linkage=linkage,
max_k=max_k,
leaf_order=leaf_order)
display(w.T)
# COMMAND ----------
# Plotting the composition of the portfolio
ax = rp.plot_pie(w=w,
title='HRP Naive Risk Parity',
others=0.05,
nrow=25,
cmap="tab20",
height=8,
width=10,
ax=None)
# COMMAND ----------
# Plotting the risk contribution per asset
mu = Y.mean()
cov = Y.cov() # Covariance matrix
returns = Y # Returns of the assets
ax = rp.plot_risk_con(w=w,
cov=cov,
returns=returns,
rm=rm,
rf=0,
alpha=0.05,
color="tab:blue",
height=6,
width=10,
t_factor=252,
ax=None)
# COMMAND ----------
# Risk Measures available:
#
# 'vol': Standard Deviation.
# 'MV': Variance.
# 'MAD': Mean Absolute Deviation.
# 'GMD': Gini Mean Difference.
# 'MSV': Semi Standard Deviation.
# 'FLPM': First Lower Partial Moment (Omega Ratio).
# 'SLPM': Second Lower Partial Moment (Sortino Ratio).
# 'VaR': Conditional Value at Risk.
# 'CVaR': Conditional Value at Risk.
# 'TG': Tail Gini.
# 'EVaR': Entropic Value at Risk.
# 'WR': Worst Realization (Minimax).
# 'RG': Range of returns.
# 'CVRG': CVaR Range of returns.
# 'TGRG': Tail Gini Range of returns.
# 'MDD': Maximum Drawdown of uncompounded cumulative returns (Calmar Ratio).
# 'ADD': Average Drawdown of uncompounded cumulative returns.
# 'DaR': Drawdown at Risk of uncompounded cumulative returns.
# 'CDaR': Conditional Drawdown at Risk of uncompounded cumulative returns.
# 'EDaR': Entropic Drawdown at Risk of uncompounded cumulative returns.
# 'UCI': Ulcer Index of uncompounded cumulative returns.
# 'MDD_Rel': Maximum Drawdown of compounded cumulative returns (Calmar Ratio).
# 'ADD_Rel': Average Drawdown of compounded cumulative returns.
# 'DaR_Rel': Drawdown at Risk of compounded cumulative returns.
# 'CDaR_Rel': Conditional Drawdown at Risk of compounded cumulative returns.
# 'EDaR_Rel': Entropic Drawdown at Risk of compounded cumulative returns.
# 'UCI_Rel': Ulcer Index of compounded cumulative returns.
rms = ['vol', 'MV', 'MAD', 'GMD', 'MSV', 'FLPM', 'SLPM', 'VaR',
'CVaR', 'TG', 'EVaR', 'WR', 'RG', 'CVRG', 'TGRG', 'MDD',
'ADD', 'DaR', 'CDaR', 'EDaR', 'UCI', 'MDD_Rel',
'ADD_Rel', 'DaR_Rel', 'CDaR_Rel', 'EDaR_Rel', 'UCI_Rel']
w_s = pd.DataFrame([])
for i in rms:
w = port.optimization(model=model,
codependence=codependence,
rm=i,
rf=rf,
linkage=linkage,
max_k=max_k,
leaf_order=leaf_order)
w_s = pd.concat([w_s, w], axis=1)
w_s.columns = rms
# COMMAND ----------
w_s.style.format("{:.2%}").background_gradient(cmap='YlGn')
# COMMAND ----------
import matplotlib.pyplot as plt
# Plotting a comparison of assets weights for each portfolio
fig = plt.gcf()
fig.set_figwidth(16)
fig.set_figheight(8)
ax = fig.subplots(nrows=1, ncols=1)
w_s.plot(kind='bar', width=0.8, ax=ax)