0
$\begingroup$

I'm using the timeSeries and fportfolio package in R to minimize the CVaR with different constraints for a given portfolio. Everything is working out so far. However, I can't manage to set a fixed mean return. When I use setTargetReturn(cvar_spec) <- 0.04 , as in the code below, the further code ignores it and calculates the CVAR for a smaller mean return. The last function, portfolioFrontier() does not return the desired value pair as well. Does anyone know a way how to fix this?

library(timeSeries)
library(timeDate)
library(fPortfolio)

lppAssets3 <- 100 * LPP2005.RET[, 1:6]
colMeans(lppAssets3)

cvar_spec <- portfolioSpec()
setTargetReturn(cvar_spec) <- 0.04
setType(cvar_spec) <- "CVaR"
setSolver(cvar_spec) <- "solveRglpk.CVAR"
getOptimize(cvar_spec)
getSolver(cvar_spec)

box.1 <- "minW[1:6] = 0.0"
box.2 <- "maxW[1:6] = 0.5"

group.1 <- "minsumW[1:6] = 1.0"
group.2 <- "maxsumW[1:6] = 1.0"


constraints_cvar1 <- c(box.1, box.2, group.1, group.2)


minCVAR_Portfolio2 <- minriskPortfolio(lppAssets3,
                                       cvar_spec,
                                       constraints = constraints_cvar1
)
getWeights(minCVAR_Portfolio2)

CVAR_Portfolio2_frontier <- portfolioFrontier(lppAssets3,
                  cvar_spec,
                  constraints = constraints_cvar1
)
$\endgroup$
4
$\begingroup$

I don't use fPortfolio but when I run your code example, I first get an error:

## Error in add.constraint() : could not find function "add.constraint"

Nevertheless, after that, I can extract a solution:

getWeights(minCVAR_Portfolio2)
##      SBI      SPI      SII      LMI      MPI      ALT 
## 0.240491 0.000172 0.169241 0.500000 0.000000 0.090096 

Cross-checking with minCVaR in package ǸMOF` (which I maintain):

library("NMOF")
R <- as.matrix(lppAssets3)
c(minCVaR(R, q = 0.05, wmax = 0.5))
## [1] 0.240491 0.000172 0.169241 0.500000 0.000000 0.090096

So, the computation so far seems reasonable. But your problem probably is the much-too-high required return of 0.04: Inspecting lppAssets3 suggests that these are daily data. And then 4% is way too high: apply(lppAssets3, 2, max) shows you that no asset ever had a single daily return of 4% in your sample:

##     SBI     SPI     SII     LMI     MPI     ALT 
## 0.00364 0.02584 0.01201 0.00368 0.02408 0.01679 

And the column means are much closer to zero. So there simply is no feasible solution. A check:

minCVaR(R, q = 0.05, wmax = 0.5, min.return = 0.04,
        Rglpk.control = list(verbose = TRUE))
## GLPK Simplex Optimizer 5.0
## 379 rows, 384 columns, 2975 non-zeros
##       0: obj =   0.000000000e+00 inf =   1.040e+00 (2)
##     220: obj =   3.241764706e-02 inf =   3.915e-02 (1) 2
## LP HAS NO PRIMAL FEASIBLE SOLUTION
## ....

I guess here that you might mean an annual return of 4%, but then you'd have to scale it so that it is aligned with the return scenarios (e.g. 0.04/250 = 0.00016).


Update following the comment:

You can compute portfolio returns under the scenario set, and then it becomes straightforward to compute quantities of interest.

R <- as.matrix(lppAssets3)
sol <- minCVaR(R, q = 0.05, wmax = 0.5)
p.rt <- c(R %*% sol)

I use c() to drop (unnecessary) attributes. You now have a univariate return series p.rt:

vol <- sd(p.rt)
## [1] 0.00103604
VaR <- quantile(p.rt, probs = 0.05)
## -0.001551667 
CVaR <- mean(p.rt[p.rt <= VaR])
## [1] -0.001952581

The covariance matrix is not (explicitly) used in the computation, but cov(R) is the standard estimator.

Note that if you compute CVar-optimal portfolios with the LP-formulation of Rockafellar/Uryasev, as minCVaR does per default, you could also directly reuse some results of the LP, for instance the VaR:

-attr(sol, "LP")$solution[1]
## [1] -0.001551667

Perhaps this note on the implementation of minCVaR also helps.

$\endgroup$
2
  • $\begingroup$ First of all, I must say that I actually used lppAssets3 <- 100 * LPP2005.RET[, 1:6], but forgot to paste the updated code (that is why there is also this add.constraint() - but I edited the code now). So the returns are given in %, and I'm aware that the target return is 0.04% daily. Anyway, this doesn't change the outcome. However your hint to the NMOF package is great (thank you very much!) as it does consider the min return. But how can I return the same results summary as with minriskPortfolio() (the optimal CVaR itself, the VaR, the cov matrix,...)? $\endgroup$
    – ironymike
    Aug 15 '21 at 11:00
  • $\begingroup$ You can compute portfolio returns under the scenario set, and then it becomes straightforward to compute quantities of interest. I have update the answer. $\endgroup$ Aug 16 '21 at 8:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.