4

我正在学习 R(及其通过 quantmod lib 在交易任务中的应用),并定期浏览社区以从这里获得很多新知识和技巧。我对 R 的总体印象,尤其是对 quantmod lib 的印象——太棒了。

在这一点上,我需要经验丰富的 R 用户的帮助。我正在使用通过 getSymbols 下载的时间序列,我需要分别从局部最小值/最大值计算累积增长/下降。

我可以使用 FOR 循环来解决我的任务,也可以在 MS Excel 中进行必要的建模,但我想找出更简单的解决方案,它不需要 FOR 循环并且在 R 中更“原生”。

例子。输入数据:

20121121    79810
20121122    79100
20121123    80045
20121126    81020
20121127    80200
20121128    81350
20121129    81010
20121130    80550
20121203    80780
20121204    81700
20121205    83705
20121206    83350
20121207    83800
20121210    85385

结果:

            CLOSE   Cumulative gr/dd
20121121    79810   N/A
20121122    79100   0.58%
20121123    80045   1.55%
20121126    81020   2.37%
20121127    80200   -0.10%
20121128    81350   0.06%
20121129    81010   -0.76%
20121130    80550   -0.82%
20121203    80780   0.73%
20121204    81700   3.78%
20121205    83705   5.19%
20121206    83350   -1.50%
20121207    83800   1.67%
20121210    85385   2.22%
4

4 回答 4

1

为了补充 Dirk 的回答,PerformanceAnalytics 包有各种回撤选项。这是我的一些代码的摘录,它还显示了增长计算(和锐化比率,作为奖励):

#x is an xts object containing OHLC data
profit=ROC(x$Close)
growth=sum(na.omit(profit)),
equity=exp(sum(na.omit(profit))),
sharpe=as.vector(SharpeRatio.annualized(profit)),
maxDrawdown=maxDrawdown(profit)
于 2013-02-07T10:31:41.690 回答
1

计算已经在tseries包中作为 function maxdrawdown。这是其示例的开头:

mxdrwdR> # Toy example
mxdrwdR> x <- c(1:10, 9:7, 8:14, 13:8, 9:20)

mxdrwdR> mdd <- maxdrawdown(x)

mxdrwdR> mdd
$maxdrawdown
[1] 6

$from
[1] 20

$to
[1] 26

将其转换为百分比非常容易——查看函数本身的(短)代码。

于 2013-02-06T20:41:36.517 回答
1

您可以使用 zig zag 点找到峰值和谷值,然后计算百分比减少/增加。例如

    s <- get(getSymbols('goog'))["2012::"]
    z <- ZigZag(s[,2:3],10,percent=TRUE)
    # 10 in this example is the sensitivity to changes. 
    # if you want to use closing prices use s instad of s[,2:3]

    # extract the extreme points
    z <- rbind(z[findPeaks(z)-1],z[findValleys(z)-1])
    # calculate the difference
    names(z) <- c("zig")
    z$PercentChange <- ((z - Lag(z)) / z) * 100 

希望能帮助到你

于 2013-03-12T17:03:09.343 回答
1

最后,我设法解决了它。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
于 2013-02-10T13:33:39.230 回答