如何在R中向量化一个函数

时间:2014-04-15 04:14:04

标签: r function vectorization trading

我需要一些帮助来矢量化以下代码,因为我相信它会变得更有效率。但是我不知道如何开始......我创建了一个遍历z的循环。 z有3列和112847行,这可能是需要很长时间的原因。 3列包含MACD()函数中使用的数字...

library(quantmod)
library(TTR)

# get stock data 
getSymbols('LUNA')

#Choose the Adjusted Close of a Symbol
stock <- Ad(LUNA)

#Create matrix for returns only
y <- stock

#Create a "MATRIX" by choosing the Adjusted Close 
Nudata3 <- stock

#Sharpe Ratio Matrix
SR1<- matrix(NA, nrow=1)

# I want to create a table with all possible combinations from the ranges below
i = c(2:50)
k = c(4:50)
j = c(2:50)

# stores possible combinations into z
z <- expand.grid(i,k,j)
colnames(z)<- c("one","two","three")            

n = 1
stretches <- length(z[,1])

while (n < stretches){ 

# I am trying to go through all the values in "z"
Nuw <- MACD((stock), nFast=z[n,1], nSlow=z[n,2], nSig=z[n,3], maType="EMA")

colnames(Nuw) <- c("MACD","Signal")  #change the col names to create signals
x <- na.omit(merge((stock), Nuw))

x$sig <- NA

# Create trading signals                            

sig1 <- Lag(ifelse((x$MACD <= x$Signal),-1, 0)) # short when MACD < SIGNAL 
sig2 <- Lag(ifelse((x$MACD >= x$Signal),1, 0))  # long when MACD > SIGNAL 
x$sig <- sig1 + sig2



#calculate Returns
ret <- na.omit(ROC(Ad(x))*x$sig)
colnames(ret)<- c(paste(z[n,1],z[n,2],z[n,3],sep=","))
x <- merge(ret,x)
y <- merge(y,ret) #This creates a MATRIX with RETURNs ONLY
Nudata3 <- merge(Nudata3, x)

((mean(ret)/sd(ret)) * sqrt(252))  -> ANNUAL # Creates a Ratio
ANNUAL->Shrat                                # stores Ratio into ShRat
SR1 <- cbind(SR1,Shrat)                      # binds all ratios as it loops

n <- (n+1)

}

我想知道如何对MACD()函数进行向量化,以加快进程,因为stretches的长度约为。{这需要我的电脑很长一段时间才能完成循环。

1 个答案:

答案 0 :(得分:2)

首先 - 特定于案例的优化 - 删除nFast > nSlow的案例,因为它在技术上没有意义。

其次 - 您正在创建对象并一遍又一遍地复制它们。这非常昂贵。

第三 - 您可以通过在一个循环中创建信号矩阵并以矢量化方式执行其余操作来更好地编码。

我会编码你正在做的事情。

如果您不理解,请阅读mapplydo.callmergesapply的帮助页面。

require(quantmod)
getSymbols("LUNA")

#Choose the Adjusted Close of a Symbol
stock <- Ad(LUNA)

# I want to create a table with all possible combinations from the ranges below
i = c(2:50)
k = c(4:50)
j = c(2:50)

# stores possible combinations into z
z <- expand.grid(i,k,j)

IMO:这是您首次优化的地方。删除i>的情况。 ķ

z <- z[z[,1]<z[,2], ]

它将案例数量从112847减少到57575

#Calculate only once. No need to calculate this in every iteration.
stockret <- ROC(stock)

getStratRet <- function(nFast, nSlow, nSig, stock, stockret) {
    x  <- MACD((stock), nFast=nFast, nSlow=nSlow, nSig=nSig, maType="EMA")
    x <- na.omit(x)
    sig <- Lag(ifelse((x$macd <= x$signal),-1, 0)) + Lag(ifelse((x$macd >= x$signal),1, 0))
    return(na.omit(stockret * sig))
}

RETURNSLIST <- do.call(merge, mapply(FUN = getStratRet, nFast = z[,1], nSlow = z[,2], nSig = z[,3], MoreArgs = list(stock = stock, stockret = stockret), SIMPLIFY = TRUE))

getAnnualSharpe <- function(ret) {
    ret <- na.omit(ret)
    return ((mean(ret)/sd(ret)) * sqrt(252))
}


SHARPELIST <- sapply(RETURNSLIST, FUN = getAnnualSharpe)

结果如下。哪个列属于ijk的哪个组合是微不足道的。

head(RETURNSLIST[, 1:3])
##            LUNA.Adjusted LUNA.Adjusted.1 LUNA.Adjusted.2
## 2007-01-10   0.012739026    -0.012739026               0
## 2007-01-11  -0.051959739     0.051959739               0
## 2007-01-12  -0.007968170    -0.007968170               0
## 2007-01-16  -0.007905180    -0.007905180               0
## 2007-01-17  -0.005235614    -0.005235614               0
## 2007-01-18   0.028315920    -0.028315920               0

SHARPELIST
##   LUNA.Adjusted LUNA.Adjusted.1 LUNA.Adjusted.2 LUNA.Adjusted.3 LUNA.Adjusted.4 LUNA.Adjusted.5 LUNA.Adjusted.6 
##      0.04939150     -0.07428392             NaN      0.02626382     -0.06789803     -0.22584987     -0.07305477 
## LUNA.Adjusted.7 LUNA.Adjusted.8 LUNA.Adjusted.9 
##     -0.05831643     -0.08864845     -0.08221986 



system.time(
+ RETURNSLIST <- do.call(merge, mapply(FUN = getStratRet, nFast = z[1:100,1], nSlow = z[1:100,2], nSig = z[1:100,3], MoreArgs = list(stock = stock, stockret = stockret), SIMPLIFY = TRUE)),
+ SHARPELIST <- sapply(RETURNSLIST, FUN = getAnnualSharpe)
+ )
   user  system elapsed 
   2.28    0.00    2.29