我想用最接近每个月n日的日期索引xts对象。
换句话说,我想要每个月15日的股票价格。但是,15日不是有效月份的有效交易日,因为它可能发生在周末或假日。对于那些月份,我想选择下一个(或者前一个)下一个有效交易日。
例如,2015年前四个月的“下一个第15个”系列将在1月15日,2月17日,3月16日和4月15日返回观察结果。
to.period( )
通过选择每个月的最后一天,无论是30日,31日,28日还是29日,都可以有效地做到这一点。我想在一个月的任意一天概括这一点。
我已经能够通过蛮力来做到这一点,但我想知道是否有一种聪明的方法来做到这一点。
提前谢谢。
更新 -
Josh的回答几乎适合我 - 由于.indexmday()
访问的索引值很奇怪,我的脚本最终失败了。
例如,
getSymbols("SPY", from="2015-01-01")
SPY[.indexmday(SPY) == 30]
产量
SPY.Open SPY.High SPY.Low SPY.Close SPY.Volume SPY.Adjusted
2015-03-31 207.26 208.10 206.36 206.43 126768700 205.4304
2015-05-01 209.40 210.77 209.28 210.72 103399700 209.6996
2015-07-01 207.73 208.03 206.56 207.57 129406500 207.5700
2015-07-31 211.42 211.45 210.16 210.45 97697400 210.4500
因为.indexmday()
检索5月1日和7月1日的索引值为30而不是0.我无法解释原因。我可以解决它 - 但解决方法是如此不优雅。有人知道.indexmday()
这样做的原因吗?
答案 0 :(得分:2)
嗯,这是一种方式,但它给“丑陋”这个词带来了新的含义。
library(quantmod) # for getSymbols
sp500 <- getSymbols("^GSPC", from="2015-01-01",auto.assign=FALSE)
result <- apply.monthly(sp500,function(x)first(x[as.POSIXlt(index(x))$mday>=15],"day"))
result
# GSPC.Open GSPC.High GSPC.Low GSPC.Close GSPC.Volume GSPC.Adjusted
# 2015-01-30 2013.75 2021.35 1991.47 1992.67 4276720000 1992.67
# 2015-02-27 2096.47 2101.30 2089.80 2100.34 3361750000 2100.34
# 2015-03-31 2055.35 2081.41 2055.35 2081.19 3295600000 2081.19
# 2015-04-30 2097.82 2111.91 2097.82 2106.63 4013760000 2106.63
# 2015-05-29 2122.07 2123.89 2116.81 2122.73 3092080000 2122.73
# 2015-06-30 2091.34 2091.34 2072.49 2084.43 3061570000 2084.43
# 2015-07-31 2109.01 2114.14 2102.49 2107.40 3261810000 2107.40
# 2015-08-26 2089.70 2102.87 2079.30 2102.44 2867690000 2102.44
因此,我们按月对sp500
进行分组(使用apply.monthly(...)
),并为每个组提取日期(POSIXlt对象中的mday
)&gt; = 15的所有行,然后找到该子集中的第一个日期。
如果查看原始sp500
对象,您会看到数据来自正确的日期,但apply.monthly(...)
会将结果的索引设置为月末。要获得实际日期(AFAICT)更复杂:
indx <- as.Date(as.integer(apply.monthly(sp500,function(x)index(first(x[as.POSIXlt(index(x))$mday>=15],"day")))))
indx
# [1] "2015-01-15" "2015-02-17" "2015-03-16" "2015-04-15" "2015-05-15" "2015-06-15" "2015-07-15" "2015-08-17"
最后,把它们放在一起,
index(result) <- indx
result
# GSPC.Open GSPC.High GSPC.Low GSPC.Close GSPC.Volume GSPC.Adjusted
# 2015-01-15 2013.75 2021.35 1991.47 1992.67 4276720000 1992.67
# 2015-02-17 2096.47 2101.30 2089.80 2100.34 3361750000 2100.34
# 2015-03-16 2055.35 2081.41 2055.35 2081.19 3295600000 2081.19
# 2015-04-15 2097.82 2111.91 2097.82 2106.63 4013760000 2106.63
# 2015-05-15 2122.07 2123.89 2116.81 2122.73 3092080000 2122.73
# 2015-06-15 2091.34 2091.34 2072.49 2084.43 3061570000 2084.43
# 2015-07-15 2109.01 2114.14 2102.49 2107.40 3261810000 2107.40
# 2015-08-17 2089.70 2102.87 2079.30 2102.44 2867690000 2102.44
答案 1 :(得分:0)
我找到了bizdays&amp; timeDate包在这方面很有帮助。 bizdays有助于将日期向量调整到下一个或上一个工作日。您还可以使用rmetrics从timeDate包导入NYSE日历,以便假期匹配。
library(bizdays)
library(timeDate)
getSymbols('^GSPC',from='2010-01-01')
load_rmetrics_calendars(2010:2017)
min <- index(GSPC)[1]
max <- index(GSPC)[length(index(GSPC))]
rng2 <- seq.Date(min,max,"month")
GSPC[adjust.next(rng2, cal = "Rmetrics/NYSE")]
输出摘录
GSPC.Open GSPC.High GSPC.Low GSPC.Close
2010-01-04 1116.56 1133.87 1116.56 1132.99
2010-02-04 1097.25 1097.25 1062.78 1063.11
2010-03-04 1119.12 1123.73 1116.66 1122.97
2010-04-05 1178.71 1187.73 1178.71 1187.44
2010-05-04 1197.50 1197.50 1168.12 1173.60
2010-06-04 1098.43 1098.43 1060.50 1064.88
2010-07-06 1028.09 1042.50 1018.35 1028.06