从局部最小值/最大值计算累积增长/回撤 [英] Calculate cumulatve growth/drawdown from local min/max

查看:69
本文介绍了从局部最小值/最大值计算累积增长/回撤的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

示例.输入数据:

20121121 7981020121122 7910020121123 8004520121126 8102020121127 8020020121128 8135020121129 8101020121130 8055020121203 8078020121204 8170020121205 8370520121206 8335020121207 8380020121210 85385

结果:

 CLOSE 累积 gr/dd20121121 79810 不适用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%

解决方案

最后,我设法解决了它.Dirk 和 Darren,非常感谢您的评论 - PerformanceAnalytics 包中的maxdrawdown"函数并不是我所需要的,但这让我关注 PerformanceAnalytics 并通过该站点和 Internet 进行了一些搜索.来自同一个包的 findDrawdowns 函数接近我的需要,但无论如何都不是我想要的(它需要更新最后一个高点以开始计算新的回撤,而我什至需要取局部最大值和最小值考虑在内).经过进一步的反复试验,我编写了自己的代码,无需 FOR 循环即可解决我的任务.:) 这是代码.作为奖励 - 它返回带有资产不断增长/下降的条数的向量.如果有人可以建议如何改进它,我会很高兴.

库(rusquant)图书馆(quantmod)图书馆(系列)na.zero <- 函数(x) {tmp <- xtmp[is.na(tmp)] <- 0返回(tmp)}my.cumulative.grdd <- 功能(资产){# 创建临时数据列表tmp <- 列表()## tmp$asset.lag <- na.locf(lag(asset), fromLast=TRUE)# 计算资产的 ROC + 将 ROC 向左和向右移动 1 个元素# 比较 ROC[i] 和 ROC[i+1] 和 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))# 计算随后的增长/回撤波的开始和结束的指数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), 简化=真)tmp$indexto <- c(sapply(index(tmp$asset.roc[sign(tmp$asset.roc) * sign(tmp$asset.roc.lag1) <= 0]), function(i) which(索引(tmp$asset.roc.lag1)==i),简化=真),长度(索引(tmp$asset.roc)))# 这对于解决 ROC[1] = 1 是必要的tmp$indexfrom <- tmp$indexfrom[-2]tmp$indexto <- tmp$indexto[-1]# 根据指数计算波浪开始/结束的日期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]))# 合并日期选择(即2012-01-02::2012-01-05")和累积产品的计算tmp$txtdates <- paste(tmp$datesfrom, tmp$datesto, sep="::")# 提取随之而来的增长/下降tmp$drawdowns.sequences <- lapply(tmp$txtdates, function(i) tmp$asset.roc[i])# 计算提取的子系列的累积产品tmp$drawdowns.sequences.cumprods <- lapply(tmp$drawdowns.sequences, function(x) cumprod(1+x)-1)# 生成最终结果结果 <- 列表()结果$len <- tmp$indexto - tmp$indexfrom + 1结果$cumgrdd <- xts(unlist(tmp$drawdowns.sequences.cumprods), index(tmp$asset.roc))返回(结果)}#让我们测试一下getSymbols("SPY", from="2012-01-01")spy.cl <- Cl(SPY)spy.grdd <- my.cumulative.grdd(spy.cl)spy.grdd

I'm learning R (and its application to trading tasks via quantmod lib) and looking through the community pretty regularly to get a lot of new knowledge and tricks from here. My impression about R in general and quantmod lib in particular - it's awesome.

At this point I need help of seasoned R users. I'm using timeseries downloaded via getSymbols and I need to calculate cumulative growth/drawdown from local minimum/maximum respectively.

I can solve my task using FOR cycles as well as I can do necessary modelling in MS Excel, but I want to figure out more simple solution that does not require FOR cycles and that is more "native" in R.

Example. Input data:

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

Result:

            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%

解决方案

Finally, I've managed to solve it. Dirk and Darren, many thanks for your comments - the "maxdrawdown" function from PerformanceAnalytics package was not exactly what I needed, but this made me paying attention to PerformanceAnalytics and make some search through this site and the Internet. The findDrawdowns function from the same package that was close to my need, but anyway was not exacly what I was looking for (it needs the last high to be updated to start calculating new drawdown, while I need even local maxima and minima to be taken into account). Making further trials-and-errors, I made my own code that solves my task without FOR cycles. :) Here is the code. As a bonus - it returns vector with number of bars of constant growing/falling of the asset. I'll be happy if anyone can advise how to improve it.

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

这篇关于从局部最小值/最大值计算累积增长/回撤的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