2

I faced an optimization problem. I need to optimize portfolio for return Omega measure. I found suggestions that this can be done by using differential evolution through DEoptim(Yollin's very nice slides on R tools for portfolio optimization. Original code can be found there).

I tried to adapt this method to my problem (since I only changed numbers and I hope didn't make any mistakes. Full credit for the author here for the idea):

optOmega <-function(x,ret,L){                     #function I want to optimize and 
retu = ret %*% x                                  # x is vector of asset weights
obj = -Omega(retu,L=L,method="simple")            #Omega from PerformanceAnalytics
weight.penalty = 100*(1-sum(x))^2
return( obj + weight.penalty )
}
L=0                                               #Parameter which defines loss 
                                                  #in Omega calculation
lower = rep(0,30)                                 #I want weight to be in bounds 
upper = rep(1,30)                                 # 0<=x<=1
res = DEoptim(optOmega,lower,upper,               #I have 30 assets in StockReturn
control=list(NP=2000,itermax=100,F=0.2,CR=0.8),
ret=coredata(StockReturn),L=L)

Omega is calculated as mean(pmax(retu-L,0))/mean(pmax(L-retu,0))

When asset number is very small (5 for example), I get results which pretty much satisfy me: asset weights add up to 0.999???? which is fairly close to one and the Omega of such portfolio is greater than Omega of any single asset (otherwise, why not invest everything in that single asset). This can be reached with 100 iterations. But when I increase asset number up to 30, result is not satisfying. Sum of weights comes to be 3 or more and Omega lower than that of some single assets. I thought this might be due to small number of iterations (I used 1000), so I tried 10 000 which is painfully slow. But the result is pretty much the same: weighs add up to way more than 1 and Omega does not seem optimal. With 10 asset algorithm seems to find weights close to 1, but Omega is lower than the one of a single asset.

My PC is quite old and it has Intel Core Duo 2 GHZ. Though, is it normal for such optimization with 1000 iterations to run ~40 minutes?

What might be the problem here? Is number of iterations too small, or my interpretation of provided algorithm is totally wrong. Thank You for your help!

manlio
  • 18,345
  • 14
  • 76
  • 126
user2287846
  • 71
  • 1
  • 1
  • 4
  • In addition to the penalty for weights not summing up to 1, try to rescale them: `penalty <- (1-sum(x))^2; x <- x/sum(x)`. – Vincent Zoonekynd Apr 26 '13 at 08:25
  • Well I though that something like that can be done after optimization, to get sum(x)=1. Now I have tried to put this into optimization function, but it doesn't seem to work, Omega is still unacceptable. In fact with this condition in function, optimization returns even worse Omega. – user2287846 Apr 26 '13 at 09:38

1 Answers1

0

If I comment out the control argument in your call to DEoptim, I have much better results: the sum of the weights is closer to 1 (it was 3), and the objective is better that for the 1-asset portfolios (it was worse).

# Sample data
library(xts)
n <- 600
k <- 26
StockReturn <- matrix( rnorm(n*k), nc=k )
colnames(StockReturn) <- LETTERS[1:k]
StockReturn <- xts( StockReturn, seq.Date(Sys.Date(), length=n, by=1) )

# Objective
library(PerformanceAnalytics)
optOmega <- function(x, ret = coredata(StockReturn), L=0) {
  penalty <- (1-sum(x))^2
  x <- x/sum(x)
  objective <- -Omega( ret %*% x, L=L, method="simple" ) 
  objective + penalty
}

# Optimization
library(DEoptim)
lower <- rep(0,k)
upper <- rep(1,k)
res <- DEoptim(
  optOmega, lower, upper,
#  control = list(NP=2000, itermax=100, F=0.2, CR=0.8),
  ret = coredata(StockReturn), L = L
)

# Check the results
w <- res$optim$bestmem
sum(w)       # Close to 1
w <- w / sum(w)
optOmega(w)  # Better (lower) that for the 1-asset portfolios
min( apply( diag(k), 2, optOmega ) )
Vincent Zoonekynd
  • 31,893
  • 5
  • 69
  • 78
  • I cannot say that scaling of weights gives good results for me. Sum of weights gets equal to 1, but omega does not seem to be big enough. However, your remark about commenting out control argument is very valuable. The problem seems to be with #control DEoptim uses default settings, which results in lower NP and that gives much quicker optimization. So I let NP to be default and played with other settings which gives quite good results with the original script. Thank You for your help! – user2287846 Apr 28 '13 at 13:35