[Returnanalytics-commits] r3364 - pkg/PortfolioAnalytics/sandbox/RFinance2014
noreply at r-forge.r-project.org
noreply at r-forge.r-project.org
Sat Apr 12 06:49:51 CEST 2014
Author: rossbennett34
Date: 2014-04-12 06:49:50 +0200 (Sat, 12 Apr 2014)
New Revision: 3364
Modified:
pkg/PortfolioAnalytics/sandbox/RFinance2014/makefile
pkg/PortfolioAnalytics/sandbox/RFinance2014/optimization_analysis.R
pkg/PortfolioAnalytics/sandbox/RFinance2014/optimize.R
pkg/PortfolioAnalytics/sandbox/RFinance2014/presentation.Rmd
pkg/PortfolioAnalytics/sandbox/RFinance2014/presentation.md
pkg/PortfolioAnalytics/sandbox/RFinance2014/slidy_presentation.html
Log:
presentation update
Modified: pkg/PortfolioAnalytics/sandbox/RFinance2014/makefile
===================================================================
--- pkg/PortfolioAnalytics/sandbox/RFinance2014/makefile 2014-04-11 05:50:24 UTC (rev 3363)
+++ pkg/PortfolioAnalytics/sandbox/RFinance2014/makefile 2014-04-12 04:49:50 UTC (rev 3364)
@@ -1,17 +1,18 @@
# http://robjhyndman.com/hyndsight/makefiles/
# https://www.cs.umd.edu/class/fall2002/cmsc214/Tutorial/makefile.html
-# List out the R files used
-RFILES := data_analysis.R optimize.R optimization_analysis.R
+# List the R files used
+RFILES := data_prep.R data_analysis.R optimize.R optimization_analysis.R
# Rout indicator files to show R file has run
+# R CMD BATCH will generate .Rout files after running
OUT_FILES:= $(RFILES:.R=.Rout)
-all: slidy_presentation.html presentation.Rmd $(OUT_FILES)
+all: $(OUT_FILES) slidy_presentation.html presentation.Rmd
# Generate slidy presentation from markdown file
-slidy_presentation.html: presentation.md
+slidy_presentation.html: $(RFILES) $(OUT_FILES) presentation.md
pandoc -t slidy -s presentation.md -o slidy_presentation.html
# Generate markdown file from R markdown file
@@ -20,25 +21,35 @@
# Data analysis script
data_analysis.Rout: data_analysis.R
- R CMD BATCH data_analysis.R
+ R CMD BATCH --vanilla data_analysis.R
# Optimization analysis script to analyze results of optimization
optimization_analysis.Rout: optimization_analysis.R optimize.R
- R CMD BATCH optimization_analysis.R
+ R CMD BATCH --vanilla optimization_analysis.R
# Run optimizations
optimize.Rout: optimize.R
- R CMD BATCH optimize.R
+ R CMD BATCH --vanilla optimize.R
+# Data prep
+data_prep.Rout: data_prep.R
+ R CMD BATCH --vanilla data_prep.R
+
lwShrink.Rout: R/lwShrink.R
- R CMD BATCH R/lwShrink.R
+ R CMD BATCH --vanilla R/lwShrink.R
# Use Rscript to run the necessary R files as an alternative to R CMD BATCH
-run:
+runR:
+ Rscript data_prep.R
Rscript data_analysis.R
Rscript optimize.R
Rscript optimization_analysis.R
clean:
- rm *.Rout
- rm *.html
\ No newline at end of file
+ rm -f *.Rout
+ rm -f data_figures/*.png
+ rm -f optimization_figures/*.png
+ rm -f optimization_results/*.rda
+ rm -f *.md
+ rm -f *.html
+
\ No newline at end of file
Modified: pkg/PortfolioAnalytics/sandbox/RFinance2014/optimization_analysis.R
===================================================================
--- pkg/PortfolioAnalytics/sandbox/RFinance2014/optimization_analysis.R 2014-04-11 05:50:24 UTC (rev 3363)
+++ pkg/PortfolioAnalytics/sandbox/RFinance2014/optimization_analysis.R 2014-04-12 04:49:50 UTC (rev 3364)
@@ -107,21 +107,35 @@
risk.type="percentage", neighbors=10)
dev.off()
-# Plot the risk contribution through time
+# Plot the risk contribution of portfolio 1 through time
png(paste(figures.dir, "risk_minES.png", sep="/"))
chart.RiskBudget(bt.opt.minES[[1]], main="Min ES Risk Contribution",
risk.type="percentage")
dev.off()
+# Plot the risk contribution of portfolio 1 through time
+png(paste(figures.dir, "weights_minES.png", sep="/"))
+chart.Weights(bt.opt.minES[[1]], main="Min ES Weights")
+dev.off()
+# Plot the risk contribution of portfolio 3 through time
png(paste(figures.dir, "risk_minESRB.png", sep="/"))
chart.RiskBudget(bt.opt.minES[[2]], main="Min ES RB Risk Contribution",
risk.type="percentage")
dev.off()
+# Plot the weights of portfolio 2 through time
+png(paste(figures.dir, "weights_minESRB.png", sep="/"))
+chart.Weights(bt.opt.minES[[2]], main="Min ES RB Weights")
+dev.off()
+# Plot the risk contribution of portfolio 3 through time
png(paste(figures.dir, "risk_minESEqRB.png", sep="/"))
chart.RiskBudget(bt.opt.minES[[3]], main="Min ES EqRB Risk Contribution",
risk.type="percentage")
dev.off()
+# Plot the weights of portfolio 3 through time
+png(paste(figures.dir, "weights_minESEqRB.png", sep="/"))
+chart.Weights(bt.opt.minES[[3]], main="Min ES EqRB Weights")
+dev.off()
# Extract the returns from each element and chart the performance summary
ret.bt.opt <- do.call(cbind, lapply(bt.opt.minES,
@@ -149,14 +163,12 @@
}
# Chart the optimization in Risk-Reward space
-png(paste(figures.dir, "crra_RR.png", sep="/"))
-par(mfrow=c(1,2))
+png(paste(figures.dir, "crra_RR_ES.png", sep="/"))
chart.RiskReward(opt.crra, risk.col="ES")
# dev.off()
-# png(paste(figures.dir, "crra_minES.png", sep="/"))
+png(paste(figures.dir, "crra_RR_StdDev.png", sep="/"))
chart.RiskReward(opt.crra, risk.col="StdDev")
-par(mfrow=c(1,1))
dev.off()
# Compute the portfolio returns with rebalancing
Modified: pkg/PortfolioAnalytics/sandbox/RFinance2014/optimize.R
===================================================================
--- pkg/PortfolioAnalytics/sandbox/RFinance2014/optimize.R 2014-04-11 05:50:24 UTC (rev 3363)
+++ pkg/PortfolioAnalytics/sandbox/RFinance2014/optimize.R 2014-04-12 04:49:50 UTC (rev 3364)
@@ -145,7 +145,7 @@
# Add factor exposure constraint to limit portfolio beta
portf.dn <- add.constraint(portf.dn, type="factor_exposure", B=betas,
- lower=-0.5, upper=0.5)
+ lower=-0.25, upper=0.25)
# portf.dn <- add.constraint(portf.dn, type="leverage_exposure", leverage=2)
# generate random portfolios
@@ -159,7 +159,8 @@
}
# Add objective to maximize return
-portf.dn.StdDev <- add.objective(portf.dn, type="return", name="mean")
+portf.dn.StdDev <- add.objective(portf.dn, type="return", name="mean",
+ target=0.0015)
# Add objective to target a portfolio standard deviation of 2%
portf.dn.StdDev <- add.objective(portf.dn.StdDev, type="risk", name="StdDev",
target=0.02)
@@ -199,7 +200,7 @@
# Add risk budget objective with upper limit on percentage contribution
portf.minES.RB <- add.objective(portf.minES, type="risk_budget",
- name="ES", max_prisk=0.2)
+ name="ES", max_prisk=0.3)
# Relax the box constraint
portf.minES.RB$constraints[[2]]$max <- rep(1,ncol(R))
@@ -207,7 +208,7 @@
# Add risk budget objective to minimize concentration of percentage component
# contribution to risk. Concentration is defined as the Herfindahl-Hirschman
-# Index (HHI). $\sum_{i=1}^n x_i^2$
+# Index (HHI). $\sum_i x_i^2$
portf.minES.EqRB <- add.objective(portf.minES, type="risk_budget",
name="ES", min_concentration=TRUE)
# relax the box constraint
@@ -233,7 +234,7 @@
} else {
# Run the optimization
opt.minES <- optimize.portfolio(R, portf, optimize_method="DEoptim",
- search_size=2000, trace=TRUE, traceDE=0,
+ search_size=5000, trace=TRUE, traceDE=0,
message=TRUE)
cat("opt.minES complete. Saving results to ", results.dir, "\n")
save(opt.minES, file=paste(results.dir, "opt.minES.rda", sep="/"))
@@ -259,6 +260,7 @@
rebalance_on=rebal.freq,
training_period=training,
trailing_periods=trailing,
+ search_size=5000,
traceDE=0, message=TRUE)
cat("bt.opt.minES complete. Saving results to ", results.dir, "\n")
save(bt.opt.minES, file=paste(results.dir, "bt.opt.minES.rda", sep="/"))
@@ -299,7 +301,7 @@
min=0.05, max=0.4)
portf.crra <- add.objective(portf.crra, type="return",
- name="CRRA", arguments=list(lambda=5))
+ name="CRRA", arguments=list(lambda=10))
# I just want these for plotting
# Set multiplier=0 so that it is calculated, but does not affect the optimization
@@ -336,6 +338,85 @@
save(bt.opt.crra, file=paste(results.dir, "bt.opt.crra.rda", sep="/"))
}
+##### RP Demo #####
+cat("Random portfolio method comparison\n")
+if(file.exists("optimization_figures/rp_plot.png")){
+ cat("file already exists\n")
+} else {
+ portf.lo <- portfolio.spec(colnames(R))
+ portf.lo <- add.constraint(portf.lo, type="weight_sum",
+ min_sum=0.99, max_sum=1.01)
+
+ portf.lo <- add.constraint(portf.lo, type="long_only")
+
+ # Use the long only portfolio previously created
+ # Generate random portfolios using the 3 methods
+ rp1 <- random_portfolios(portf.lo, permutations=5000,
+ rp_method='sample')
+ rp2 <- random_portfolios(portf.lo, permutations=5000,
+ rp_method='simplex')
+ rp3 <- random_portfolios(portf.lo, permutations=5000,
+ rp_method='grid')
+
+ # Calculate the portfolio mean return and standard deviation
+ rp1_mean <- apply(rp1, 1, function(x) mean(R %*% x))
+ rp1_StdDev <- apply(rp1, 1, function(x) StdDev(R, weights=x))
+ rp2_mean <- apply(rp2, 1, function(x) mean(R %*% x))
+ rp2_StdDev <- apply(rp2, 1, function(x) StdDev(R, weights=x))
+ rp3_mean <- apply(rp3, 1, function(x) mean(R %*% x))
+ rp3_StdDev <- apply(rp3, 1, function(x) StdDev(R, weights=x))
+
+ x.assets <- StdDev(R)
+ y.assets <- colMeans(R)
+
+ x.lower <- min(x.assets) * 0.9
+ x.upper <- max(x.assets) * 1.1
+ y.lower <- min(y.assets) * 0.9
+ y.upper <- max(y.assets) * 1.1
+
+ png("optimization_figures/rp_plot.png")
+ # plot feasible portfolios
+ plot(x=rp1_StdDev, y=rp1_mean, col="gray", main="Random Portfolio Methods",
+ ylab="mean", xlab="StdDev", xlim=c(x.lower, x.upper),
+ ylim=c(y.lower, y.upper))
+ points(x=rp2_StdDev, y=rp2_mean, col="red", pch=2)
+ points(x=rp3_StdDev, y=rp3_mean, col="green", pch=5)
+ points(x=x.assets, y=y.assets)
+ text(x=x.assets, y=y.assets, labels=colnames(R), pos=4, cex=0.8)
+ legend("bottomright", legend=c("sample", "simplex", "grid"),
+ col=c("gray", "red", "green"),
+ pch=c(1, 2, 5), bty="n")
+ dev.off()
+}
+
+cat("Random portfolio simplex method fev biasing\n")
+if(file.exists("optimization_figures/fev_plot.png")){
+ cat("file already exists\n")
+} else {
+ png("optimization_figures/fev_plot.png")
+ fev <- 0:5
+ x.assets <- StdDev(R)
+ y.assets <- colMeans(R)
+ par(mfrow=c(2, 3))
+ for(i in 1:length(fev)){
+ rp <- rp_simplex(portfolio=portf.lo, permutations=2000, fev=fev[i])
+ tmp.mean <- apply(rp, 1, function(x) mean(R %*% x))
+ tmp.StdDev <- apply(rp, 1, function(x) StdDev(R=R, weights=x))
+ x.lower <- min(c(tmp.StdDev, x.assets)) * 0.85
+ x.upper <- max(c(tmp.StdDev, x.assets)) * 1.15
+ y.lower <- min(c(tmp.mean, y.assets)) * 0.85
+ y.upper <- max(c(tmp.mean, y.assets)) * 1.15
+ plot(x=tmp.StdDev, y=tmp.mean, main=paste("FEV =", fev[i]),
+ ylab="mean", xlab="StdDev", col=rgb(0, 0, 100, 50, maxColorValue=255),
+ xlim=c(x.lower, x.upper),
+ ylim=c(y.lower, y.upper))
+ points(x=x.assets, y=y.assets)
+ text(x=x.assets, y=y.assets, labels=colnames(R), pos=4, cex=0.8)
+ }
+ par(mfrow=c(1,1))
+ dev.off()
+}
+
# # Calculate the turnover per period
# turnover.rebalancing <- function(object){
# weights <- extractWeights(object)
Modified: pkg/PortfolioAnalytics/sandbox/RFinance2014/presentation.Rmd
===================================================================
--- pkg/PortfolioAnalytics/sandbox/RFinance2014/presentation.Rmd 2014-04-11 05:50:24 UTC (rev 3363)
+++ pkg/PortfolioAnalytics/sandbox/RFinance2014/presentation.Rmd 2014-04-12 04:49:50 UTC (rev 3364)
@@ -2,23 +2,15 @@
% Ross Bennett
% May 16, 2014
-<!---
-title: "R/Finance 2014:Complex Portfolio Optimization with PortfolioAnalytics"
-author: Ross Bennett
-date: May 16, 2014
--->
-
-```{r, echo=FALSE}
-library(knitr)
-opts_chunk$set(fig.height=4.5, fig.cap="", tidy=FALSE, cache=TRUE)
-```
-
-
# Portfolio Optimization
## General
TODO: Add some general comments here about goals and pitfalls of optimization in the context of constructing a portfolio.
+<!---
+comments
+-->
+
## Modern Portfolio Theory
"Modern" Portfolio Theory (MPT) was introduced by Harry Markowitz in 1952.
@@ -32,14 +24,17 @@
How do we define risk?
+<!---
+comments
+-->
+
## Portfolio Optimization Objectives
* Minimize Risk
* Volatility
* Tail Loss (VaR, ES)
* Other Downside Risk Measure
* Maximize Risk Adjusted Return
- * Sharpe Ratio
- * Modified Sharpe Ratio
+ * Sharpe Ratio, Modified Sharpe Ratio
* Several Others
* Risk Budgets
* Equal Component Contribution to Risk (i.e. Risk Parity)
@@ -47,20 +42,23 @@
* Maximize a Utility Function
* Quadratic, CRRA, CARA, etc.
+<!---
+comments
+-->
+
# PortfolioAnalytics
## Overview
PortfolioAnalytics is an R package designed to provide numerical solutions and visualizations for portfolio optimization problems with complex constraints and objectives.
-## Key Features
-
* Support for multiple constraint and objective types
+* An objective function can be any valid R function
* Modular constraints and objectives
-* An objective function can be any valid R function
-* Custom moments
+* Support for user defined moment functions
+* Visualizations
* Solver agnostic
-* Visualizations
+* Support for parallel computing
<!---
The key points to make here are:
@@ -88,12 +86,32 @@
* Particle Swarm Optimization (pso)
* Generalized Simulated Annealing (GenSA)
+<!---
+Brief explanation of each solver and what optimization problems (constraints and objectives) are supported
+-->
+
## Random Portfolios
-TODO: Add graphic comparing the three methods
+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.
+
+<!---
+The sample method to generate random portfolios is based on an idea by Pat Burns. This is the most flexible method, but also the slowest, and can generate portfolios to satisfy leverage, box, group, and position limit constraints.
+
+The simplex method to generate random portfolios is based on a paper by W. T. Shaw. The simplex method is useful to generate random portfolios with the full investment constraint, where the sum of the weights is equal to 1, and min box constraints. Values for min_sum and max_sum of the leverage constraint will be ignored, the sum of weights will equal 1. All other constraints such as the box constraint max, group and position limit constraints will be handled by elimination. If the constraints are very restrictive, this may result in very few feasible portfolios remaining. Another key point to note is that the solution may not be along the vertexes depending on the objective. For example, a risk budget objective will likely place the portfolio somewhere on the interior.
+
+The grid method to generate random portfolios is based on the gridSearch function in NMOF package. The grid search method only satisfies the min and max box constraints. The min_sum and max_sum leverage constraint will likely be violated and the weights in the random portfolios should be normalized. Normalization may cause the box constraints to be violated and will be penalized in constrained_objective.
+-->
+
+## Comparison of Random Portfolio Methods
+![](optimization_figures/rp_plot.png)
+
## Random Portfolios: Simplex Method
-TODO: Add graphic with different fev biasing values
+![](optimization_figures/fev_plot.png)
+
## Workflow
TODO: Add a nice graphic here (Guy might have one)
@@ -119,8 +137,14 @@
* 15 Mid Cap
* 5 Small Cap
+```{r, eval=FALSE, tidy=FALSE}
+equity.data <- cbind(largecap_weekly[,1:15],
+ midcap_weekly[,1:15],
+ smallcap_weekly[,1:5])
+```
+
## Distribution of Monthly Returns
-![alt text](data_figures/equity_box.png)
+![](data_figures/equity_box.png)
## Minimum Variance Portfolio
Consider a portfolio of stocks. Our objective to minimize portfolio variance subect to full investment and box constraints. We will use out of sample backtesting to compare the sample covariance matrix estimate and a Ledoit-Wolf shinkage estimate.
@@ -129,19 +153,20 @@
Demonstrate a custom moments function to compare a sample covariance matrix estimate and a Ledoit-Wolf shrinkage covariance matrix estimate. An alternative is a robust (MCD, MVE, etc.) estimate, DCC GARCH model, factor model, etc.
-->
-## Data
-```{r, eval=FALSE}
-equity.data <- cbind(largecap_weekly[,1:15],
- midcap_weekly[,1:15],
- smallcap_weekly[,1:5])
-```
-
## Specify Portfolio
```{r,eval=FALSE}
+# Specify an initial portfolio
stocks <- colnames(equity.data)
portf.init <- portfolio.spec(stocks)
+
+# Add full investment constraint such that the weights sum to 1
portf.minvar <- add.constraint(portf.init, type="full_investment")
+
+# Add box constraint such that no asset can have a weight of greater than
+# 20% or less than 1%
portf.minvar <- add.constraint(portf.minvar, type="box", min=0.01, max=0.2)
+
+# Add objective to minimize portfolio variance
portf.minvar <- add.objective(portf.minvar, type="risk", name="var")
```
@@ -152,9 +177,9 @@
## Ledoit-Wolf Shrinkage Estimate
The default function for `momentFUN` is `set.portfolio.moments`. We need to write our own function to estimate the covariance matrix.
```{r, eval=FALSE}
+# Function to estimate covariance matrix via Ledoit-Wolf shrinkage
lw.sigma <- function(R, ...){
out <- list()
- # estimate covariance matrix via ledoit-wolf shrinkage
out$sigma <- lwShrink(R)$cov
return(out)
}
@@ -164,20 +189,27 @@
```{r, eval=FALSE}
# Set rebalancing frequency
rebal.freq <- "quarters"
+
# Training Period
training <- 400
+
# Trailing Period
trailing <- 250
```
+<!---
+Explain each of the rebalancing parameters
+-->
-
## Run Optimization
-```{r, eval=FALSE}
+```{r, eval=FALSE, tidy=FALSE}
+# Backtest using sample covariance matrix estimate
opt.minVarSample <- optimize.portfolio.rebalancing(equity.data, portf.minvar,
optimize_method="ROI",
rebalance_on=rebal.freq,
training_period=training,
trailing_periods=trailing)
+
+# Backtest using Ledoit-Wolf shrinkage covariance matrix estimate
opt.minVarLW <- optimize.portfolio.rebalancing(equity.data, portf.minvar,
optimize_method="ROI",
momentFUN=lw.sigma,
@@ -186,20 +218,16 @@
trailing_periods=trailing)
```
-## Chart Weights
+## Chart Weights Through Time
```{r, eval=FALSE}
chart.Weights(opt.minVarSample, main="minVarSample Weights", legend.loc=NULL)
chart.Weights(opt.minVarLW, main="minVarLW Weights", legend.loc=NULL)
```
+![](optimization_figures/weights_minVarSample.png)
+![](optimization_figures/weights_minVarLW.png)
-## Sample Estimate
-![alt text](optimization_figures/weights_minVarSample.png)
-
-## Ledoit-Wolf Shrinkage Estimate
-![alt text](optimization_figures/weights_minVarLW.png)
-
## Returns
-Compute the rebalancing returns and chart the performance summary
+Compute the portfolio rebalancing returns and chart the performance.
```{r, eval=FALSE}
ret.minVarSample <- summary(opt.minVarSample)$portfolio_returns
ret.minVarRobust <- summary(opt.minVarLW)$portfolio_returns
@@ -209,46 +237,79 @@
```
## Performance Summary
-![alt text](optimization_figures/ret_minVar.png)
+![](optimization_figures/ret_minVar.png)
# Example 2
## Market Neutral Portfolio
-Consider a portfolio of stocks. Our objective to maximize portfolio return and minimize portfolio StdDev with a target of 0.02 subject to Dollar neutral, beta neutral, box, and position limit constraints. We will use the same data considered in example 1.
+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. We will use the same data considered in Example 1.
+<!---
+comments
+-->
+
## Specify Portfolio: Contraints
```{r, eval=FALSE, tidy=FALSE}
portf.init <- portfolio.spec(stocks)
+
+# Add constraint such that the portfolio weights sum to 0*
portf.dn <- add.constraint(portf.init, 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)
+
+# Compute the betas of each stock
betas <- t(CAPM.beta(equity.data, market, Rf))
+
+# Add constraint such that the portfolio beta is between -0.25 and 0.25
portf.dn <- add.constraint(portf.dn, type="factor_exposure", B=betas,
- lower=-0.5, upper=0.5)
+ lower=-0.25, upper=0.25)
```
+<!---
+explain the constraints
+-->
+
## Specify Portfolio: Objectives
```{r,eval=FALSE, tidy=FALSE}
-portf.dn.StdDev <- add.objective(portf.dn, type="return", name="mean")
+# 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)
```
+<!---
+explain the objectives, specifically the target
+-->
+
## Run Optimization
```{r, eval=FALSE, tidy=FALSE}
+# Generate random portfolios
rp <- random_portfolios(portf.dn, 10000, "sample", eliminate=TRUE)
+# Run the optimization
opt.dn <- optimize.portfolio(equity.data, portf.dn.StdDev,
optimize_method="random", rp=rp,
trace=TRUE)
```
+<!---
+generate a set of random portfolios and then pass directly to optimize.portfolio. Could just specify optimize_method = "random" and will automatically generate for you.
+-->
+
## Plot Results
```{r, eval=FALSE, tidy=FALSE}
plot(opt.dn, main="Dollar Neutral Portfolio", risk.col="StdDev", neighbors=10)
```
-![alt text](optimization_figures/opt_dn.png)
+![](optimization_figures/opt_dn.png)
# Example 3
@@ -265,55 +326,78 @@
* Emerging Markets (EM)
* Global Macro (GM)
+## Data
+```{r, eval=FALSE, tidy=FALSE}
+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")
+```
## Monthly Returns
-![alt text](data_figures/relative_barvar.png)
-![alt text](data_figures/directional_barvar.png)
+![](data_figures/relative_barvar.png)
+![](data_figures/directional_barvar.png)
## Distribution of Monthly Returns
-![alt text](data_figures/edhec_box.png)
+![](data_figures/edhec_box.png)
## 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 portfolio expected shortfall, then risk budget percent contribution limit, then equal risk contribution limit.
+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 Expected Shortfall
* Minimize Expected Shortfall with Risk Budget Limit
* Minimize Expected Shortfall with Equal Risk Contribution
-Add risk budget objective to minimize concentration of percentage component contribution to risk. Concentration is defined as the Herfindahl-Hirschman Index (HHI). $\sum_{i=1}^n x_i^2$
+Add risk budget objective to minimize concentration of percentage component contribution to risk. Concentration is defined as the Herfindahl-Hirschman Index (HHI). $\sum_i x_i^2$
-## Data
-```{r, eval=FALSE}
-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")
-```
+<!---
+comments
+-->
## Specify Initial Portfolio
```{r, eval=FALSE, tidy=FALSE}
+# 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)
```
+<!---
+basic comments about setting up an initial portfolio
+-->
+
## Add Objectives
```{r, eval=FALSE, tidy=FALSE}
+# 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.2)
+ 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)
```
@@ -324,16 +408,22 @@
## Run Optimization
```{r, eval=FALSE, tidy=FALSE}
+# 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=2000, trace=TRUE, traceDE=0)
+ search_size=5000, trace=TRUE, traceDE=0)
```
+<!---
+explain how portf is a list of portfolios and passed to optimize.portfolio
+-->
+
## Plot in Risk-Return Space
-![alt text](optimization_figures/opt_minES.png)
+![](optimization_figures/opt_minES.png)
## Chart Risk Budgets
```{r, eval=FALSE, tidy=FALSE}
@@ -343,41 +433,40 @@
chart.RiskBudget(opt.minES[[3]], main="Equal ES Component Contribution",
risk.type="percentage", neighbors=10)
```
+![](optimization_figures/rb_minES.png)
+![](optimization_figures/eqrb_minES.png)
-## Risk Budget 1
-![alt text](optimization_figures/rb_minES.png)
-
-## Risk Budget 2
-![alt text](optimization_figures/eqrb_minES.png)
-
-## Rebalancing Parameters
+## Set Rebalancing Parameters and Run Backtest
```{r, eval=FALSE, tidy=FALSE}
# Set rebalancing frequency
rebal.freq <- "quarters"
+
# Training Period
training <- 120
+
# Trailing Period
trailing <- 72
-```
-## Run Backtest
-```{r, eval=FALSE, tidy=FALSE}
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)
```
-## Min ES Risk Contributions Through Time
-![alt text](optimization_figures/risk_minES.png)
+## Min ES Risk Contributions and Weights Through Time
+![](optimization_figures/risk_minES.png)
+![](optimization_figures/weights_minES.png)
-## Min ES Risk Budget Limit Risk Contributions Through Time
-![alt text](optimization_figures/risk_minESRB.png)
+## Min ES Risk Budget Limit Risk Contributions and Weights Through Time
+![](optimization_figures/risk_minESRB.png)
+![](optimization_figures/weights_minESRB.png)
-## Min ES Equal Component Contribution Risk Contributions Through Time
-![alt text](optimization_figures/risk_minESEqRB.png)
+## Min ES Equal Component Contribution Risk Contributions and Weights Through Time
+![](optimization_figures/risk_minESEqRB.png)
+![](optimization_figures/weights_minESEqRB.png)
## Compute Returns and Chart Performance
@@ -387,27 +476,28 @@
colnames(ret.bt.opt) <- c("min ES", "min ES RB", "min ES Eq RB")
charts.PerformanceSummary(ret.bt.opt)
```
-![alt text](optimization_figures/ret_minES.png)
+![](optimization_figures/ret_minES.png)
# Example 4
## 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 Martinelli paper.
+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 Martinelli paper. We use the same data as Example 3.
+TODO: Add equation
+
<!---
Demonstrate a custom moment function and a custom objective function.
-->
-## CRRA
-TODO: Add equation
+## Define a function to compute CRRA
```{r, eval=FALSE, tidy=FALSE}
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 <- 0.5 * lambda * M2.w
+ 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
@@ -418,15 +508,27 @@
## Specify Portfolio
```{r, eval=FALSE, tidy=FALSE}
+# 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=5))
+ name="CRRA", arguments=list(lambda=10))
```
+<!---
+Focus on how CRRA is added as an objective
+-->
+
## Run Optimization
```{r, eval=FALSE, tidy=FALSE}
opt.crra <- optimize.portfolio(R, portf.crra, optimize_method="DEoptim",
@@ -434,10 +536,15 @@
momentFUN="crra.moments")
```
+<!---
+remember to specify a momentFUN to match the arguments in CRRA
+-->
+
## Chart Results
-![alt text](optimization_figures/crra_RR.png)
+![](optimization_figures/crra_RR_ES.png)
+![](optimization_figures/crra_RR_StdDev.png)
-## Backtest
+## Run Backtest and Compute Returns
```{r, eval=FALSE, tidy=FALSE}
bt.opt.crra <- optimize.portfolio.rebalancing(R, portf.crra,
optimize_method="DEoptim",
@@ -447,16 +554,21 @@
rebalance_on=rebal.freq,
training_period=training,
trailing_periods=trailing)
+
+ret.crra <- summary(bt.opt.crra)$portfolio_returns
+colnames(ret.crra) <- "CRRA"
```
-## Compute Returns and Chart Performance
+<!---
+Run optimization and extract the portfolio rebalancing returns from the summary method
+-->
+
+## Chart Performance
```{r, eval=FALSE, tidy=FALSE}
-ret.crra <- summary(bt.opt.crra)$portfolio_returns
-colnames(ret.crra) <- "CRRA"
charts.PerformanceSummary(cbind(ret.bt.opt, ret.crra),
main="Optimization Performance")
```
-![alt text](optimization_figures/ret_crra.png)
+![](optimization_figures/ret_crra.png)
# Conclusion
@@ -474,6 +586,19 @@
- Google for funding the Google Summer of Code for PortfolioAnalytics and many other proposals for R
-->
+## References
[TRUNCATED]
To get the complete diff run:
svnlook diff /svnroot/returnanalytics -r 3364
More information about the Returnanalytics-commits
mailing list