0% found this document useful (0 votes)
106 views

Ccoom Mpplleexx Ppoorrttffoolliioo Ooppttiim Miizzaattiioonn Wwiitthh Ppoorrttffoolliiooaannaallyyttiiccss

The document discusses portfolio optimization using the R package PortfolioAnalytics. It introduces modern portfolio theory and objectives like minimizing risk and maximizing risk-adjusted return. It overviews PortfolioAnalytics' support for multiple constraints, objectives, and solvers. Examples demonstrate generating random portfolios and optimizing a dollar neutral portfolio with return and risk objectives using equity data. It also sets up hedge fund return data to optimize a portfolio minimizing expected shortfall.

Uploaded by

Danna Jordan
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
106 views

Ccoom Mpplleexx Ppoorrttffoolliioo Ooppttiim Miizzaattiioonn Wwiitthh Ppoorrttffoolliiooaannaallyyttiiccss

The document discusses portfolio optimization using the R package PortfolioAnalytics. It introduces modern portfolio theory and objectives like minimizing risk and maximizing risk-adjusted return. It overviews PortfolioAnalytics' support for multiple constraints, objectives, and solvers. Examples demonstrate generating random portfolios and optimizing a dollar neutral portfolio with return and risk objectives using equity data. It also sets up hedge fund return data to optimize a portfolio minimizing expected shortfall.

Uploaded by

Danna Jordan
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 51

Complex Portfolio Optimization with

PortfolioAnalytics
R/Finance 2014

Ross Bennett
Overview
· Discuss Portfolio Optimization
· Introduce PortfolioAnalytics

· Demonstrate PortfolioAnalytics with Examples

2/51
Modern Portfolio Theory
"Modern" Portfolio Theory (MPT) was introduced by Harry Markowitz in 1952.

In general, MPT states that an investor's objective is to maximize portfolio expected return for a
given amount of risk.

General Objectives

· Maximize a measure of gain per unit measure of risk

· Minimize a measure of risk

How do we define risk? What about more complex objectives and constraints?

3/51
Portfolio Optimization Objectives
· Minimize Risk
- Volatility

- Tail Loss (VaR, ES)

- Other Downside Risk Measure


· Maximize Risk Adjusted Return

- Sharpe Ratio, Modified Sharpe Ratio

- Several Others
· Risk Budgets

- Equal Component Contribution to Risk (i.e. Risk Parity)


- Limits on Component Contribution
· Maximize a Utility Function

- Quadratic, CRRA, etc.

4/51
PortfolioAnalytics Overview
PortfolioAnalytics is an R package designed to provide numerical solutions and visualizations
for portfolio optimization problems with complex constraints and objectives.

· Support for multiple constraint and objective types

· An objective function can be any valid R function


· Modular constraints and objectives

· Support for user defined moment functions

· Visualizations
· Solver agnostic

· Support for parallel computing

5/51
Support Multiple Solvers
Linear and Quadratic Programming Solvers

· R Optimization Infrastructure (ROI)

- GLPK (Rglpk)
- Symphony (Rsymphony)

- Quadprog (quadprog)

Global (stochastic or continuous solvers)

· Random Portfolios
· Differential Evolution (DEoptim)

· Particle Swarm Optimization (pso)

· Generalized Simulated Annealing (GenSA)

6/51
Random Portfolios
PortfolioAnalytics has three methods to generate random portfolios.

1. The sample method to generate random portfolios is based on an idea by Pat Burns.

2. The simplex method to generate random portfolios is based on a paper by W. T. Shaw.


3. The grid method to generate random portfolios is based on the gridSearch function in the
NMOF package.

7/51
Comparison of Random Portfolio Methods

8/51
Comparison of Random Portfolio Methods
(Interactive!)
Magnify sample
simplex
grid
0.0074
0.0072

0.0070

0.0068

0.0066

0.0064

0.0062
Return

0.0060

0.0058

0.0056

0.0054

0.0052

0.0050
0.0048
0.0082 0.0100 0.0150 0.0200 0.0250 0.0300 0.0350
0.0355
Risk (std. dev.)

9/51
Random Portfolios: Simplex Method

10/51
Workflow: Specify Portfolio
args(portfolio.spec)

## function (assets = NULL, category_labels = NULL, weight_seq = NULL,


## message = FALSE)
## NULL

Initializes the portfolio object that holds portfolio level data, constraints, and objectives

11/51
Workflow: Add Constraints
args(add.constraint)

## function (portfolio, type, enabled = TRUE, message = FALSE, ...,


## indexnum = NULL)
## NULL

Supported Constraint Types

· Sum of Weights

· Box

· Group

· Factor Exposure
· Position Limit
· and many more

12/51
Workflow: Add Objectives
args(add.objective)

