The Efficient Frontier with PortfolioAnalytics – Part III

Learning R For Finance – Post 26

(continued from this post)

We follow up on our previous example to compute the portfolio efficient frontier in the mean-CVaR space. The CVaR (conditional value at risk) is also sometimes called expected shortfall (ES) or expected tail loss (ETL). In this post, these terms are interchangeable.

This is the code:

# Compute the mean-ES efficient frontier.

meanES.ef = create.EfficientFrontier(R=R, portfolio=init, type="mean-ES")

# Print the first 5 portfolios on the efficient frontier

meanES.ef$frontier[1:5,]

##                 mean         ES        out     w.WLDFP    w.EQQQIM  w.EM13IM
## result.1    0.003265638 0.03122183 0.03122183 0.2992372 0.019628318 0.6000000
## result.2    0.003517313 0.03136584 0.03136584 0.2822132 0.000000000 0.5708754
## result.3    0.003768988 0.03161271 0.03161271 0.2733011 0.000000000 0.5054341
## result.4    0.004020663 0.03191178 0.03191178 0.2685052 0.009960288 0.4215641
## result.5    0.004272338 0.03221439 0.03221439 0.2629443 0.020564665 0.3375767
##           w.SPYEGR    w.JPNEUAGR   w.IBCXIM    w.EMGIM    w.USAEUAGR   w.FXCIM
## result.1        0    0.071134519        0    0.00000000   0.00000000       0
## result.2        0    0.023239933        0    0.02912456   0.08454689       0
## result.3        0    0.005087644        0    0.09456587   0.11161131       0
## result.4        0    0.002027929        0    0.17843593   0.10950654       0
## result.5        0    0.000000000        0    0.26242335   0.10649108       0
# Chart the mean-ES efficient frontier.
chart.EfficientFrontier(meanES.ef, match.col="ES", main="mean-ETL Efficient  Frontier", type="l", col="blue", RAR.text="Sharpe Ratio")

26.1

# Chart the mean-ES efficient frontier.
chart.EfficientFrontier(meanES.ef, match.col="ES", main="mean-ETL Efficient  Frontier", type="l", col="blue", RAR.text="Sharpe Ratio")

26.2

chart.EF.Weights(meanES.ef, by.groups = TRUE, colorset=rainbow(n = length(funds)), match.col = "ES")

26.3

The PortfolioAnalytics package requires the following steps to solve a portfolio optimization problem:

  1. initialize the portfolio;
  2. add the constraints (several types are possible);
  3. add the objectives (both return and risk measured in several different ways).

The instruction create.EfficientFrontier can then compute the weights, expected return and risk of the portfolios lying on the efficient frontier. See ?create.EfficientFrontier, ?portfolio.spec, ?add.constraint, ?add.objective for further information.

The examples shown here only demonstrates a few of the capabilities offered by the PortfolioAnalytics package: many more are available, although not all of them are fully documented. Probably the best way to approach the package is to carefully go through the demo code included with it.

 


Learning R For Finance

With these posts I just wish to share my experience in learning how to use R to solve some real life financial problems. This will be mostly done introducing and discussing some programs listings. See here for an introduction. See also here for the folder structure that is used in the program listings.

Advertisements

The Efficient Frontier with PortfolioAnalytics – Part II

Learning R For Finance – Post 25

(continued from this post)


# Compute the mean-variance efficient frontier and show it. This is done by default with the "quadprog" package solver within the "ROI" package infrastructure.

meanSigma.ef = create.EfficientFrontier(R=R, portfolio=init,  type="mean-StdDev", n.portfolios = 25)
# Print the weights of the 25 portfolios on the efficient frontier

summary(meanSigma.ef, digits=2)

