Ccoom Mpplleexx Ppoorrttffoolliioo Ooppttiim Miizzaattiioonn Wwiitthh Ppoorrttffoolliiooaannaallyyttiiccss
Ccoom Mpplleexx Ppoorrttffoolliioo Ooppttiim Miizzaattiioonn Wwiitthh Ppoorrttffoolliiooaannaallyyttiiccss
PortfolioAnalytics
R/Finance 2014
Ross Bennett
Overview
· Discuss Portfolio Optimization
· Introduce PortfolioAnalytics
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
How do we define risk? What about more complex objectives and constraints?
3/51
Portfolio Optimization Objectives
· Minimize Risk
- Volatility
- Several Others
· Risk Budgets
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.
· Visualizations
· Solver agnostic
5/51
Support Multiple Solvers
Linear and Quadratic Programming Solvers
- GLPK (Rglpk)
- Symphony (Rsymphony)
- Quadprog (quadprog)
· Random Portfolios
· Differential Evolution (DEoptim)
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.
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)
Initializes the portfolio object that holds portfolio level data, constraints, and objectives
11/51
Workflow: Add Constraints
args(add.constraint)
· Sum of Weights
· Box
· Group
· Factor Exposure
· Position Limit
· and many more
12/51
Workflow: Add Objectives
args(add.objective)
· Return
· Risk
· Risk Budget
· Weight Concentration
13/51
Workflow: Run Optimization
args(optimize.portfolio)
args(optimize.portfolio.rebalancing)
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
· 15 Mid Cap
· 5 Small Cap
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 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 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)
20/51
Run Optimization
# Generate random portfolios
rp <- random_portfolios(portf.dn, 10000, "sample")
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.
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.
25/51
Specify Initial Portfolio
# Specify an initial portfolio
funds <- colnames(R)
portf.init <- portfolio.spec(funds)
# 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")
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))
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
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.
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.
40/51
Specify Portfolio
# Specify portfolio
portf.crra <- portfolio.spec(funds)
# 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)
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)
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)
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
- many more
Acknowledgements
Many thanks to...
48/51
PortfolioAnalytics Links
PortfolioAnalytics is on R-Forge in the ReturnAnalytics project
· PortfolioAnalytics
· https://github.com/rossb34/PortfolioAnalyticsPresentation
· http://rossb34.github.io/PortfolioAnalyticsPresentation/
49/51
Any Questions?
50/51
References and Useful Links
· ROI
· DEoptim
· pso
· GenSA
· PerformanceAnalytics
· Boudt paper
· Shiny App
51/51