Expected shortfall (CVaR) and Conditional Drawdown at Risk (CDaR) risk measures
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
In the Maximum Loss and Mean-Absolute Deviation risk measures post I started the discussion about alternative risk measures we can use to construct efficient frontier. Another alternative risk measures I want to discuss are Expected shortfall (CVaR) and Conditional Drawdown at Risk (CDaR). I will use methods presented in Comparative Analysis of Linear Portfolio Rebalancing Strategies: An Application to Hedge Funds by Krokhmal, P., S. Uryasev, and G. Zrazhevsky (2001) and Portfolio Optimization Using Conditional Value-At-Risk and Conditional Drawdown-At-Risk by Enn Kuutanpapers to construct optimal portfolios.
Let x.i, i= 1,…,n be weights of instruments in the portfolio. We suppose that j= 1,…,T scenarios of returns with equal probabilities are available. I will use historical assets returns as scenarios. Let us denote by r.ij the return of i-th asset in the scenario j. The portfolio’s Conditional Value at Risk (CVaR) (page 30-32) can be written as
It can be formulated as a linear programming problem
This linear programming problem can be easily implemented
min.cvar.portfolio ( ia, # input assumptions constraints # constraints ) { n = ia$n nt = nrow(ia$hist.returns) # objective : Conditional Value at Risk (CVaR) # E + 1/(1-a) * 1/T * [ SUM w.j ] f.obj = c( rep(0, n), (1/(1-alpha))* (1/nt) * rep(1, nt), 1 ) # adjust prior constraints, add w.j, E f.con = rbind( constraints$A, matrix(0, (nt + 1), ncol(constraints$A) ) ) f.dir = c(rep('=', constraints$meq), rep('>=', len(constraints$b) - constraints$meq)) f.rhs = constraints$b # -E - [ SUM r.ij * x.i ] < w.j, for each j = 1,...,T a1 = rbind( matrix(0, n, nt), diag(nt), 1) b1 = rep(0, nt) a1[1:n0,] = t(ia$hist.returns) f.con = cbind( f.con, a1 ) f.dir = c(f.dir, rep('>=', nt)) f.rhs = c(f.rhs, b1) # find optimal solution x = NA min.x.bounds = c( rep(-100, n), rep(0, nt), -100 ) sol = try(solve.LP.bounds('min', f.obj, t(f.con), f.dir, f.rhs, lb = min.x.bounds), TRUE) if(!inherits(sol, 'try-error')) { x = sol$solution[1:n] } return( x ) }
The portfolio’s Conditional Drawdown at Risk (CDaR) (page 32-33) concept is very similar to CVaR. Instead of using portfolio returns to determine shortfall, we use portfolio drawdowns. The Conditional Drawdown at Risk (CDaR) can be written as
It can be formulated as a linear programming problem
min.cdar.portfolio ( ia, # input assumptions constraints # constraints ) { n = ia$n nt = nrow(ia$hist.returns) # objective : Conditional Drawdown at Risk (CDaR) # E + 1/(1-a) * 1/T * [ SUM w.j ] f.obj = c( rep(0, n), (1/(1-alpha))* (1/nt) * rep(1, nt), 1, rep(0, nt) ) # adjust prior constraints, add w.j, E, u.j f.con = rbind( constraints$A, matrix(0, (2 * nt + 1), ncol(constraints$A) ) ) f.dir = c(rep('=', constraints$meq), rep('>=', len(constraints$b) - constraints$meq)) f.rhs = constraints$b # u.j - [ SUM [ SUM r.ij ] * x.i ] - E < w.j, for each j = 1,...,T a1 = rbind( matrix(0, n, nt), diag(nt), 1, -diag(nt)) b1 = rep(0, nt) a1[1:n0,] = t(apply( t(ia$hist.returns), 1, cumsum)) f.con = cbind( f.con, a1 ) f.dir = c(f.dir, rep('>=', nt)) f.rhs = c(f.rhs, b1) # [ SUM [ SUM r.ij ] * x.i ] < u.j, for each j = 1,...,T a1 = rbind( matrix(0, n, nt), 0*diag(nt), 0, diag(nt)) b1 = rep(0, nt) a1[1:n0,] = -t(apply( t(ia$hist.returns), 1, cumsum)) f.con = cbind( f.con, a1 ) f.dir = c(f.dir, rep('>=', nt)) f.rhs = c(f.rhs, b1) # u.j-1 < u.j, for each j = 1,...,T temp = diag(nt) temp[-nt,-1]=-diag((nt-1)) diag(temp) = 1 a1 = rbind( matrix(0, n, nt), 0*diag(nt), 0, temp) b1 = rep(0, (nt-1)) a1 = a1[,-1] f.con = cbind( f.con, a1 ) f.dir = c(f.dir, rep('>=', (nt-1))) f.rhs = c(f.rhs, b1) # find optimal solution x = NA min.x.bounds = c( rep(-100, n), rep(0, nt), -100, rep(-100, nt) ) sol = try(solve.LP.bounds('min', f.obj, t(f.con), f.dir, f.rhs, lb = min.x.bounds), TRUE) if(!inherits(sol, 'try-error')) { x = sol$solution[1:n] } return( x ) }
Let’s examine efficient frontiers computed under different risk measures using historical input assumptions presented in the Introduction to Asset Allocation post:
# load Systematic Investor Toolbox setInternet2(TRUE) source(gzcon(url('https://github.com/systematicinvestor/SIT/raw/master/sit.gz', 'rb'))) #-------------------------------------------------------------------------- # Create Efficient Frontier #-------------------------------------------------------------------------- ia = aa.test.create.ia() n = ia$n # 0 <= x.i <= 0.8 constraints = new.constraints(n, lb = 0, ub = 0.8) # SUM x.i = 1 constraints = add.constraints(rep(1, n), 1, type = '=', constraints) # Alpha for used for CVaR and CDaR # http://www.investopedia.com/articles/04/092904.asp ia$parameters.alpha = 0.95 # create efficient frontier(s) ef.risk = portopt(ia, constraints, 50, 'Risk') ef.cvar = portopt(ia, constraints, 50, 'CVaR', min.cvar.portfolio) ef.cdar = portopt(ia, constraints, 50, 'CDaR', min.cdar.portfolio) # Plot multiple Efficient Frontiers layout( matrix(1:4, nrow = 2) ) plot.ef(ia, list(ef.risk, ef.cvar, ef.cdar), portfolio.risk, F) plot.ef(ia, list(ef.risk, ef.cvar, ef.cdar), portfolio.cvar, F) plot.ef(ia, list(ef.risk, ef.cvar, ef.cdar), portfolio.cdar, F) # Plot multiple Transition Maps layout( matrix(1:4, nrow = 2) ) plot.transitopn.map(ef.risk) plot.transitopn.map(ef.cvar) plot.transitopn.map(ef.cdar)
The efficient frontiers constructed under Expected shortfall (CVaR) and Standard Deviation risk measures look similar. The efficient frontier constructed under Conditional Drawdown at Risk (CDaR) is superior to the other risk measures in controlling drawdowns.
In the next post, I will discuss how to combine multiple risk measures during construction of efficient frontier.
To view the complete source code for this example, please have a look at the aa.cvar.test() function in aa.test.r at github.
R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.