2014-04-15 123 views
0

我需要一些帮助来矢量化下面的代码,因为我相信它会变得更高效。不过,我不知道如何开始...我创建了一个循环,通过zz有3列和112847行,这可能是需要很长时间的原因。 3列包含了在该MACD()功能使用的号码......如何在R中矢量化函数

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长度约。 112847.我的电脑需要一段时间才能通过循环。

+0

请提供一些[再现的代码](http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example)。具体来说,因为我不熟悉拉交易数据,我不知道'Ad()'是什么,也不知道'LUNA'是什么(你指的是股票代号LUNA?)。此外,“MACD”应该做什么? – r2evans

+0

什么证据表明你有这个MACD是你的速度问题?你在while循环中做了很多合并。这一定很慢。你最好提出一个关于如何完成你真正想要做的事情的问题,然后提供你的代码作为你所尝试的例子。 – John

+0

@ r2evans'Ad()'是股票数据调整后的收盘价。是LUNA是交易标志。我更新了代码以要求使用的软件包。 “MACD()”是“MACD是由Gerald Appel开发的,可能是最受欢迎的价格振荡器。本页中记录的MACD函数比较了一系列的快速移动平均线(MA)和相同的慢速MA系列,它可以用作任何单变量系列的通用振荡器,而不仅仅是价格。“ – Jason

回答

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], ] 

它减少的情况下的数量从11284757575

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

结果将是如下。哪一列属于哪个组合i,j,k是微不足道的。

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 
+0

你是指'x $ MACD <= x $ Signal'?,我怎么能一遍又一遍地复制? – Jason

+0

没有 - 对于MACD指标'nFast> nSlow' \t没有意义 –

+0

我明白你的意思了。感谢上面的代码,但我有一个问题。计算机运行代码需要多长时间?我现在认为这可能是我的电脑速度很慢,因为它需要很长时间才能运行代码 – Jason