from: https://systematicinvestor.wordpress.com/2013/02/12/cluster-portfolio-allocation/
Today, I want to continue with clustering theme and show how the portfolio weights are determined in the Cluster Portfolio Allocation method. One example of the Cluster Portfolio Allocation method is
Cluster Risk Parity (Varadi, Kapler, 2012).
The Cluster Portfolio Allocation method has 3 steps:
- Create Clusters
- Allocate funds within each Cluster
- Allocate funds across all Clusters
I will illustrate below all 3 steps using “Equal Weight” and “Risk Parity” portfolio allocation methiods. Let’s start by loading historical prices for the 10 major asset classes.
12 | load.packages ( 'quantmod' ) |
14 | tickers = spl ( 'GLD,UUP,SPY,QQQ,IWM,EEM,EFA,IYR,USO,TLT' ) |
17 | getSymbols (tickers, src = 'yahoo' , from = '1900-01-01' , env = data, auto.assign = T) |
18 | for (i in ls (data)) data[[i]] = adjustOHLC (data[[i]], use.Adjusted=T) |
20 | bt.prep (data, align= 'remove.na' ) |
26 | ret = data$prices / mlag (data$prices) - 1 |
Next, let’s compute “Plain” portfolio allocation (i.e. no Clustering)
1 | fn.name = 'equal.weight.portfolio' |
5 | ia = create.historical.ia (ret, 252) |
Next, let’s create clusters and compute portfolio allocation within each Cluster
02 | group = cluster.group.kmeans.90 (ia) |
05 | weight0 = rep ( NA , ia$n) |
08 | hist.g = NA * ia$hist.returns[,1:ngroups] |
12 | if ( sum (group == g) == 1 ) { |
13 | weight0[group == g] = 1 |
14 | hist.g[,g] = ia$hist.returns[, group == g, drop=F] |
17 | ia.temp = create.historical.ia (ia$hist.returns[, group == g, drop=F], 252) |
23 | weight0[group == g] = w0 |
26 | hist.g[,g] = ia.temp$hist.returns %*% w0 |
Next, let’s compute portfolio allocation across all Clusters and compute final portfolio weights
2 | ia.g = create.historical.ia (hist.g, 252) |
5 | group.weights = fn (ia.g) |
9 | weight0[group == g] = weight0[group == g] * group.weights[g] |
Finally, let’s create reports and compare portfolio allocations
04 | load.packages ( 'RColorBrewer' ) |
05 | col = colorRampPalette ( brewer.pal (9, 'Set1' ))(ia$n) |
07 | layout ( matrix (1:2,nr=2,nc=1)) |
11 | pie (weight[index], labels = paste ( colnames (ret), round (100*weight,1), '%' )[index], col=col, main=fn.name) |
13 | pie (weight0[index], labels = paste ( colnames (ret), round (100*weight0,1), '%' )[index], col=col, main= paste ( 'Cluster' ,fn.name)) |
The difference is most striking in the “Equal Weight” portfolio allocation method. The Cluster version allocates 25% to each cluster first, and then allocates equally within each cluster. The Plain version allocates equally among all assets. The “Risk Parity” version below works in similar way, but instead of having equal weights, the focus is on the equal risk allocations. I.e. UUP gets a much bigger allocation because it is far less risky than any other asset.
Next week, I will show how to back-test Cluster Portfolio Allocation methods.
No comments:
Post a Comment