Reputation: 575
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
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
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
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