## function (portfolio, constraints = NULL, type, name, arguments = NULL,


## enabled = TRUE, ..., indexnum = NULL)
## NULL

Supported Objective types

· Return

· Risk

· Risk Budget

· Weight Concentration

13/51
Workflow: Run Optimization
args(optimize.portfolio)

## function (R, portfolio = NULL, constraints = NULL, objectives = NULL,


## optimize_method = c("DEoptim", "random", "ROI", "pso", "GenSA"),
## search_size = 20000, trace = FALSE, ..., rp = NULL, momentFUN = "set.portfolio.moments",
## message = FALSE)
## NULL

args(optimize.portfolio.rebalancing)

## function (R, portfolio = NULL, constraints = NULL, objectives = NULL,


## optimize_method = c("DEoptim", "random", "ROI"), search_size = 20000,
## trace = FALSE, ..., rp = NULL, rebalance_on = NULL, training_period = NULL,
## trailing_periods = NULL)
## NULL

14/51
Workflow: Analyze Results
VISUALIZATION DATA EXTRACTION

plot extractObjectiveMeasures

chart.Concentration extractStats

chart.EfficientFrontier extractWeights

chart.RiskReward print

chart.RiskBudget summary

chart.Weights

15/51
Stock Data Setup
Here we will look at portfolio optimization in the context of stocks.

· Selection of large cap, mid cap, and small cap stocks from CRSP data

· Weekly data from 1/7/1997 to 12/28/2010


· 15 Large Cap

· 15 Mid Cap

· 5 Small Cap

equity.data <- cbind(largecap_weekly[,1:15],


midcap_weekly[,1:15],
smallcap_weekly[,1:5])

16/51
Distribution of Monthly Returns

17/51
Example 1: Market Neutral Portfolio
Here we consider a portfolio of stocks. Our objective is to maximize portfolio return with a
target of 0.0015 and minimize portfolio StdDev with a target of 0.02 subject to dollar neutral,
beta, box, and position limit constraints.

18/51
Specify Portfolio: Constraints
portf.dn <- portfolio.spec(stocks)

# Add constraint such that the portfolio weights sum to 0*


portf.dn <- add.constraint(portf.dn, type="weight_sum",
min_sum=-0.01, max_sum=0.01)

# Add box constraint such that no asset can have a weight of greater than
# 20% or less than -20%
portf.dn <- add.constraint(portf.dn, type="box", min=-0.2, max=0.2)

# Add constraint such that we have at most 20 positions


portf.dn <- add.constraint(portf.dn, type="position_limit", max_pos=20)

# Add constraint such that the portfolio beta is between -0.25 and 0.25
betas <- t(CAPM.beta(equity.data, market, Rf))
portf.dn <- add.constraint(portf.dn, type="factor_exposure", B=betas,
lower=-0.25, upper=0.25)

19/51
Specify Portfolio: Objectives
# Add objective to maximize portfolio return with a target of 0.0015
portf.dn.StdDev <- add.objective(portf.dn, type="return", name="mean",
target=0.0015)

# Add objective to minimize portfolio StdDev with a target of 0.02


portf.dn.StdDev <- add.objective(portf.dn.StdDev, type="risk", name="StdDev",
target=0.02)

20/51
Run Optimization
# Generate random portfolios
rp <- random_portfolios(portf.dn, 10000, "sample")

# Run the optimization


opt.dn <- optimize.portfolio(equity.data, portf.dn.StdDev,
optimize_method="random", rp=rp,
trace=TRUE)

21/51
Plot Results
plot(opt.dn, main="Dollar Neutral Portfolio", risk.col="StdDev", neighbors=10)

22/51
EDHEC Data Setup
Here we will look at portfolio optimization in the context of portfolio of hedge funds.

· EDHEC-Risk Alternative Indexes monthly returns from 1/31/1997 to 1/31/2014

RELATIVE VALUE DIRECTIONAL

Convertible Arbitrage (CA) CTA Global (CTAG)

Equity Market Neutral (EMN) Emerging Markets (EM)

Fixed Income Arbitrage (FIA) Global Macro (GM)

R <- edhec[,c("Convertible.Arbitrage", "Equity.Market.Neutral",


"Fixed.Income.Arbitrage",
"CTA.Global", "Emerging.Markets", "Global.Macro")]
# Abreviate column names for convenience and plotting
colnames(R) <- c("CA", "EMN", "FIA", "CTAG", "EM", "GM")

23/51
Monthly Returns

24/51
Example 2: Minimum Expected Shortfall
Consider an allocation to hedge funds using the EDHEC-Risk Alternative Index as a proxy. This
will be an extended example starting with an objective to minimize modified expected shortfall,
then add risk budget percent contribution limit, and finally add equal risk contribution limit.