## **************************************************
## PortfolioAnalytics Efficient Frontier
## **************************************************
##
## Call:
## create.EfficientFrontier(R = R, portfolio = init, type = "mean-StdDev",
##     n.portfolios = 25)
##
## Efficient Frontier Points: 25
##
## Weights along the efficient frontier:
##    WLDFP EQQQIM EM13IM SPYEGR JPNEUAGR IBCXIM EMGIM USAEUAGR FXCIM
## 1   0.29   0.00   0.60      0     0.10      0  0.00     0.01  0.00
## 2   0.22   0.00   0.60      0     0.08      0  0.00     0.09  0.00
## 3   0.18   0.00   0.55      0     0.07      0  0.05     0.14  0.00
## 4   0.14   0.00   0.48      0     0.06      0  0.12     0.18  0.01
## 5   0.12   0.01    0.43     0     0.05      0  0.17     0.20  0.01
## 6   0.09   0.03   0.38      0     0.05      0  0.22     0.21  0.01
## 7   0.07   0.05   0.34      0     0.05      0  0.26     0.21  0.01
## 8   0.05   0.07   0.30      0     0.04      0  0.30     0.22  0.01
## 9   0.02   0.09   0.25      0     0.04      0  0.35     0.23  0.01
## 10  0.00   0.11   0.21      0     0.04      0  0.39     0.23  0.01
## 11  0.00   0.13   0.16      0     0.03      0  0.44     0.22  0.01
## 12  0.00   0.15   0.10      0     0.02      0  0.50     0.21  0.01
## 13  0.00   0.17   0.05      0     0.01      0  0.55     0.20  0.01
## 14  0.00   0.19   0.00      0     0.00      0  0.60     0.19  0.01
## 15  0.00   0.24   0.00      0     0.00      0  0.60     0.15  0.00
## 16  0.00   0.29   0.00      0     0.00      0  0.60     0.10  0.00
## 17  0.00   0.35   0.00      0     0.00      0  0.60     0.04  0.00
## 18  0.00   0.39   0.00      0     0.00      0  0.60     0.00  0.00
## 19  0.00   0.42   0.00      0     0.00      0  0.59     0.00  0.00
## 20  0.00   0.45   0.00      0     0.00      0  0.56     0.00  0.00
## 21  0.00   0.48   0.00      0     0.00      0  0.53     0.00  0.00
## 22  0.00   0.51   0.00      0     0.00      0  0.50     0.00  0.00
## 23  0.00   0.54   0.00      0     0.00      0  0.47     0.00  0.00
## 24  0.00   0.57   0.00      0     0.00      0  0.44     0.00  0.00
## 25  0.00   0.60   0.00      0     0.00      0  0.41     0.00  0.00
##
## Risk and return metrics along the efficient frontier:
##    mean StdDev out
## 1  0.00   0.02   0
## 2  0.00   0.02   0
## 3  0.00   0.02   0
## 4  0.00   0.02   0
## 5  0.00   0.02   0
## 6  0.00   0.02   0
## 7  0.00   0.02   0
## 8  0.00   0.02   0
## 9  0.01   0.02   0
## 10 0.01   0.02   0
## 11 0.01   0.02   0
## 12 0.01   0.02   0
## 13 0.01   0.02   0
## 14 0.01   0.02   0
## 15 0.01   0.02   0
## 16 0.01   0.02   0
## 17 0.01   0.02   0
## 18 0.01   0.02   0
## 19 0.01   0.02   0
## 20 0.01   0.02   0
## 21 0.01   0.03   0
## 22 0.01   0.03   0
## 23 0.01   0.03   0
## 24 0.01   0.03   0
## 25 0.01   0.03   0

# Print the first 5 portfolios on the efficient frontier

meanSigma.ef$frontier[1:5,]

##                mean          StdDev           out         w.WLDFP      w.EQQQIM
## result.1    0.003073670    0.01518459    0.0002305717    0.2876279     6.570652e-19
## result.2    0.003333343    0.01525096    0.0002325917    0.2203795    -2.435967e-18
## result.3    0.003593017    0.01542189    0.0002378347    0.1774600    -4.176983e-18
## result.4    0.003852691    0.01564293    0.0002447012    0.1441133    -5.518727e-18
## result.5    0.004112364    0.01590749    0.0002530483    0.1162911     1.036959e-02
##              w.EM13IM      w.SPYEGR        w.JPNEUAGR     w.IBCXIM        w.EMGIM
## result.1    0.6000000     -3.143736e-19    0.09507974    5.582161e-17     8.453798e-16
## result.2    0.6000000      9.665141e-19    0.07663612    5.907242e-17     8.653728e-16
## result.3    0.5486926     -1.380626e-17    0.06699819    6.049687e-17     5.130745e-02
## result.4    0.4819355     -3.330462e-17    0.05914592    6.133114e-17     1.180645e-01
## result.5    0.4276039     -4.630404e-17    0.05373694    6.540959e-17     1.723961e-01
##              w.USAEUAGR     w.FXCIM
## result.1    0.007292396    0.000000000
## result.2    0.092984355    0.000000000
## result.3    0.141585830    0.003955991
## result.4    0.179666309    0.007074499
## result.5    0.200687760    0.008914639

