合并具有不同时间间隔的xts对象

时间:2016-07-07 08:03:06

标签: r merge time-series xts quantmod

我使用quantmod从yahoo下载引号,计算季度回报并希望将返回和引号合并到一个xts对象中。在这个新对象中,我想只看到我有返回和季度回报的日期(通常是季度的最后一天)。但我看到的是:

2011-06-29 appears two time

以下是代码:

library(quantmod)

#Define stocks
tickers<-c("DBK.DE","DTE.DE")
stock<-tickers
StartDate<-'2011-6-25'
EndDate<-'2016-06-25'

PF <- getSymbols(tickers, src='yahoo', from=StartDate, to=EndDate)

# combine the adjusted close values in one (xts) object
dataset <- Ad(get(PF[1]))
for (i in 2:length(PF)) {
  dataset <- merge(dataset, Ad(get(PF[i])))
}

#Getting Quarterly Returns
QReturns<-as.xts(as.data.frame(lapply(dataset,quarterlyReturn)))

#Here is where I suspect the problem
Quarterly_Portfolio<-merge.xts(dataset,QReturns)

有什么想法吗?

2 个答案:

答案 0 :(得分:5)

虽然FXQuantTrader's answer解决了问题,但它无法正确诊断或解决根本原因。

合并具有不同索引类的两个xts对象没有任何问题,因为所有xts对象都在内部将索引存储为POSIXct。例如:

d <- Sys.Date()
merge(date=xts(1,d), posixct=xts(2,as.POSIXct(d,tz="UTC")))
             date posixct
# 2016-07-09    1       2

问题是因为你的两个xts对象有不同的时区。请注意,dataset具有UTC时区,因为Date索引不能包含时区。

R> str(dataset)
An ‘xts’ object on 2011-06-27/2016-06-24 containing:
  Data: num [1:1305, 1:2] 33.5 34.3 34.6 35.1 36 ...
 - attr(*, "dimnames")=List of 2
  ..$ : NULL
  ..$ : chr [1:2] "DBK.DE.Adjusted" "DTE.DE.Adjusted"
  Indexed by objects of class: [Date] TZ: UTC
  xts Attributes:  
List of 2
 $ src    : chr "yahoo"
 $ updated: POSIXct[1:1], format: "2016-07-09 08:21:12"

但是QReturns有空的&#39; TZ属性(表示使用本地时区)。

R> str(QReturns)
An ‘xts’ object on 2011-06-30/2016-06-24 containing:
  Data: num [1:21, 1:2] 0.047 -0.354 0.118 0.267 -0.215 ...
 - attr(*, "dimnames")=List of 2
  ..$ : NULL
  ..$ : chr [1:2] "quarterly.returns" "quarterly.returns.1"
  Indexed by objects of class: [POSIXct,POSIXt] TZ: 
  xts Attributes:  
 NULL

QReturns看起来像这样,因为您在data.frame上调用了as.xts,而as.xts.data.frame默认指定了dateFormat = "POSIXct"。如果设置dateFormat = "Date",则无法合并这两个对象。

另请注意,直接调用方法(merge.xts)是不好的做法。您应该只调用merge泛型并让S3系统处理方法调度。

QReturns <- as.xts(as.data.frame(lapply(dataset,quarterlyReturn)),dateFormat="Date")
Quarterly_Portfolio <- merge(dataset,QReturns)
head(Quarterly_Portfolio)
#            DBK.DE.Adjusted DTE.DE.Adjusted quarterly.returns quarterly.returns.1
# 2011-06-27         33.5422           7.820                NA                  NA
# 2011-06-28         34.2747           7.786                NA                  NA
# 2011-06-29         34.6194           7.909                NA                  NA
# 2011-06-30         35.1193           8.085        0.04701838          0.03388747
# 2011-07-01         36.0286           7.992                NA                  NA
# 2011-07-04         35.7787           7.995                NA                  NA

我个人会在计算QReturns时不将xts转换为data.frame,从而避免这一切。您可以直接在xts对象上调用lapply,然后使用do.call(merge, ...)将结果合并回来。

QReturns <- do.call(merge, lapply(dataset, quarterlyReturn))
Quarterly_Portfolio <- merge(dataset, QReturns)

您的getSymbols和&#34;合并&#34;步骤也可以更紧凑地完成:

PF <- new.env()
getSymbols(tickers, from=StartDate, to=EndDate, env=PF)
# combine the adjusted close values in one (xts) object
dataset <- do.call(merge, eapply(PF, Ad))

答案 1 :(得分:3)

你的问题出现了,因为有不同类型的时间对象:

> class(index(dataset))
[1] "Date"
> class(index(QReturns))
[1] "POSIXct" "POSIXt" 

您希望在使用merge.xts时转换为同一个班级。您可以在方便的lubridate函数floor_date的帮助下尝试这一点,该函数将POSIXct时间向下舍入到POSIXct对象值附加非零小时的最近日期:

require(lubridate)
index(dataset) <- floor_date(as.POSIXct(index(dataset)), "day")
Quarterly_Portfolio<-merge.xts(dataset,QReturns)

> head(Quarterly_Portfolio)
           DBK.DE.Adjusted DTE.DE.Adjusted quarterly.returns quarterly.returns.1
2011-06-27         33.5422           7.820                NA                  NA
2011-06-28         34.2747           7.786                NA                  NA
2011-06-29         34.6194           7.909                NA                  NA
2011-06-30         35.1193           8.085        0.04701838          0.03388747
2011-07-01         36.0286           7.992                NA                  NA
2011-07-04         35.7787           7.995                NA                  NA

或者,您也可以使用基础R的floor_date代替round.POSIXt,而不是as.POSIXct(round.POSIXt(as.POSIXct(index(dataset)), "day"))