· Minimize Modified Expected Shortfall


· Minimize Modified Expected Shortfall with Risk Budget Limit

· Minimize Modified Expected Shortfall with Equal Risk Contribution

25/51
Specify Initial Portfolio
# Specify an initial portfolio
funds <- colnames(R)
portf.init <- portfolio.spec(funds)

# Add constraint such that the weights sum to 1*


portf.init <- add.constraint(portf.init, type="weight_sum",
min_sum=0.99, max_sum=1.01)

# Add box constraint such that no asset can have a weight of greater than
# 40% or less than 5%
portf.init <- add.constraint(portf.init, type="box",
min=0.05, max=0.4)

# Add return objective with multiplier=0 such that the portfolio mean
# return is calculated, but does not impact optimization
portf.init <- add.objective(portf.init, type="return",
name="mean", multiplier=0)

26/51
Add Objectives
# Add objective to minimize expected shortfall
portf.minES <- add.objective(portf.init, type="risk", name="ES")

# Add objective to set upper bound on percentage component contribution


portf.minES.RB <- add.objective(portf.minES, type="risk_budget",
name="ES", max_prisk=0.3)
# Relax box constraints
portf.minES.RB$constraints[[2]]$max <- rep(1,ncol(R))

# Add objective to minimize concentration of modified ES


# component contribution
portf.minES.EqRB <- add.objective(portf.minES, type="risk_budget",
name="ES", min_concentration=TRUE)
# Relax box constraints
portf.minES.EqRB <- add.constraint(portf.minES.EqRB, type="box",
min=0.05, max=1, indexnum=2)

27/51
Run Optimization
# Combine the 3 portfolios
portf <- combine.portfolios(list(minES=portf.minES,
minES.RB=portf.minES.RB,
minES.EqRB=portf.minES.EqRB))

# Run the optimization


opt.minES <- optimize.portfolio(R, portf, optimize_method="DEoptim",
search_size=5000, trace=TRUE, traceDE=0)

28/51
Plot in Risk-Return Space

29/51
Chart Risk Budgets

30/51
Set Rebalancing Parameters and Run Backtest
# Set rebalancing frequency
rebal.freq <- "quarters"

# Training Period
training <- 120

# Trailing Period
trailing <- 72

bt.opt.minES <- optimize.portfolio.rebalancing(R, portf,


optimize_method="DEoptim",
rebalance_on=rebal.freq,
training_period=training,
trailing_periods=trailing,
search_size=5000,
traceDE=0)

31/51
Min ES Risk Contributions and Weights Through Time

32/51
Min ES Risk Budget Limit Risk Contributions and
Weights Through Time

33/51
Min ES Equal Component Contribution Risk
Contributions and Weights Through Time

34/51
Min ES Equal Component Contribution Risk
Contributions and Weights (interactive!)
Percent Contribution to Risk Weights
Grouped
Stacked CA EMN FIA CTAGEM GM Grouped
Stacked CA EMN FIA CTAGEM GM
100.00% 101.00%

90.00% 90.00%

80.00% 80.00%

70.00% 70.00%

60.00% 60.00%

50.00% 50.00%

40.00% 40.00%

30.00% 30.00%

20.00% 20.00%

10.00% 10.00%

0.00% 0.00%
Dec 2008 Mar 2011 Jun 2013 Dec 2008 Mar 2011 Jun 2013

35/51
Compute Returns
ret.bt.opt <- do.call(cbind, lapply(bt.opt.minES,
function(x) summary(x)$portfolio_returns))
colnames(ret.bt.opt) <- c("min ES", "min ES RB", "min ES Eq RB")

36/51
Chart Performance
charts.PerformanceSummary(ret.bt.opt)

37/51
Example 3: Maximize CRRA
Consider an allocation to hedge funds using the EDHEC-Risk Alternative Index as a proxy. Our
objective to maximize the fourth order expansion of the Constant Relative Risk Aversion (CRRA)
expected utility function as in the Boudt paper and Martellini paper. We use the same data as
Example 3.

λ λ(λ + 1) λ(λ + 1)(λ + 2)


EUλ (w) = − m(2) (w) + m(3) (w) − m(4) (w)
2 6 24

38/51
Define a function to compute CRRA
CRRA <- function(R, weights, lambda, sigma, m3, m4){
weights <- matrix(weights, ncol=1)
M2.w <- t(weights) %*% sigma %*% weights
M3.w <- t(weights) %*% m3 %*% (weights %x% weights)
M4.w <- t(weights) %*% m4 %*% (weights %x% weights %x% weights)
term1 <- (1 / 2) * lambda * M2.w
term2 <- (1 / 6) * lambda * (lambda + 1) * M3.w
term3 <- (1 / 24) * lambda * (lambda + 1) * (lambda + 2) * M4.w
out <- -term1 + term2 - term3
out
}

