# [R-SIG-Finance] Static Portfolio Optimization

Thomas Etheber etheber at gmx.de
Mon Sep 28 20:29:25 CEST 2009

```Brian G. Peterson wrote:
> Jesse Velez wrote:
>> Is there any function or example in R or Rmetrics of static portfolio
>> optimization, where I have a vector of expected returns for N assets
>> and a
>> expected covariance matrix of said N assets all at a fixed time (say
>> generated from a MFM risk and return model).
>>
>> fPortfolio, Portfolio, portfolio.optim appear to all require time
>> series of
>> returns to generate the expected return and historical covariance
>> matrix for
>> use in creating weights.
>>
>> Ideally, I hope to find an example that allows easily allows Long/Short
>> weights to make the portfolio  market neutral (i.e. Summation of Weights
>> =0).
>>
> All the implementations of Markowitz style mean/variance optmization
>
> Plenty of information on the list archives from before all these
>
> Regards,
>
>  - Brian
>

Hi there,

I also had the problem with fixed parameter inputs some time ago.
Implementing methods to perform this tasks would certainly be a nice
improvement of the library (as would be some help/error messages if the
covariance matrix is not positive semidefinite).
sounds like reinventing the wheel, but might nevertheless be needed to

In order to use prespecified estimates as inputs I helped myself with
overwriting some of the methods. It's not a nice solution, but it worked
for me. You will find the methods attached below.
I didn't check the code again, but I think it should work. Please note,
some other methods of Rmetrics and fPortfolio might rely on the
timeseries objects and might not work properly.

Hth
Thomas

>>>
require(MBESS)
require(fPortfolio)
rm(list=ls())
spec <- portfolioSpec()
constraints <- NULL

portfolioData <- function (data, spec = portfolioSpec())
{
ans = NULL
if(class(data) == "timeSeries") {
data = sort(data)
nAssets = dim(data)[2]
statistics = portfolioStatistics(data, spec)
tailRisk = spec at model\$tailRisk
ans <- new("fPFOLIODATA", data = list(series = data, nAssets =
nAssets),
statistics = statistics, tailRisk = tailRisk)
}
if(class(data) == "list") {
statistics = list(mu = data\$mu, Sigma = data\$Sigma )
attr(statistics, "estimator") = spec at model\$estimator
ans <- new("fPFOLIODATA", data = list( nAssets = length(data\$mu)
), statistics = statistics, tailRisk = list() )
}
ans
}

####################################################################################

.efficientConstrainedMVPortfolio <- function (data, spec, constraints)
{
if (!inherits(data, "fPFOLIODATA"))
data = portfolioData(data, spec)
mu = getMu(data)
Sigma = getSigma(data)
nAssets = getNumberOfAssets(data)
targetAlpha = getTargetAlpha(spec)
solver = getSolver(spec)
stopifnot(solver == "quadprog" | solver == "Rdonlp2")
}
else if (solver == "Rdonlp2") {
portfolio = solveRDonlp2(data, spec, constraints)
}
weights = portfolio\$weights
attr(weights, "status") <- portfolio\$status
names(weights) = names(mu)
targetReturn = matrix(as.numeric(mu %*% weights), nrow = 1)
colnames(targetReturn) <- getEstimator(spec)[1]
covTargetRisk = sqrt(as.numeric(weights %*% Sigma %*% weights))
#   x = getSeries(data)@Data %*% weights
#   VaR = quantile(x, targetAlpha, type = 1)
#   CVaR = VaR - 0.5 * mean(((VaR - x) + abs(VaR - x)))/targetAlpha
#   targetRisk = matrix(c(covTargetRisk, CVaR, VaR), nrow = 1)
#   colnames(targetRisk) <- c("cov", paste(c("CVaR.", "VaR."),
#   targetAlpha * 100, "%", sep = ""))
targetRisk = matrix(c(covTargetRisk), nrow = 1)
## is needed to use the plotting functions....
targetRisk = matrix(c(covTargetRisk, covTargetRisk ), nrow = 1)
colnames(targetRisk) <- c( "cov", "dummy" )
new("fPORTFOLIO", call = match.call(), data = list(data = data),
spec = list(spec = spec), constraints = as.character(constraints),
portfolio = list(weights = weights, targetReturn = targetReturn,
targetRisk = targetRisk, targetAlpha = targetAlpha,
status = portfolio\$status), title = paste("Constrained MV
Portfolio - Solver:",
solver), description = .description())
}

####################################################################################

.minvarianceConstrainedMVPortfolio <- function (data, spec, constraints)
{
if (!inherits(data, "fPFOLIODATA"))
data = portfolioData(data, spec)
mu = getMu(data)
Sigma = getSigma(data)
nAssets = getNumberOfAssets(data)
targetAlpha = getTargetAlpha(spec)
.minVariancePortfolioFun = function(x, data, spec, constraints) {
spec at portfolio\$targetReturn = x
ans = .efficientConstrainedMVPortfolio(data = data, spec = spec,
constraints = constraints)
f = getTargetRisk(ans)[1]
attr(f, "targetReturn") <- getTargetReturn(ans)
attr(f, "targetRisk") <- getTargetRisk(ans)[1]
attr(f, "weights") <- getWeights(ans)
f
}
minVar = optimize(.minVariancePortfolioFun, interval = range(mu),
data = data, spec = spec, constraints = constraints,
tol = .Machine\$double.eps^0.5)
weights = attr(minVar\$objective, "weights")
names(weights) = names(mu)
targetReturn = spec at portfolio\$targetReturn =
as.numeric(attr(minVar\$objective,
"targetReturn"))
targetReturn = matrix(targetReturn, nrow = 1)
colnames(targetReturn) <- spec at model\$estimator[1]
covTargetRisk = as.numeric(attr(minVar\$objective, "targetRisk"))
# x = getSeries(data)@Data %*% weights
# VaR = quantile(x, targetAlpha, type = 1)
# CVaR = VaR - 0.5 * mean(((VaR - x) + abs(VaR - x)))/targetAlpha
#targetRisk = matrix(c(covTargetRisk, CVaR, VaR), nrow = 1)
#colnames(targetRisk) <- c("cov", paste(c("CVaR.", "VaR."),
targetRisk = matrix(c(covTargetRisk), nrow = 1)
## is needed to use the plotting functions....
targetRisk = matrix(c(covTargetRisk, covTargetRisk ), nrow = 1)
colnames(targetRisk) <- c( "cov", "dummy" )
new("fPORTFOLIO", call = match.call(), data = list(data = data),
spec = list(spec = spec), constraints = as.character(constraints),
portfolio = list(weights = weights, targetReturn = targetReturn,
targetRisk = targetRisk, targetAlpha = targetAlpha,
status = 0), title = "Minimum Variance Portfolio",
description = .description())
}

show.fPORTFOLIO <- function (object)
{
cat("\nTitle:\n ")
cat(getTitle(object), "\n")
cat("\nCall:\n ")
print.default(getCall(object))
cat("\nPortfolio Weight(s):\n")
weights = round(getWeights(object), digits = 4)
if (length(weights) == 1) {
cat(" ", weights, "\n")
}
else {
print.table(weights)
}
cat("\nRiskBudget(s):\n")
riskBudgets = round(getCovRiskBudgets(object), digits = 4)
if (length(riskBudgets) == 1) {
cat(" ", riskBudgets, "\n")
}
else {
print.table(riskBudgets)
}
if (FALSE) {
if (!is.na(getTailRiskBudgets(object))) {
cat("\nRiskBudget(s):\n")
riskBudgets = round(getTailRiskBudgets(object), digits = 4)
if (length(riskBudgets) == 1) {
cat(" ", riskBudgets, "\n")
}
else {
print.table(riskBudgets)
}
}
}
targetReturn = object at portfolio\$targetReturn
targetRisk = object at portfolio\$targetRisk
spec = getSpec(object)
cat("\nTarget Risk(s) and Return(s):\n")
if (is.null(dim(targetReturn))) {
targetReturn = matrix(targetReturn, nrow = 1)
colnames(targetReturn) = getEstimator(spec)[1]
}
if (is.null(dim(targetRisk))) {
targetRisk = matrix(targetRisk, nrow = length(targetRisk) )
colnames(targetRisk) = getEstimator(spec)[2]
}
target = cbind(targetReturn, targetRisk)
colnames(target) = c(colnames(targetReturn), colnames(targetRisk) )
if (nrow(target) == 1) {
print(target[1, ])
}
else {
print(target)
}
cat("\nDescription:\n ")
cat(getDescription(object), "\n")
invisible(object)
}

setMethod("show", "fPORTFOLIO", show.fPORTFOLIO)

####################################################################################

.portfolioConstrainedMVFrontier <- function (data, spec, constraints)
{
if (!inherits(data, "fPFOLIODATA"))
data = portfolioData(data, spec)
mu = getMu(data)
Sigma = getSigma(data)
nAssets = getNumberOfAssets(data)
targetAlpha = getTargetAlpha(spec)
nFrontierPoints = getNFrontierPoints(spec)
targetReturn = targetRisk = targetWeights = error = NULL
Spec = spec
solver = spec at solver\$solver
Spec at portfolio\$weights = rep(1/nAssets, nAssets)
k = 0
solverType = spec at solver\$solver
status = NULL
for (nTargetReturn in seq(min(mu), max(mu), length = nFrontierPoints)) {
k = k + 1
setTargetReturn(Spec) <- nTargetReturn
nextPortfolio = .efficientConstrainedMVPortfolio(data = data,
spec = Spec, constraints = constraints)
Spec at portfolio\$weights = nextPortfolio at portfolio\$weights
targetReturn = rbind(targetReturn,
nextPortfolio at portfolio\$targetReturn)
targetRisk = rbind(targetRisk, nextPortfolio at portfolio\$targetRisk)
nextWeights = nextPortfolio at portfolio\$weights
names(nextWeights) = names(mu)
status = c(status, nextPortfolio at portfolio\$status)
targetWeights = rbind(targetWeights, t(nextWeights))
}
Index = (1:length(status))[status == 0]
weights = targetWeights
colnames(weights) = names(mu)
weights = weights[Index, ]
DIM = dim(targetReturn)[2]
targetReturn = targetReturn[Index, ]
targetReturn = matrix(targetReturn, ncol = DIM)
colnames(targetReturn) = getEstimator(spec)[1]
targetRisk = targetRisk[Index, ]
new("fPORTFOLIO", call = match.call(), data = list(data = data),
spec = list(spec = spec), constraints = as.character(constraints),
portfolio = list(weights = weights, targetReturn = targetReturn,
targetRisk = targetRisk, targetAlpha = targetAlpha,
status = status), title = "Constrained MV Frontier",
description = .description())
}

####################################################################################

# You should be able to specify the data in this form:
mu <- c( 0.1, 0.08, 0.065)
sigma <- c( 0.18, 0.12, 0.09 )

correlationMatrix <- rbind( c( 1, 0.8, 0.9 ),
c( 0.8, 1, 0.75),
c( 0.9, 0.75, 1) )

covarianceMatrix <- cor2cov(correlationMatrix, sigma )

data = list( mu = mu, Sigma = covarianceMatrix )

# And then do the optimisation
frontier <- portfolioFrontier(data, spec = spec, constraints )

```