首页 > 解决方案 > R中的优化代码,我错过了什么吗?

问题描述

我正在尝试通过最大化锐化比率来优化简单策略的参数,如下面的代码。输出结果显然是错误的。你能提供一些帮助吗?

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)

输出

[1] 1.869527 1.000000

$值 [1] -0.6721263

$counts 函数梯度 7 7

$收敛[1] 0

$message [1] "收敛:投影梯度的标准 <= PGTOL"

标签: roptimization

解决方案


optim()和相关的方法可以找到光滑表面的最优值。只有两个参数,很容易通过蛮力计算表面上的目标函数(为方便起见,我使用emdbookandplot3D包中的函数,但您可以使用for()循环和内置persp()函数轻松做到这一点......)(下面的代码)

极其粗糙的目标函数面

我对您的主题领域(财务?)或目标函数的幕后情况一无所知,但优化不起作用并不奇怪。

我担心问题可能出在参数的非整数值上(optim()在任何情况下都会出现问题,但可能会建议其他方法),但甚至限制在范围内的整数值(5-20​​、180- 200)我们仍然得到一个粗糙的表面:

另一个粗糙的表面

我发现DEoptim(通过差分进化进行优化)函数对此类问题很有用。

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()

推荐阅读