xts to.weekly returns 星期五和星期一作为一周的结束

xts to.weekly returns both Fridays and Mondays as the end of the week

我似乎无法获得 xts 中的 to.weeklyendpoints(被 to.weekly 使用)函数来给我正确的星期结束日对于大多数类型的日期数据。 xts 包的 CRAN 和 R-Forge 版本都遇到过这个问题。

它似乎与此处讨论的问题相似但不完全相同:XTS to.weekly returns different weekly endpoints

对于我拥有的样本数据,to.weekly 函数在不同周的周五和周一使用默认值 indexAt="endof",在周二使用 indexAt="startof"

我每天使用标准普尔 500 指数的 return:

library(quantmod)
getSymbols("^GSPC", from="1961-12-15", to="1962-01-15", src="yahoo")

weekdays(index(to.weekly(GSPC))) # Fridays and mondays
[1] "Monday" "Friday" "Friday" "Monday" "Monday"

我已经尝试将对象的时区从我的时区更改为 UTC,将我的系统时区更改为 UTC 和我的本地时区,并使用转换为 POSIXct 的原始日期重新创建 xts 对象。 None 我的尝试已经成功。

我发现获得我期望的 to.weekly 行为的唯一方法是创建一个日期向量作为字符串,然后将它们转换为 POSIXct 而不是 Date用作新 xts 对象的索引。不幸的是,我无法将其用于我的实际数据。

dates <-
c("1961-12-15","1961-12-18","1961-12-19","1961-12-20","1961-12-21","1961-12-22",
  "1961-12-26","1961-12-27","1961-12-28","1961-12-29","1962-01-02","1962-01-03",
  "1962-01-04","1962-01-05","1962-01-08","1962-01-09","1962-01-10","1962-01-11",
  "1962-01-12","1962-01-15")
data <- rep(1, length(dates))
p <- xts(data, order.by=as.POSIXct(dates))
d <- xts(data, order.by=as.Date(dates))

# Last day in the week, as expected
weekdays(index(to.weekly(p)))
# [1] "Friday" "Friday" "Friday" "Friday" "Friday" "Monday"

# First day in the week, as expected
weekdays(index(to.weekly(p, indexAt="startof")))
# [1] "Friday"  "Monday"  "Tuesday" "Tuesday" "Monday"  "Monday" 

# Mix of first and last days, not expected
weekdays(index(to.weekly(d)))
# [1] "Monday" "Friday" "Friday" "Monday" "Monday"

由于日期的 POSIXct 值似乎适用于字符值,我想我会尝试使用价格数据。

GSPCp <- xts(coredata(GSPC), order.by=as.POSIXct(index(GSPC)))
weekdays(index(to.weekly(GSPCp)))                # Not as expected
[1] "Monday" "Friday" "Friday" "Monday" "Monday"

我怀疑问题是时区(和缺乏经验)问题,但我已经用尽了所有我能想到的方法来使它达到 return 每周结束时的值这个数据系列。

我目前 运行 xts_0.9.874.

------编辑------

正如 WaltS 在下面指出的那样,这似乎是一个问题,因为 POSIXct 使用 Unix 时间,从 1970-01-01 开始。在此时间之前的日期可能会出现奇怪的行为。

我今天做了一些实验,添加了 17 年和 4 个闰日,将索引移动到 1978-1979,这与 1961-1962 的日期相同。果然,to.weekly 在移动到 1970 年后的某个点的相同数据上工作得很好。

d <- GSPC
index(d) <- index(d)+365*17+4 # 1978-1979
weekdays(index(to.weekly(d)))
[1] "Friday" "Friday" "Friday" "Friday" "Friday" "Monday"

因为这似乎是使用 POSIX 时间的固有特性,我认为这不再是我使用 to.weeklyendpoints 的问题,而是时间格式的结构性问题。我需要找到一种不同的方法来确定 1970 年之前日期的周终点。

我同意 Quantmod 数据看起来不错。 to.weekly() 似乎也适用于像 GSPC 这样的 xts 对象。你遇到的问题似乎 将 1970-01-01 用作 POSIXct 时间的起点。为了更好地说明这一点,请考虑示例

GSPC1970 <- getSymbols("^GSPC", from="1970-12-15", to="1971-03-19", src="yahoo", auto.assign=FALSE)
to.weekly(GSPC1970)
weekdays(index(to.weekly(GSPC1970)))
 [1] "Friday"   "Thursday" "Thursday" "Friday"   "Friday"   "Friday"   "Friday"   "Friday"   "Friday"   "Friday"   "Friday"   "Friday"  
[13] "Friday"   "Friday" 

输出符合预期。特别是,从 1969 年到 1970 年

GSPC1969 <- getSymbols("^GSPC", from="1969-11-15", to="1970-03-20", src="yahoo", auto.assign=FALSE)
to.weekly(GSPC1969)
weekdays(index(to.weekly(GSPC1969)))
 [1] "Monday" "Monday" "Monday" "Monday" "Monday" "Monday" "Friday" "Friday" "Friday" "Friday" "Friday" "Friday" "Friday" "Friday"
[15] "Friday" "Friday" "Friday" "Friday"

返回 1969 周的星期一作为周的结束,而星期五返回 1970 的日期。问题可能出在 endpoints() for on = "weeks" 和可能的其他时期。您是否有必要使用 1970 年之前的数据?

------------更新------------

我认为问题更多出在 endpoints() 或其使用的函数上,而不是更基本的问题。无论如何,下面的函数 to.weekly.df() 是 to.weekly() 的替代方法,它将 quantmod 数据从 xts 对象转换为以日期作为列的数据框。它还添加了一个包含周数的列,该周数从 1970-01-01 开始计算周数,并将星期日作为一周的第一天。它使用周数将数据框拆分为数周,然后 sapply 获取每周的摘要数据并将 returns 作为数据框。还有一个小的辅助函数可以将 xts 数据转换为 data.frame.

xts2df <- function(xts_data) data.frame(date=index(xts_data),coredata(cbind(xts_data, week=(as.numeric(index(xts_data))+5)%/%7)))

to.weekly.df <- function(xts_data) {
  df <- xts2df(xts_data)

  weekly <- t(sapply(split(df, df$week), 
                 function(x) c(date=tail(x$date,1), Open=x[1,2], High=max(x[,3]), 
                               Low=min(x[,4]), Close=tail(x[,5], 1),
                               Volume=sum(x[,6]), Adjusted=tail(x[,7],1) ) ) )
 weekly <- data.frame(date=as.Date(weekly[,1]), weekly[,-1])
 return(weekly)
}

对于 post 1970-01-01 的数据,这似乎给出了与 to.weekly() 相同的结果,并且对于之前的时期也给出了正确的结果。如果您有任何问题,请告诉我。