将 xts 对象与一些公共列合并

Merging xts objects with some common columns

我正在对股票指数成员的交易策略进行回测。我每年都有历史股价日期。我想合并这些时间序列对象。我的问题是索引成分不一样,因此我不能简单地对它们进行 rbind。合并也不是一种选择,因为它会为不同年份的相同股票创建单独的列。有人可以建议我解决方案吗?

这是我的问题的一个例子: xts1:

                                  AAPL    AMZ   AA    AXP     
              11/01/2020          100     85     90    70     
              12/01/2020          105     70     80    90     

xts2:

                                  AAPL    AM    AXP     BA
              01/01/2021          108     75     80     50
              02/01/2021          110     60     70     60 

最终 xts:

                                  AAPL    AMZ   AA    AXP     BA
              11/01/2020          100     85     90    70     NA
              12/01/2020          105     70     80    90     NA
              01/01/2021          108     75     NA    80     50
              02/01/2021          110     60     NA    70     60 

                

order.byxts 的索引应该是 Date/Datetime class。根据`?xts

order.by - a corresponding vector of unique times/dates - must be of a known time-based class.

如果初始对象是 xts 并且日期是 Date class,一个选项是 rbind 在使用 [= 转换为 data.frame 之后19=]

library(xts)
library(dplyr)
bind_rows(fortify.zoo(xt1), fortify.zoo(xt2))
       Index AAPL AMZ AA AXP BA
1 2020-11-01  100  85 90  70 NA
2 2020-12-01  105  70 80  90 NA
3 2021-01-01  108  75 NA  80 50
4 2021-02-01  110  60 NA  70 60

如果我们想重新转换为xts

out <- bind_rows(fortify.zoo(xt1), fortify.zoo(xt2))
xts(out[-1], order.by = out$Index)
           AAPL AMZ AA AXP BA
2020-11-01  100  85 90  70 NA
2020-12-01  105  70 80  90 NA
2021-01-01  108  75 NA  80 50
2021-02-01  110  60 NA  70 60

数据

xt1 <- structure(c(100L, 105L, 85L, 70L, 90L, 80L, 70L, 90L), .Dim = c(2L, 
4L), .Dimnames = list(NULL, c("AAPL", "AMZ", "AA", "AXP")), index = structure(c(1604188800, 
1606780800), tzone = "UTC", tclass = "Date"), class = c("xts", 
"zoo"))

xt2 <- structure(c(108L, 110L, 75L, 60L, 80L, 70L, 50L, 60L), .Dim = c(2L, 
4L), .Dimnames = list(NULL, c("AAPL", "AMZ", "AXP", "BA")), index = structure(c(1609459200, 
1612137600), tzone = "UTC", tclass = "Date"), class = c("xts", 
"zoo"))

我们定义了一个合并两个 xts 对象的函数 Merge。它只使用 xts 包。它使用 c.xtscbind.xts 来执行此操作。

下面示例中使用的 xts1xts2 对象在末尾的注释中以可重现的形式显示。

Merge <- function(xts1, xts2) {

  nms1 <- names(xts1)
  nms2 <- names(xts2)
  both <- intersect(nms1, nms2)

  cbind(c(xts1[, both], xts2[, both]), 
        xts1[, !nms1 %in% both], 
        xts2[, !nms2 %in% both])
}

x <- Merge(xts1, xts2); x

给出这个 xts 对象:

           AAPL AXP AMZ AA AM BA
2020-11-01  100  70  85 90 NA NA
2020-12-01  105  90  70 80 NA NA
2021-01-01  108  80  NA NA 75 50
2021-02-01  110  70  NA NA 60 60

另请注意,xts 支持 yearmon class,它在内部将年和月表示为年 + 分数,其中分数为 0 表示 1 月,1/12 表示 2 月,...,11/12 表示 12 月显示如下。

aggregate(x, as.yearmon)

给予:

         AAPL AXP AMZ AA AM BA
Nov 2020  100  70  85 90 NA NA
Dec 2020  105  90  70 80 NA NA
Jan 2021  108  80  NA NA 75 50
Feb 2021  110  70  NA NA 60 60

备注

library(xts)

Lines1 <- "                      AAPL    AMZ   AA    AXP     
              11/01/2020          100     85     90    70     
              12/01/2020          105     70     80    90     "
xts1 <- read.zoo(text = Lines1, format = "%m/%d/%Y", index = 0) |>
  as.xts()

Lines2 <- "                                  AAPL    AM    AXP     BA
              01/01/2021          108     75     80     50
              02/01/2021          110     60     70     60 " 
xts2 <- read.zoo(text = Lines2, format = "%m/%d/%Y", index = 0) |>
  as.xts()