Reputation: 23
I'm trying to optimize the parameters of a simple strategy as the code below by maximizing the sharpe ratio. The output results are clearly wrong. Can you please provide some help?
library(xts)
library(zoo)
library(quantmod)
library(PerformanceAnalytics)
library(TTR)
f_opt <- function(x, data){
a <- x[1]
b <- x[2]
sma <- SMA(Cl(data), n = a)
fma <- EMA(Cl(data), n = b)
signal <- Lag(ifelse(sma < fma, 1, -1))
ret <- Return.calculate(data, method = "discrete") * signal
colnames(ret) <- c("MA Strategy")
ret <- na.omit(ret)
sharpe <- SharpeRatio.annualized(ret, Rf = 0, scale = 252) * -1
return(as.numeric(sharpe))
}
SYMBL <- getSymbols("^GSPC", auto.assign=F, from="2011-01-01", to="2021-02-08")
data <- na.omit(SYMBL[,4])
optim(par = c(1,1), fn = f_opt, data = data, method = "L-BFGS-B", lower = 1, upper = 200)
OUTPUT
[1] 1.869527 1.000000
$value [1] -0.6721263
$counts function gradient 7 7
$convergence [1] 0
$message [1] "CONVERGENCE: NORM OF PROJECTED GRADIENT <= PGTOL"
Upvotes: 1
Views: 293
Reputation: 226057
optim()
and related methods can find optima of smooth surfaces. With only two parameters it's easy enough to compute the objective function over a surface by brute force (I use functions from the emdbook
and plot3D
packages for convenience, but you could easily do this with for()
loops and the built-in persp()
function ...) (code below)
I know nothing about your subject area (finance?) or what's going on under the hood in the objective function, but it's not at all surprising that the optimization didn't work.
I was concerned that maybe the problem was with non-integer values of the parameters (which would present a problem for optim()
in any case, but might suggest other approaches), but even restricting to integer values in the range (5-20, 180-200) we still get a rough-looking surface:
I have found the DEoptim
(optimization by differential evolution) function useful for problems like this.
d1 <- DEoptim(f_opt, data=data,lower=c(1,1),upper=c(200,200))
## $optim
## $optim$bestmem
## par1 par2
## 12.87796 190.91548
##
## $optim$bestval
## [1] -1.158693
library(emdbook)
## this step takes a while
system.time(
cc <- curve3d(f_opt(c(x,y), data=data),
from=c(1,1),to=c(200,200),
n=61,
sys3d="none",
.progress="text")
)
## Cairo::Cairo(file="plot3d.png")
library(plot3D)
with(cc,persp3D(x=replicate(61,x),
y=t(replicate(61,y)),
z,
border="black")
)
## dev.off()
cc2 <- curve3d(f_opt(c(x,y), data=data),
from=c(5,180),to=c(20,200),
n=c(16,21),
sys3d="none",
.progress="text")
## Cairo::Cairo(file="plot3dB.png",width=1280,height=960)
with(cc2,persp3D(x=replicate(21,x),
y=t(replicate(16,y)),
cc2$z,
border="black"))
## dev.off()
Upvotes: 3