2014-04-15 126 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