Setting Up a Minimum-Variance Portfolio Optimization in PortfolioAnalytics
Summary
The answer diagnoses a failed PortfolioAnalytics optimization call as a problem with the supplied inputs. It explains that the optimization function expects a return time series for R, rather than a vector of initial weights, and that initial weights are unnecessary for a static optimization without transaction costs. It also notes that the undefined rp argument should be removed.
For a minimum-variance setup, the response builds the portfolio specification from the return data's asset names, adds a variance objective and a full-investment constraint, then calls the optimizer with the returns and an optimization method. To target a higher expected return, it suggests adding a return constraint. The example output permits negative weights and weights above one, so the illustrated constraints do not impose long-only positions or per-asset bounds. The answer is a worked software example; its output and recommended solver may depend on the user's package setup and optimization requirements.
Key ideas
- Pass the asset return time series to the optimizer's R argument rather than portfolio weights.
- Initial weights are not needed for the stated static optimization without transaction costs.
- Use a variance objective with a full-investment constraint to seek a global minimum-variance portfolio.
- Add a return target when optimizing for a portfolio with a minimum expected return.
- The example allows short positions and weights above one because it does not set long-only or asset-level bounds.
Tags
Full text
# Why optimize.portfolio in R package PortfolioAnalytics is not working?
# Why optimize.portfolio in R package PortfolioAnalytics is not working?
I used the R-package PortfolioAnalytics for portfolio optimization. In the portfolio optimization part. I used the function optimize.portfolio to set up my optimization. However, here was the error just showed that
> Error in optimize.portfolio(R = initial_weights, portfolio = p, optimize_method = "random", : unused arguments (R = initial_weights, portfolio = p, optimize_method = "random", rp = rp, trace = TRUE)
I checked my code and I made sure everything was fine beside this step. So I am wondering this function is not working? Anybody knows how to fix this situation or recommend other package to use?
Thank you so much.
```
Here is my code:
library(PortfolioAnalytics)
library(quantmod)
library(PerformanceAnalytics)
library(zoo)
library(plotly)
# Get data of the stock
getSymbols(c("SWX","SPY","ICUI","MSFT"), src = 'yahoo', from = '2016-01-01')
Adjusted_price <- merge.zoo(SWX[,6], SPY[,6], ICUI[,6], MSFT[,6])
#Get Returns of portfolio
returns.portfolio <- CalculateReturns(Adjusted_price)
returns.portfolio <- na.omit(returns.portfolio)
#Set names of each stocks
colnames(returns.portfolio) <- c("Southwest Gas Holdings","S&P 500","ICU Medical","Microsoft")
# Meanreturns
meanReturns <- colMeans(returns.portfolio)
covMat <- cov(returns.portfolio)
#Initial weights
portfolio.spec(assets = c("SWX","SPY","ICUI","MSFT") )
initial_weights <- c("SWX" = 0.25,"SPX" = 0.25,"ICUI"=0.25,"MSFT"=0.25)
port <- intial_weights
portfolio.spec(assets = initial_weights)
#Initialize Portfolio specification
p <- portfolio.spec(assets = initial_weights)
#Add constraint
p <- add.constraint(portfolio = p, type = "weight_sum", min_sum = 1, max_sum = 1)
#Add objective
p <- add.objective(portfolio = p, type = "risk", name = "StdDev")
p <- add.objective(portfolio = p, type = "return", name = "mean")
#optimization
opt_single <- optimize.portfolio(R = initial_weights, portfolio = p, optimize_method = "random", rp = rp, trace = TRUE)
Error in optimize.portfolio(R = initial_weights, portfolio = p, optimize_method = "random", :
unused arguments (R = initial_weights, portfolio = p, optimize_method = "random", rp = rp, trace = TRUE)
```
## Answer by Stefan Voigt (score 3)
https://quant.stackexchange.com/a/33664
There are some issues with your code - you are using wrong variables as inputs/ in case you are not sure what the function arguments mean, search online for a documentation of the PortfolioPerformance functionality! Let me try to make some things clear on how to solve your optimization issue:
Your data input is fine!
```
library(PortfolioAnalytics)
library(quantmod)
library(PerformanceAnalytics)
library(zoo)
# Get data of the stock
getSymbols(c("SWX","SPY","ICUI","MSFT"), src = 'yahoo', from = '2016-01-01')
Adjusted_price <- merge.zoo(SWX[,6], SPY[,6], ICUI[,6], MSFT[,6])
```
You don't need to set any initial weights, at least not for your purpose of a static optimization without reflecting any transaction costs! The optimal portfolio in your setting is independent of the initial weights. Your initial portfolio specifications are also redundant in the code.
```
p <- portfolio.spec(assets = colnames(returns.portfolio))
```
Now, whenever you refer to the variable `p` you can change your portfolio specifications. You have correctly specified your objective function, however, I made the experience that referring to standard deviation sometimes leads to to trouble. In case you are into Markowitz Optimization you care for the Variance of the portfolio weights anyway, so I have changed this:
```
p <- add.objective(portfolio = p, type = "risk", name = "var")
p <- add.constraint(portfolio = p, type = "full_investment")
```
The `full_investment` part is equivalent to setting a constraint on the sum of the portfolio weights such that they always sum-up to 1. In your setup the investor currently only cares about the risk of the portfolio. Your optimization therefore returns the portfolio weights which attain the lowest possible portfolio variance. This is the global minimum variance portfolio. If you would like to get the efficient portfolio then you need to add an additional constraint, namely the minimal expected return. Just in case you need this, add the following line
```
p <- add.constraint(portfolio=p, type = "return", return_target=0.1/250)
```
The `return_target=0.1/250` can be replaced with any number, I have chosen it to reflect that you have daily data and in this case you would like to have a portfolio which makes 10 per cent per year in expectation.
Last but not least, the optimization part: Here you mixed up the inputs. The input `R` should be the time-series of returns you have. I also recommend to specify the way, R is optimizing the function. Your specification `rp=rp` does not make sense as R does not know what you mean with `rp`.
```
#Optimize
optimize.portfolio(R=returns.portfolio, portfolio = p,
optimize_method = "ROI", trace = TRUE)
```
It may be the case that you have to install the package `ROI` in order to run this code. What I get as output is the following:
```
***********************************
PortfolioAnalytics Optimization
***********************************
Call:
optimize.portfolio(R = returns.portfolio, portfolio = portf1,
optimize_method = "ROI", trace = TRUE)
Optimal Weights:
SWX.Adjusted SPY.Adjusted ICUI.Adjusted MSFT.Adjusted
-0.1077 1.3764 -0.0635 -0.2052
Objective Measure:
StdDev
0.008082
```Shown in full with attribution under the source's licence. Licence: CC BY-SA 4.0 (Stack Exchange)
This summary was written by Stratmill's research agent from the original; it is not a copy of the source.