##               w.EM13IM      w.SPYEGR      w.JPNEUAGR     w.IBCXIM      w.EMGIM
## result.1    0.6000000    -3.143736e-19    0.09507974    5.582161e-17    8.453798e-16
## result.2    0.6000000     9.665141e-19    0.07663612    5.907242e-17    8.653728e-16
## result.3    0.5486926    -1.380626e-17    0.06699819    6.049687e-17    5.130745e-02
## result.4    0.4819355    -3.330462e-17    0.05914592    6.133114e-17    1.180645e-01
## result.5    0.4276039    -4.630404e-17    0.05373694    6.540959e-17    1.723961e-01
##              w.USAEUAGR      w.FXCIM
## result.1    0.007292396    0.000000000
## result.2    0.092984355    0.000000000
## result.3    0.141585830    0.003955991
## result.4    0.179666309    0.007074499
## result.5    0.200687760    0.008914639

# In the following instruction, the RAR.text argument is used to identify therisk-adjusted-return name on the legend.

chart.EfficientFrontier(meanSigma.ef, match.col="StdDev", type="l", rf=0,    RAR.text="Sharpe Ratio", pch=4)

25-1

In the chart above, the efficient frontier is the convex curve drawn with a solid line. The dashed line is built by taking the tangent to the efficient frontier startingù from the risk free rate (0% in this example) and it is the locus of the portfolios that can be built linearly combining the risk free asset with the tangent portfolio on the efficient frontier. If there is no leverage, the optimal portfolios that include the risk free assets are those that lie on the straight segment between the origin (0,0) and the tangency point on the efficient frontier. If the investment in risk free asset is not allowed, all optimal portfolios lie on the efficient frontier. Note also that some assets lie above the efficient frontier: this is due to the fact that in this example we have assumed the existence of constraints on the size of the investment in certain assets (the “box” constraints and the “group” constraints).

Now we chart the weights by asset and by group along the efficient frontier. Remember that group 1 is composed  by bond ETFs while group 2 is composed by equity and commodity ETFs.

 
chart.EF.Weights(meanSigma.ef, main= "Weights on the Efficient Frontier", match.col="StdDev")
chart.EF.Weights(meanSigma.ef, colorset=rainbow(n=length(funds)), by.groups = TRUE, main = "Weights by Group on the Efficient Frontier", match.col="StdDev")

The first chart shows the weight on the vertical axis, the mean return on the lower horizontal axis and the standard deviation on the top horizontal axis. Each column represents one of the 25 portfolios on the efficient  frontier and the colored segments in each columns represent individual ETFs  as defined in the legend.The second chart shows how each portfolio is  allocated to the two groups we have defined.

25-2

25-3In this post we have computed the efficient frontier in the mean-standard deviation space, in the next post we will show how to compute the the efficient frontier in the mean-CVar space.

(to be continued)

 


Learning R For Finance

With these posts I just wish to share my experience in learning how to use R to solve some real life financial problems. This will be mostly done introducing and discussing some programs listings. See here for an introduction. See also here for the folder structure that is used in the program listings.

The Efficient Frontier with PortfolioAnalytics – Part I

Learning R For Finance – Post 24

The portfolio efficient frontier is the set of portfolios that offer the maximum expected return for any given level of risk. In the original formulation by prof. Harry Markowitz more than half a century ago, risk was defined as the variance of the expected returns and the main idea was that risk could be reduced if the assets composing the portfolio were not all perfectly correlated. Fundamentally, if asset prices did not move all in the same direction at the same time, portfolio diversification could yield the same return with less risk or, alternatively, higher returns with the same risk. If we can measure assets returns, variances and covariances (correlations), and we apply the standard mathematical technique[1] used to solve optimization problems, we can determine a set of optimal portfolios for any given level of risk (or for any given level of return).

It is important to note that the Markowitz approach was put forward as a comparative statics problem as it was typical in the economic theory of that time. In other words, in this model time plays no role: returns, variances and assets covariances (correlations) are assumed to be practically the same in the future as they were in the past. No assumption is made about the dynamics of these variables, about the existence of a possible relationship between expected asset returns and their own expected variances or about the possibility that covariances become all highly positive at the same time during a market crisis.

