A lot of people talk about equal risk contribution or balancing risk. This post aim’s to explore how a risk parity portfolio performs depending on the risk metric used in it’s calculation.

I explore using Expected Shortfall. Volatility, Semi deviation and maximum drawdown as risk factors.

The strategy is rebalanced monthly.

Mathematically.

Choose W such that Rf_i * W_i = 1/NumberofAssets

What’s the rationale here?

This means mathematically that the investor has a risk budget and wants to naively diversify the risk budget across the investable universe.

Some potential drawbacks to this approach is the fact it does not take into consideration the correlation/covariance structure of the market. This can also be a positive as it implies that the parameter does not need to be invested however the allocation is universe dependent. It might be worth a future blog post for me to identify least correlated securities from a universe then use risk-parity on that uncorrelated bunch.

- Sharpe Ratio for ES strategy: 0.51
- Sharpe Ratio for vol strategy: 0.56
- Sharpe Ratio for semidev strategy: 0.56
- Sharpe Ratio for max dd strategy: 0.39

Will update later more performance stats.

library(PerformanceAnalytics) library(quantmod) ###Symlist symbol_list = c('SPY','XLF','XLE','XLU','XLK','XLB','XLP','XLY','XLI','XLV','TLT','GLD') getSymbols(symbol_list, from = '1990-01-01') securities_matrix = NULL for( sym in symbol_list){ securities_matrix = merge.xts(securities_matrix,ROC(Ad(get(paste(sym))),type='discrete')) } ##Start in 2005, as GLD has inception of 2004-11 securities_matrix = securities_matrix['2005/2015-01-01'] ###Risk Metrics weight_matrix_es = xts(matrix(nrow=nrow(securities_matrix),ncol=ncol(securities_matrix)),order.by=index(securities_matrix)) weight_matrix_vol= xts(matrix(nrow=nrow(securities_matrix),ncol=ncol(securities_matrix)),order.by=index(securities_matrix)) weight_matrix_sd= xts(matrix(nrow=nrow(securities_matrix),ncol=ncol(securities_matrix)),order.by=index(securities_matrix)) weight_matrix_mdd= xts(matrix(nrow=nrow(securities_matrix),ncol=ncol(securities_matrix)),order.by=index(securities_matrix)) monthly_dates_for_rebal = index(weight_matrix_es[endpoints(weight_matrix_es)]) for(i in 253:nrow(securities_matrix)){ info_set = first(securities_matrix,i-1) ##Estimate ES if(index(securities_matrix[i])%in%monthly_dates_for_rebal){ es_est = ES(info_set) es_w = 1/(es_est*ncol(es_est)) es_w = es_w/sum(es_w) weight_matrix_es[i,] = es_w ##VOL est vol_est = StdDev(info_set) vol_w = 1/(vol_est*ncol(vol_est)) vol_w = vol_w/sum(vol_w) weight_matrix_vol[i,] = vol_w sd_est = SemiDeviation(info_set) sd_w = 1/sd_est*ncol(sd_est) sd_w = sd_w/sum(sd_w) weight_matrix_sd[i,] = sd_w mdd_est = maxDrawdown(info_set) mdd_w = 1/mdd_est*ncol(mdd_est) mdd_w = mdd_est/sum(mdd_w) weight_matrix_mdd[i,] = mdd_w} else{ weight_matrix_es[i,] = weight_matrix_es[i-1,]*(1+securities_matrix[i-1,]) weight_matrix_es[i,] = weight_matrix_es[i,]/sum(weight_matrix_es[i,]) weight_matrix_vol[i,] = weight_matrix_vol[i-1,]*(1+securities_matrix[i-1,]) weight_matrix_vol[i,] = weight_matrix_vol[i,]/sum(weight_matrix_vol[i,]) weight_matrix_sd[i,] = weight_matrix_sd[i-1,]*(1+securities_matrix[i-1,]) weight_matrix_sd[i,] = weight_matrix_sd[i,]/sum(weight_matrix_sd[i,]) weight_matrix_mdd[i,] = weight_matrix_mdd[i-1,]*(1+securities_matrix[i-1,]) weight_matrix_mdd[i,] = weight_matrix_mdd[i,]/sum(weight_matrix_mdd[i,]) } } port_es = xts(rowSums(weight_matrix_es*securities_matrix),order.by=index(securities_matrix)) port_vol = xts(rowSums(weight_matrix_vol*securities_matrix),order.by=index(securities_matrix)) port_sd = xts(rowSums(weight_matrix_sd*securities_matrix),order.by=index(securities_matrix)) port_mdd = xts(rowSums(weight_matrix_mdd*securities_matrix),order.by=index(securities_matrix)) my_mat = merge.xts(port_es,port_vol,port_sd,port_mdd,securities_matrix$SPY.Adjusted) colnames(my_mat) = c('expected shortfall','volatility','semi deviation','max drawdown','sp500')

Created by Pretty R at inside-R.org

[…] ← Risk Parity using various risk measures (volatility, expected shortfall, semi deviation, maximum dra… […]

[…] This post will aim to explore the effective number of bets (https://kylebalkissoon.wordpress.com/2014/04/15/effective-number-of-bets/) of various risk parity strategies (https://kylebalkissoon.wordpress.com/2014/04/14/risk-parity-using-various-risk-measures-volatility-ex…). […]

Wouldn’t you want to omit SPY from the securities list if you’re comparing the results to SPY?

Good question, the answer no as the goal is to manage risk as opposed to beat a benchmark. Taking tactical exposure in SPY is also valuable from a risk to return standpoint.