# Minimizing Downside Risk

November 1, 2011
By

(This article was first published on Systematic Investor » R, and kindly contributed to R-bloggers)

In the Maximum Loss and Mean-Absolute Deviation risk measures, and Expected shortfall (CVaR) and Conditional Drawdown at Risk (CDaR) posts I started the discussion about alternative risk measures we can use to construct efficient frontier. Another alternative risk measure I want to discuss is Downside Risk.

In the traditional mean-variance optimization both returns above and below the mean contribute to the portfolio risk (usually measured by the standard deviation of the portfolio’s return). In the Downside Risk framework, only returns that are below the mean or below the target rate of return (MAR) contribute to the portfolio risk. I will discuss two Downside Risk measures: Lower Semi-Variance, and Lower Semi-Absolute Deviation. I will use methods presented in Portfolio Optimization under Lower Partial Risk Measure by H. Konno, H. Waki and A. Yuuki (2002) paper 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 Lower Semi-Absolute Deviation (page 6) can be written as

$\frac{1}{T}\sum_{j=1}^{T}\left | \tau - \sum_{i=1}^{n}r_{ij}x_{i} \right |_{-} \newline\newline =\frac{1}{T}\sum_{j=1}^{T}max\left \{ \tau - \sum_{i=1}^{n}r_{ij}x_{i},0 \right \}$

It can be formulated as a linear programming problem

$\min_{}{}\frac{1}{T}\sum_{j=1}^{T}z_{j} \newline\newline \tau - \sum_{i=1}^{n}r_{ij}x_{i} \leq z_{j}, j=1,...,T \newline\newline z_{j} \geq 0, j=1,...,T$

This linear programming problem can be easily implemented

min.mad.downside.portfolio <- function
(
ia,		# input assumptions
constraints	# constraints
)
{
n = ia$n nt = nrow(ia$hist.returns)

mar = ia$parameters.mar # objective : Mean-Lower-Semi-Absolute Deviation (M-LSAD) # 1/T * [ SUM <over j> z.j ] f.obj = c( rep(0, n), (1/nt) * rep(1, nt) ) # adjust constraints, add z.j constraints = add.variables(nt, constraints, lb = 0) # MAR - [ SUM <over i> r.ij * x.i ] <= z.j , for each j = 1,...,T a = rbind( matrix(0, n, nt), diag(nt)) a[1 : n, ] = t(ia$hist.returns)
constraints = add.constraints(a, rep(mar, nt), '>=', constraints)

# setup linear programming
f.con = constraints$A f.dir = c(rep('=', constraints$meq), rep('>=', len(constraints$b) - constraints$meq))
f.rhs = constraints$b # find optimal solution x = NA sol = try(solve.LP.bounds('min', f.obj, t(f.con), f.dir, f.rhs, lb = constraints$lb, ub = constraints$ub), TRUE) if(!inherits(sol, 'try-error')) { x = sol$solution[1:n]
}

return( x )
}


The portfolio’s Lower Semi-Absolute Deviation (page 7) can be written as

$\frac{1}{T}\sum_{j=1}^{T}\left | \tau - \sum_{i=1}^{n}r_{ij}x_{i} \right |_{-}^{2} \newline\newline =\frac{1}{T}\sum_{j=1}^{T}max\left \{ \tau - \sum_{i=1}^{n}r_{ij}x_{i},0 \right \}^{2}$

It can be formulated as a quadratic programming problem

$\min_{}{}\frac{1}{T}\sum_{j=1}^{T}z_{j}^{2} \newline\newline \tau - \sum_{i=1}^{n}r_{ij}x_{i} \leq z_{j}, j=1,...,T \newline\newline z_{j} \geq 0, j=1,...,T$

This quadratic programming problem can be implemented

min.risk.downside.portfolio <- function
(
ia,		# input assumptions
constraints	# constraints
)
{
n = ia$n nt = nrow(ia$hist.returns)

mar = ia$parameters.mar # objective : Mean-Lower Semi-Variance (MV) # 1/T * [ SUM <over j> z.j^2 ] f.obj = c( rep(0, n), (1/nt) * rep(1, nt) ) # adjust constraints, add z.j constraints = add.variables(nt, constraints, lb = 0) # MAR - [ SUM <over i> r.ij * x.i ] <= z.j , for each j = 1,...,T a = rbind( matrix(0, n, nt), diag(nt)) a[1 : n, ] = t(ia$hist.returns)
constraints = add.constraints(a, rep(mar, nt), '>=', constraints)

Dmat = diag( len(f.obj) )
diag(Dmat) = f.obj
if(!is.positive.definite(Dmat)) {
Dmat <- make.positive.definite(Dmat)
}

# find optimal solution
x = NA
sol = try(solve.QP.bounds(Dmat = Dmat, dvec = rep(0, nrow(Dmat)) ,
Amat=constraints$A, bvec=constraints$b, constraints$meq, lb = constraints$lb, ub = constraints$ub),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) # Set target return (or Minimum Acceptable Returns (MAR)) # and consider only returns that are less than the target ia$parameters.mar = 0/100
# convert annual to monthly
ia$parameters.mar = ia$parameters.mar / 12

# create efficient frontier(s)

ef.risk = portopt(ia, constraints, 50, 'Risk')
ef.risk.downside = portopt(ia, constraints, 50, 'S-Risk', min.risk.downside.portfolio)

# Plot multiple Efficient Frontiers and Transition Maps
layout( matrix(1:4, nrow = 2) )

# Plot multiple Efficient Frontiers and Transition Maps
layout( matrix(1:4, nrow = 2) )
plot.ef(ia, list(ef.risk.downside, ef.risk), portfolio.risk, F)
plot.ef(ia, list(ef.risk.downside, ef.risk), portfolio.risk.downside, F)

plot.transition.map(ef.risk)
plot.transition.map(ef.risk.downside)


The downside risk efficient frontiers, prefixed with S-, are similar to their full counterparts and have similar transition maps in our example.

Another way to approach minimization of the Lower Semi-Variance that I want to explore later is presented in Mean-Semivariance Optimization: A Heuristic Approach by Javier Estrada paper.

To view the complete source code for this example, please have a look at the aa.downside.test() function in aa.test.r at github.

R-bloggers.com offers daily e-mail updates about R news and tutorials on topics such as: visualization (ggplot2, Boxplots, maps, animation), programming (RStudio, Sweave, LaTeX, SQL, Eclipse, git, hadoop, Web Scraping) statistics (regression, PCA, time series, trading) and more...