使用Quantmod计算日收益率全为0的问题排查
问题原因及解决方案
问题出在xts对象的时间索引对齐机制上。你用行数截取的两个子集stkdata[2:n,]和stkdata[1:(n-1),],它们的时间戳完全没有重叠:前者从2022-01-04开始,后者到2023-01-02结束。xts在执行算术运算时会自动对齐时间索引,只有相同时间戳的元素才会参与计算,无匹配的索引会被丢弃,这就是为什么x[1,]/y[1,]返回空值,而你的收益率计算结果异常。
修正后的代码
在xts/quantmod中计算收益率,正确的做法是使用lag()函数获取滞后一期的数据,或者直接用diff(log()),两种方法都会自动处理时间索引对齐:
library(quantmod) getSymbols(c("TSLA", "AAPL", "CSCO", "IBM")) # 截取时间范围并提取调整后价格 tsla <- TSLA['2022-01-03::2023-01-03']$TSLA.Adjusted aapl <- AAPL['2022-01-03::2023-01-03']$AAPL.Adjusted csco <- CSCO['2022-01-03::2023-01-03']$CSCO.Adjusted ibm <- IBM['2022-01-03::2023-01-03']$IBM.Adjusted stkdata <- cbind(tsla, aapl, csco, ibm) # 方法1:用diff(log())直接计算对数收益率 rets <- diff(log(stkdata)) # 方法2:用log(当前值/滞后值)计算,lag()默认滞后1期 rets <- log(stkdata / lag(stkdata)) # 移除第一行的NA值(第一期无前置数据) rets <- na.omit(rets)
原代码问题解析
你手动按行数截取子集的方式忽略了xts的时间索引特性:
stkdata[2:n,]的时间序列是2022-01-04 ~ 2023-01-03stkdata[1:(n-1),]的时间序列是2022-01-03 ~ 2023-01-02
两者没有任何重叠的时间戳,执行除法时xts找不到相同时间的配对元素,因此返回空结果;你看到的“日收益率全为0”实际是无有效计算结果导致的异常显示,并非真实的0值。
内容的提问来源于stack exchange,提问作者RnewBie
相关产品推荐
相关产品推荐

