最后,我设法解决了它。Dirk 和 Darren,非常感谢您的评论——PerformanceAnalytics 包中的“maxdrawdown”功能并不是我所需要的,但这让我开始关注 PerformanceAnalytics,并通过该站点和 Internet 进行了一些搜索。findDrawdowns 函数来自与我的需求接近的同一包,但无论如何并不是我想要的(它需要更新最后一个高点才能开始计算新的回撤,而我什至需要取局部最大值和最小值考虑)。通过进一步的反复试验,我编写了自己的代码,无需 FOR 循环即可解决我的任务。:) 这是代码。作为奖励 - 它返回带有资产不断增长/下降的条数的向量。如果有人可以建议如何改进它,我会很高兴。
library(rusquant)
library(quantmod)
library(tseries)
na.zero <- function(x) {
tmp <- x
tmp[is.na(tmp)] <- 0
return(tmp)
}
my.cumulative.grdd <- function(asset) {
# creating list for temporary data
tmp <- list()
#
# tmp$asset.lag <- na.locf(lag(asset), fromLast=TRUE)
# calculating ROC for the asset + getting ROC shifted by 1 element to the left and to the right
# to compare ROC[i] and ROC[i+1] and ROC[i-1]
tmp$asset.roc <- na.zero(ROC(asset))
tmp$asset.roc.lag <- na.zero(lag(tmp$asset.roc))
tmp$asset.roc.lag1 <- na.locf(lag(tmp$asset.roc, k=-1))
# calculating indices of consequent growth/drawdown waves start and end
tmp$indexfrom <- sapply(index(tmp$asset.roc[sign(tmp$asset.roc) * sign(tmp$asset.roc.lag) <= 0]), function(i) which(index(tmp$asset.roc) == i), simplify=TRUE)
tmp$indexto <- c(sapply(index(tmp$asset.roc[sign(tmp$asset.roc) * sign(tmp$asset.roc.lag1) <= 0]), function(i) which(index(tmp$asset.roc.lag1) == i), simplify=TRUE), length(index(tmp$asset.roc)))
# this is necessary to work around ROC[1] = 1
tmp$indexfrom <- tmp$indexfrom[-2]
tmp$indexto <- tmp$indexto[-1]
# calculating dates of waves start/end based on indices
tmp$datesfrom <- (sapply(tmp$indexfrom, FUN=function(x) format(index(asset)[x])))
tmp$datesto <- (sapply(tmp$indexto, FUN=function(x) format(index(asset)[x])))
tmp$dates <- apply(cbind(tmp$indexfrom, tmp$indexto), 2, FUN=function(x) format(index(asset)[x]))
# merging dates for selection (i.e. "2012-01-02::2012-01-05") and calculation of cumulative product
tmp$txtdates <- paste(tmp$datesfrom, tmp$datesto, sep="::")
# extracting consequent growth/drawdowns
tmp$drawdowns.sequences <- lapply(tmp$txtdates, function(i) tmp$asset.roc[i])
# calculating cumulative products for extracted sub-series
tmp$drawdowns.sequences.cumprods <- lapply(tmp$drawdowns.sequences, function(x) cumprod(1+x)-1)
# generating final result
result <- list()
result$len <- tmp$indexto - tmp$indexfrom + 1
result$cumgrdd <- xts(unlist(tmp$drawdowns.sequences.cumprods), index(tmp$asset.roc))
return(result)
}
# let's test
getSymbols("SPY", from="2012-01-01")
spy.cl <- Cl(SPY)
spy.grdd <- my.cumulative.grdd(spy.cl)
spy.grdd