并行计算 - 协整

Parallel Computing - Cointegration

我正在尝试在标准普尔 500 指数中寻找协整对。我有每日价格数据。以前我使用“for”循环来检查协整对并且它有效。但是大约用了1500秒,所以我想也许并行计算会减少时间。

但是当我 运行 我的代码使用“for each”循环时,最终矩阵 (Jotru) 应该包含关系是否存在(是或否)的信息,结果是空的(意思是 returns 用原始矩阵填充零而不是 yes 或 no)。

有效的“for”循环如下

for  (a in 1:359) {
  Bstock    <- colnames(Useries)[a]
    stockleft = 360-a
    for(i in (1:(stockleft))) {
    teststock <- a + i
    tstock <- colnames(Useries)[teststock]
    Stocknames <- c(Bstock, tstock)
    Jotr <- ca.jo(Useries[,Stocknames], type = "trace", ecdet ="none", K=10)
    tvalue <- Jotr@teststat
    tvalue <- as.data.frame(tvalue)
    cval <- Jotr@cval
    cval <- as.data.frame(cval)
    j = a+(i-1)
    Jotru[j,a] <- ifelse(tvalue[1,1]<cval[1,2], "No", "Yes")
    }
}

我用 try({}) 尝试了下面的代码,但也没有用。无论有没有 try({}),代码 运行s 都没有错误,唯一的问题是最终矩阵没有被填充。我不确定哪里出错了,如有任何帮助,我们将不胜感激。

CPU <- makeCluster(cores[1]-2)
registerDoParallel(CPU)
foreach (a = 1:359,.packages = c("urca"),.combine = rbind) %dopar% {
    Bstock    <- colnames(Useries)[a]
    stockleft = 360-a
    for(i in (1:(stockleft))) {
    teststock <- a + i
    tstock <- colnames(Useries)[teststock]
    Stocknames <- c(Bstock, tstock)
    Jotr <- ca.jo(Useries[,Stocknames], type = "trace", ecdet ="none", K=10)
    tvalue <- Jotr@teststat
    tvalue <- as.data.frame(tvalue)
    cval <- Jotr@cval
    cval <- as.data.frame(cval)
    j = a+(i-1)
    Jotru[j,a] <- ifelse(tvalue[1,1]<cval[1,2], "No", "Yes")
    }
}
stopCluster(CPU)
toc()

编辑 - 包 - 为了执行“foreach”循环,我使用“parallel”、“foreach”和“doParallel”包。 urca 是循环中唯一使用的包。 Xts 用于创建循环内使用的系列。其他一切都基于基础 r.

编辑 2 - 用户 - 数据文件 - 该文件大约 13 Mb。

https://github.com/AvisR/AvisR/blob/main/Useries.csv

https://drive.google.com/file/d/1r3pLwvYxHdnxq1i9hP2Jso8g4qzpq4ds/view?usp=sharing

Jotru - 359*359 矩阵来保存值。当我们 运行 "for" 循环

时,下半部分将填充 Yes 或 No
Jotru <- matrix(rep(0), 359,359)
rownames(Jotru) <- colnames(Useries)[-1]  
colnames(Jotru) <- colnames(Useries)[-360]  
Jotru <- as.data.frame(Jotru)

以防有人遇到同样的问题。我想出了如何让 Forloop 工作。

“for”和“foreach”循环的主要区别是“for”循环存储在环境中循环期间创建的所有对象。

为了解决这个问题,我做了两件事,

  1. 结果 - “Foreach”循环只报告一个结果。我将整个“foreach”循环作为一个对象,因此结果存储为一个列表。 (Jotruraw)

  2. “Foreach”循环不存储对象。 “foreach”循环的最终结果就是我想要提取的所有对象。 ( return(c(j,a,Jotru[j,a])) )

  3. 然后我将结果重新格式化为我想要的结构。 (Jotru,请注意,即使结果中的数字也保存为字符。我已将它们转换。)

以下代码给出了与我上面提到的“for”循环相同的结果。 (尽管我的数据略有不同,并且对代码进行了一些更改。)

CPU <- makeCluster(cores[1]-2)
registerDoParallel(CPU)
Jotruraw <- foreach (a = 1:439,.packages = c("urca", "parallel", "foreach", "doParallel"),.combine = rbind) %dopar% {
  Bstock    <- colnames(Useries)[a]
  stockleft = 440-a
    foreach (i = (1:(stockleft)),.packages = c("urca"),.combine = rbind) %dopar% { 
    teststock <- a + i
    tstock <- colnames(Useries)[teststock]
    Stocknames <- c(Bstock, tstock)
    Jotr <- ca.jo(Useries[,Stocknames], type = "trace", ecdet ="none", K=12)
    tvalue <- Jotr@teststat
    tvalue <- as.data.frame(tvalue)
    cval <- Jotr@cval
    cval <- as.data.frame(cval)
    j = a+(i-1)
    Jotru[j,a] <- ifelse(tvalue[1,1]<cval[1,2], "No", "Yes")
    return(c(j,a,Jotru[j,a]))
    }
}
stopCluster(CPU)

Jotruraw <- as.data.frame(Jotruraw)
Jotruraw$V1 <- as.numeric(Jotruraw$V1)
Jotruraw$V2 <- as.numeric(Jotruraw$V2)

for (i in 1:96580){
  a <- Jotruraw$V1[i]
  b <- Jotruraw$V2[i]
  c <- Jotruraw$V3[i]
  Jotru[a,b] <- c
}