1

我目前正在使用 R 进行一些研究,我想知道是否有人对如何创建以下变量有任何聪明的想法或任何预打包的函数:

我有一个单变量价格序列,比如金融资产的每日收盘价,可以追溯到 10 年。(它是一个 xts 对象)

我选择我的 x 为 2%

对于我每天的价格数据。我想知道您需要返回的最少天数才能创造大于 x% 的(可能是绝对的)回报(假设您当时有远见进行交易)。该变量将返回产生 x% 回报所需的天数/月数/年数。如果需要在数据开始之后返回以产生大于 x% 的回报,则在早期阶段返回 NA。

我可以想到一些手动和笨重的方法来做到这一点,但它使用大量循环来检查大量日期/价格,以便返回每天的正确值,然后该过程在第二天重复。 .它在 10 年的数据或日内数据上相当成问题,因此将对更快的解决方案给予支持......

4

2 回答 2

2

如果没有 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 
于 2012-10-03T11:18:14.347 回答
1

首先,您应该反转时间序列,以便具有最小正值的 x 值在时间上是最近的,而较远的过去点在右侧。然后你可以取当前值并说:

set.seed(123)
yval=cumsum(0.01*rnorm(100))
plot(1:100, yval, type="b")
which(rev(yval) < 0.95*yval[100])
which(rev(yval) < (1- 0.05)*yval[100])[1]
[1] 5

如果您提供了包含日期时间或日期分类变量的示例数据集,我们可以帮助进行任何需要的转换。

于 2012-10-03T05:50:17.773 回答