39/51
Define a custom moment function
The default function for momentFUN is set.portfolio.moments. We need to write our own
function to estimate the moments for our objective function.

crra.moments <- function(R, ...) {


out <- list()
out$mu <- colMeans(R)
out$sigma <- cov(R)
out$m3 <- PerformanceAnalytics:::M3.MM(R)
out$m4 <- PerformanceAnalytics:::M4.MM(R)
out
}

40/51
Specify Portfolio
# Specify portfolio
portf.crra <- portfolio.spec(funds)

# Add constraint such that the weights sum to 1


portf.crra <- add.constraint(portf.crra, type="weight_sum",
min_sum=0.99, max_sum=1.01)

# Add box constraint such that no asset can have a weight of greater than
# 40% or less than 5%
portf.crra <- add.constraint(portf.crra, type="box",
min=0.05, max=0.4)

# Add objective to maximize CRRA


portf.crra <- add.objective(portf.crra, type="return",
name="CRRA", arguments=list(lambda=10))

41/51
"Dummy" Objectives
# Dummy objectives for plotting and/or further analysis
portf.crra <- add.objective(portf.crra, type="return", name="mean", multiplier=0)
portf.crra <- add.objective(portf.crra, type="risk", name="ES", multiplier=0)
portf.crra <- add.objective(portf.crra, type="risk", name="StdDev", multiplier=0)

42/51
Run Optimization
opt.crra <- optimize.portfolio(R, portf.crra, optimize_method="DEoptim",
search_size=5000, trace=TRUE, traceDE=0,
momentFUN="crra.moments")

head(extractStats(opt.crra),4)

## CRRA.CRRA mean ES StdDev out w.CA w.EMN


## .DE.portf.1 -0.0009786 0.005906 0.03407 0.01367 0.0009786 0.1667 0.1667
## .DE.portf.2 -0.0007585 0.005716 0.02532 0.01215 0.0007585 0.1560 0.3420
## .DE.portf.3 -0.0019451 0.006380 0.05068 0.01901 0.0019451 0.1180 0.1200
## .DE.portf.4 -0.0007816 0.005536 0.02591 0.01232 0.0007816 0.0900 0.1840
## w.FIA w.CTAG w.EM w.GM
## .DE.portf.1 0.1667 0.1667 0.1667 0.1667
## .DE.portf.2 0.0560 0.2180 0.1280 0.0920
## .DE.portf.3 0.0880 0.1300 0.3900 0.1620
## .DE.portf.4 0.2800 0.2720 0.1160 0.0640

43/51
Chart Results
chart.RiskReward(opt.crra, risk.col = "ES")
chart.RiskReward(opt.crra, risk.col = "StdDev")

44/51
Run Backtest and Compute Returns
bt.opt.crra <- optimize.portfolio.rebalancing(R, portf.crra,
optimize_method="DEoptim",
search_size=5000, trace=TRUE,
traceDE=0,
momentFUN="crra.moments",
rebalance_on=rebal.freq,
training_period=training,
trailing_periods=trailing)

ret.crra <- summary(bt.opt.crra)$portfolio_returns


colnames(ret.crra) <- "CRRA"

45/51
Chart Weights Through Time
chart.Weights(bt.opt.crra, main="CRRA Weights", col=bluemono)

46/51
Chart Performance
charts.PerformanceSummary(cbind(ret.bt.opt, ret.crra),
main="Optimization Performance")

47/51
Conclusion
· Introduced the goals and summary of PortfolioAnalytics
· Demonstrated the flexibility through examples

· Exciting plans for GSOC 2014

- Support for regime switching


- Support for supervised learning

- many more

Acknowledgements
Many thanks to...

· Google: funding for Google Summer of Code (GSoC)

· UW CF&RM Program: continued work on PortfolioAnalytics


· GSoC Mentors: Brian Peterson, Peter Carl, Doug Martin, and Guy Yollin
· R/Finance Committee

48/51
PortfolioAnalytics Links
PortfolioAnalytics is on R-Forge in the ReturnAnalytics project

· PortfolioAnalytics

Source code for the slides

· https://github.com/rossb34/PortfolioAnalyticsPresentation

and view it here

· http://rossb34.github.io/PortfolioAnalyticsPresentation/

49/51
Any Questions?

50/51
References and Useful Links
· ROI
· DEoptim

· pso

· GenSA
· PerformanceAnalytics

· Patrick Burns Random Portfolios

· W.T. Shaw Random Portfolios


· Martellini paper

· Boudt paper
· Shiny App

51/51

You might also like