如果没有 for 循环,我看不到任何方法可以做到这一点,但下面的解决方案相当快(在我的 2.2Ghz 笔记本电脑上每 10,000 行约 1 秒)。
请注意,我正在coredata
使用 xts 对象并删除dim
属性 (via drop
),该属性返回一个向量。我这样做是因为 xts/zoo 中的数学运算按索引对齐,因此您需要先从分子中删除索引,然后才能计算回报。
但是,这会导致除法调度调用NextMethod
,因为分子是numeric
类而分母是xts
类。我通过对数字向量执行除法来避免这种开销。
library(quantmod)
getSymbols("^GSPC",from="1900-01-01")
x <- Ad(GSPC)
lookback <- function(x, p) {
# lookback() assumes x is xts
# select first column, take coredata, drop dims
dcx <- drop(coredata(x[,1]))
# initialize result object
f <- dcx*NA
# loop over all rows in 'x'
for(i in 1:nrow(x)) {
# Calculate cumulative return through today
r <- dcx[i]/dcx-1 # or log(dcx[i]/dcx)
# This really slows things down:
# r <- dcx[i]/x-1
#
# Find which returns are greater than 'p'
w <- which(abs(r[1:i]) > p)
# If any returns are greater than 'p', then
# record the closest location to 'p'
if(length(w)!=0)
f[i] <- max(w)-i
}
# return an xts object
xts(f, index(x))
}
nrow(x)
# [1] 15791
system.time(lookback(x,0.02))
# user system elapsed
# 15.761 0.152 16.040