user2157086
user2157086

Reputation: 575

Portfolio optimization with R with known mu and cov matrix

Would like to optimize a portfolio in fPortfolio ideally where the vector mu (returns) and the covariance matrix are already known (from some other algorithm which does the calculation). So, let's say I have the following:

mu = c(0.05,0.1,0.075,0.06)
cov=    
0.02657429 0.01805751 0.02048764 0.02110555
0.01805751 0.03781108 0.03859943 0.02959261
0.02048764 0.03859943 0.04606304 0.03043146
0.02110555 0.02959261 0.03043146 0.03880064

Now, I would like to do

efficientPortfolio(data, spec = portfolioSpec(), constraints = "LongOnly")

with returns and covariance as specfied above. How would that work?

Regards Andreas

Upvotes: 4

Views: 1820

Answers (3)

NSAA
NSAA

Reputation: 185

There is another way to write your own covariance estimator. This is explained in Portfolio Optimization with R/Rmetrics Update 2015, Diethelm Würtz, Tobias Setz, Yohan Chalabi, William Chen, Andrew Ellis, page 234.

You can do something like this:-

mu = c(0.05,0.1,0.075,0.06)
cov <- matrix(c(0.02657429, 0.01805751, 0.02048764, 0.02110555, 0.01805751, 0.03781108, 0.03859943, 0.02959261, 0.02048764, 0.03859943, 0.04606304, 0.03043146, 0.02110555, 0.02959261, 0.03043146, 0.03880064), 4, 4, dimnames=list(names(mu), names(mu))) 
lppAssets <- 100*LPP2005.RET[, c("SBI", "SPI", "LMI", "MPI")]

covtEstimator <- function (x, spec = NULL, ...) {
x.mat = as.matrix(x)
list(mu = mu, Sigma = cov) }   #Input your mean and covariance matrix here.

defaultSpec <- portfolioSpec()
setEstimator(defaultSpec) <- "covtEstimator"
setTargetReturn(defaultSpec) <- 0.06

myPort2 <- efficientPortfolio(lppAssets, defaultSpec, constraints = "LongOnly")

which also produce the same answer.

Title:
MV Efficient Portfolio 
Estimator:         covtEstimator 
Solver:            solveRquadprog 
Optimize:          minRisk 
Constraints:       LongOnly 

Portfolio Weights:
[1] 0.7316 0.1829 0.0000 0.0855

Covariance Risk Budgets:
[1] 0.1473 0.6156 0.0000 0.2370

Target Returns and Risks:
 mean     mu    Cov  Sigma   CVaR    VaR 
0.0205 0.0600 0.1986 0.1555 0.4805 0.3003 

Hope it is still not too late to answer this question! May be useful to others. Thanks

Upvotes: 1

Wolfgang Wu
Wolfgang Wu

Reputation: 864

I am not an expert in the fPortfolio package. But it looks like you need to define your own fPFOLIODATA object. In fPortfolio this is done in the portfolioData() function. So a quick and dirty solution might be to write your own function that doesn't do the covariance estimation but takes as input your estimated mu and sigma. So here is my solution:

myPortfolioData <- function(mu, sigma, data, spec){
    if (is(data, "fPFOLIODATA")) 
        return(data)
    stopifnot(class(data) == "timeSeries")
    data = sort(data)
    nAssets = NCOL(data)
    names = colnames(data)
    if (is.null(names)) 
        names = paste("A", 1:nAssets, sep = "")
    Cov = cov(data)
    rownames(Cov) <- colnames(Cov) <- names
    .data = list(series = data, nAssets = nAssets, names = names)
    .statistics <- list(mean = colMeans(data), Cov = Cov, estimator = 'other', mu = mu, Sigma = covar);
    .tailRisk = spec@model$tailRisk
    new("fPFOLIODATA", data = .data, statistics =.statistics, tailRisk = .tailRisk)
}

Let's test if it gives the same results:

library(fPortfolio)

#This is how you would usually do it
defaultSpec <- portfolioSpec()
setTargetReturn(defaultSpec) <- 0.06
lppAssets <- 100*LPP2005.RET[, c("SBI", "SPI", "LMI", "MPI")]
lppData <- portfolioData(data = lppAssets, spec = defaultSpec)
port <- efficientPortfolio(lppData, defaultSpec, constraints = "LongOnly")

#Now I am creating my own mu and sigma 
#In this case exactly the same as the estimation above to see if the results match  
mu <- c(SBI=0.0000406634, SPI=0.0841754390, LMI=0.0055315332, MPI=0.0590515119)
sigma <- matrix(c(0.015899554, -0.01274142,  0.009803865, -0.01588837,-0.012741418,  0.58461212, -0.014074691,  0.41159843,0.009803865, -0.01407469,  0.014951108, -0.02332223,-0.015888368,  0.41159843, -0.023322233,  0.53503263), 4, 4, dimnames=list(names(mu), names(mu))) 
myLppData <- myPortfolioData(mu, sigma, lppAssets, defaultSpec)
myPort <- efficientPortfolio(myLppData, defaultSpec, constraints = "LongOnly")

all.equal(port@portfolio, myPort@portfolio)

Now with your numbers:

mu <- c(SBI=0.05, SPI=0.1, LMI=0.075, MPI=0.06)
sigma <- matrix(c(0.02657429, 0.01805751, 0.02048764, 0.02110555, 0.01805751, 0.03781108, 0.03859943, 0.02959261, 0.02048764, 0.03859943, 0.04606304, 0.03043146, 0.02110555, 0.02959261, 0.03043146, 0.03880064), 4, 4, dimnames=list(names(mu), names(mu))) 
myLppData <- myPortfolioData(mu, sigma, lppAssets, defaultSpec)
myPort <- efficientPortfolio(myLppData, defaultSpec, constraints = "LongOnly")

Hope that helps!

Upvotes: 1

ennovation
ennovation

Reputation: 366

You need to do something like this:

library(quadprog)

d = rep(0,4); #4 - no. of stocks
A = rbind(rep(1,4), #1st const. --- sum of weights should be 1
                mu, #2nd const. --- returns should be positive
                diag(4) #3rd const ---- all the weights are positive   
        );
b = c(1, 0, rep(0,4) );
solve.QP(cov, d, t(A), b, meq=1)

Upvotes: 1

Related Questions