Portfolio Optimization With R

R offers so many benefits to those interested in Quantitative Finance. It makes life super easy in terms of getting data, and in this particular case analyzing the data and constructing an optimal portfolio. Doing this in Excel is arduous. Getting bulk data via an API is slow. And automating calculations for the efficient frontier takes forever. Python is not on R’s level yet in terms of packages for finance either.

In general, in order to construct a minimum variance portfolio you need three things:

  • Historical Returns
  • Historical Volatility
  • Some sort of covariance matrix or correlation matrix

In order to run this script, we will need a few packages. I would like to highlight one in particular, fPortfolio. This package is specifically geared towards portfolio optimization.

We need to prepare a time series object in order to plot the Efficient Frontier for a given portfolio. First, we will construct a vector of tickers and gather prices for them using the getSymbols function within quantmod. We will next calculate returns and convert the data to a time series object.

We can now calculate and plot the Efficient Frontier. We will do this by using the portfolioFrontier() function within R. This is what makes this package so great. We can overlay many different series’ on top of the frontier. The options are displayed below. We can also output the covariance matrix and correlation matrix for our portfolio of assets. On top of all of this, we can extract certain portfolios such as the Minimum Variance Portfolio or Max Return Portfolio as well as their individual characteristics. These characteristics include the expected return for each asset, the expected volatility for each asset, as well as different Value at Risk calculations. We can isolate any of these characteristics as well to graph and compare. Let’s examine some.

We can output the weights generated by the frontier and save them to a CSV file. We can also output the mean and volatility for each point also.

 

Let’s examine the weights of each point on the frontier graphically:

We can annualize this data and plot the risk returns on a scatter plot also. Note we can also annualize the returns data with the performance analytics library also as mentioned before. We can also plot the Sharpe Ratio of each point on the frontier on a scatter graph also.

Let’s examine the correlation matrix and covariance matrix associated with our assets also.

Next, we can examine specific classes of portfolios that could lie on the frontier. These can include the Tangency Portfolio, Minimum Variance Portfolio. In the documentation for fPortfolio, the following options are available as portfolio classes:

  • feasiblePortfolio
  • cmlPortfolio (deprecated)
  • tangencyPortfolio
  • efficientPortfolio
  • minvariancePortfolio

Let’s output some basic stats for the Minimum Variance Portfolio and Tangency Portfolio. The Tangency Portfolio is one where the Sharpe Ratio is maximized. We can also use the ggplot2 library to output some awesome graphs.

    

We can also examine the Efficient Frontier under different constraints and specifications. I provided a list of the available constraints and specifications below.

Constraints List (Truncated)

minWminimum weight in asset
maxWmaximum weight in asset
eqsumWsum of weights (assets)
minsumWminimum sum of weights (assets)
maxsumWmaximum sum of weights (assets)

Specs List

setTypeSets type of portfolio optimization
setOptimizeSets what to optimize, min risk or max return
setEstimatorSets names of mean and covariance estimators
setParamsSets optional model parameters
setWeightsSets weights vector
setTargetReturnSets target return value
setTargetRiskSets target risk value
setTargetAlphaSets CVaR target alpha value
setRiskFreeRateSets risk-free rate value
setNFrontierPointsSets number of frontier points
setStatusSets status value
setSolverSets the type of solver to be used
setObjectiveSets objective function name to be used
setTraceSets the logical trace flag.

Let’s implement some constraints and specifications in our portfolio. We will allow short selling in this portfolio and set the minimum and maximum weight in one given asset throughout the entire list of tickers.

 

Let’s examine the output on a minimal level.

 

In short, fPortfolio is extremely useful when analyzing a given portfolio of assets. We could prepare good looking automated reports with this package. fPortfolio also allows for backtesting strategies also and examining portfolios under rolling time frames as well. Theoretically, we could iterate over thousands of portfolio optimization models under different constraints and compare them. The backtesting features of this module are outside the scope of this post and will be discussed in later posts.

About the author

programmingforfinance

Hi, I'm Frank. I have a passion for coding and extend it primarily within the realm of Finance.

View all posts

9 Comments

  • Hi Frank. Extremely interesting post but I can’t get it to work. Running the portfolioFrontier function throws the following error:

    Error in colnames<-(*tmp*, value = c("AXP", "C", "WFC", "AMZN", "JNJ", :
    attempt to set 'colnames' on an object with less than two dimensions

    Any suggestions on how to solve this?

    • If you have 5 stocks (columns), you need to have more than 5 observations (prices) so rows must be greater than collumns.

  • Hi. I try to replicate the results. However, the target return and sharp ratio plot y-axes values are much larger than what you plotted. Are those plots annualized return based?

  • Another thing is that the spec constraint doesn’t really constrain the asset weights as it should be. I have a warning message:
    In as.vector(invSigma %*% one)/(one %*% invSigma %*% one) :
    Recycling array of length 1 in vector-array arithmetic is deprecated.
    Use c() or as.vector() instead.
    when I run the portfolio calculation involving spec and constraints.
    I don’t know what went wrong.

  • Hi Frank. This is awesome. Thank you for sharing. I’m anxious waiting for the backtest and compare the performance of the optimized portfolio and naive diversified portfolio (1/n).

  • Error in download.file(paste(google.URL, “q=”, Symbols.name, “&startdate=”, :
    cannot open URL ‘http://finance.google.com/finance/historical?q=AXP&startdate=Jan+01,+2016&enddate=Mar+31,+2018&output=csv’
    In addition: Warning message:
    In download.file(paste(google.URL, “q=”, Symbols.name, “&startdate=”, :
    cannot open URL ‘http://finance.google.com/finance/historical?q=AXP&startdate=Jan+01,+2016&enddate=Mar+31,+2018&output=csv’: HTTP status was ‘403 Forbidden’

  • Hi Frank:
    Thank you very much for the above. After I changed the sources for the prices it seemed to work. I have had many issues with fPortfolio before but your code didn’t throw any errors apart from getting data.
    By the way, what are major differences between fPortfolio and FRAPO which appears to do the same thing.

Leave a Reply

Your email address will not be published. Required fields are marked *