In spite of all this, or perhaps because no satisfactory solution to these issues has yet been found, the efficient frontier remains a useful reference for investors and the listing below shows how it can be computed in R using the PortfolioAnalytics package. In this example, we compute the efficient frontier using two different risk measures: the standard deviation (sigma) and the expected shortfall (ES) and we use a modified version of one of the demo scripts included in the PortfolioAnalytics package.

The data used in this example are the daily prices of  nine ETF’s listed in euro  in the period January 2 2007 – October 26 2015 and they can be downloaded here. Remember to remove the .doc extension before using this file and change the dash in the name to a dot (sorry about this, but WordPress does not allow uploading files with .dat or .Rdata extensions and moreover, it converts dots in the names to dashes…).

# Load required packages

library(PortfolioAnalytics)

# the following packages contain the optimzation algorithms used by PortfolioAnalytics:

library(ROI)
library(ROI.plugin.quadprog)
library(ROI.plugin.glpk)

# this package provides multicore capabilities to PortfolioAnalytics:

library(doParallel)
registerDoParallel()

# Load the data and take out the ".Close" extension from the asset names for shorter legends in plotting.
load("etf.Rdata")
names(prices) = gsub(".Close","",names(prices))

# convert to monthly prices
ep = endpoints(prices, "months")
ep = ep[-1]
mon.prices = prices[ep,]
 
# compute monthly discrete returns
 
R = na.omit(Return.calculate(mon.prices,method="discrete"))
 
# create a vector containing the asset names
funds = names(R)
 
# Set up the initial portfolio object with some basic constraints.
 
init = portfolio.spec(assets=funds)
 
# the "type=leverage" argument allows to specify asset weights that are below
# zero and greater than 1: this can be used for long-short portfolio or 
# (as in this case) to allow some numerical slack (min -0.005, max = 1.005) in
# the  optimization algorithms
 
init = add.constraint(portfolio=init, type="leverage")
init = add.constraint(portfolio=init, type="box", min=0, max=1)
 
# the following instruction adds some "group constraints": here we force the
# portfolio to always hold at least 10% of the assets in bond ETFs (EM13IM,
# IBCXIM and/or EMGIM) and 10% in equity ETFs while at the same time, none of
# these two groups can exceed 60% of the portfolio. The numbers in the argument
# "groups" refer to the ETF position in the vector "funds". Note that the
# "add.constaint" instruction actually allows for many other configurations.
 
init = add.constraint(portfolio=init, type="group", groups=list(c(3, 6, 7), c(1, 2, 4, 5, 8, 9)), group_min=0.1, group_max=0.6)
 
# We now add the objectives for a portfolio that uses the constraints above and
# we call it "meanES.portf". 
# First, we want to minimize the risk (with  the argument type= "risk") where
# risk is here defined as the expected shortfall  ("ES"):
 
meanES.portf = add.objective(portfolio=init, type="risk", name="ES")
 
# Second, we want to achieve the maximum possible return (with the argument
# type= "return") defined as the mean of the monthly returns:
 
meanES.portf = add.objective(portfolio=meanES.portf, type="return", name="mean")
 
# Warning messages stating "In is.na(le) : is.na() applied to non-(list or vector)
# of type 'NULL'" that may appear while running the program are due to an issue with
# the current version (1.03636) of the PortfolioAnalysis package that does not affect
# the results and that can be safely ignored.
 
# We now define a second portfolio called "meanSigma.portf" where we want to minimize
# the risk defined as standard deviation ("StdDev"):
 
meanSigma.portf = add.objective(portfolio=init, type="risk", name="StdDev")
 
# even in the second portfolio we want to achieve the maximum possible return:
 
meanSigma.portf = add.objective(portfolio=meanSigma.portf, type="return", name="mean")

In the next post we will execute these instructions.

(to be continued)


 

 

[1] More precisely the maximization of returns for a given variance is a linear optimization problem with quadratic constraints, while the minimization of risk for a given return is a quadratic optimzation problem with linear constraints. The mathematical solutions to these problems can be found in any good investment textbook.

 

 

 


Learning R For Finance

With these posts I just wish to share my experience in learning how to use R to solve some real life financial problems. This will be mostly done introducing and discussing some programs listings. See here for an introduction. See also here for the folder structure that is used in the program listings.