在R中计算xts对象滚动60日回撤遇问题求助
解决滚动60日回撤计算的报错问题
我来帮你搞定这个滚动回撤计算的问题,先拆解下报错的根源,再给出实用的解决方案:
报错原因分析
rollapply(x, width=60, FUN=Drawdowns)的错误:Drawdowns()函数返回的是和输入序列长度完全一致的回撤序列(每个时间点对应相对于之前峰值的回撤)。当你用rollapply对60天窗口应用它时,每个窗口都会返回一个60行的xts对象,但rollapply默认会尝试把这些结果拼接成一个二维数组,这就导致了维度名和数组范围不匹配的错误——原数据的行数和窗口返回的行数根本无法对齐。apply.rolling(x, width=60, FUN=SharpeRatio)的错误:apply.rolling是PerformanceAnalytics里的旧函数,现在官方更推荐用rollapply。这个错误是因为SharpeRatio()默认返回的是包含多列的矩阵(比如不同无风险利率下的夏普比率),而apply.rolling在拼接结果时,列数不匹配导致失败。
可行解决方案
根据你的需求(计算滚动60日回撤),分两种常见场景给出代码:
场景1:计算每个日期对应的过去60天窗口内的最大回撤(最常用)
我们需要自定义一个函数,让它在每个窗口内计算出一个单值(最大回撤幅度),这样rollapply就能正常拼接结果:
# 加载依赖包 library(xts) library(PerformanceAnalytics) # 自定义函数:计算单列收益数据的窗口内最大回撤 calc_max_drawdown <- function(returns) { # 先计算累计收益,再推导回撤序列,最后取最大回撤(最负的那个值) cum_returns <- cumprod(1 + returns) peak_values <- cummax(cum_returns) drawdowns <- (cum_returns - peak_values) / peak_values min(drawdowns, na.rm = TRUE) } # 应用滚动窗口计算(注意:你的示例数据只有6行,实际用width=60) rolling_max_dd <- rollapply( data = x, width = 60, # 实际使用60,这里示例用3演示 FUN = calc_max_drawdown, by.column = TRUE, # 对每种货币单独计算 fill = NA, # 窗口不足60天的位置填充NA align = "right" # 结果对应窗口的最后一个日期(右对齐) ) # 查看结果 head(rolling_max_dd)
场景2:获取每个60天窗口的完整回撤序列(较少用,结果体积大)
如果你确实需要每个窗口的完整回撤数据,可以让rollapply返回列表,避免自动拼接的维度错误:
rolling_dd_list <- rollapply( data = x, width = 60, FUN = Drawdowns, by.column = FALSE, simplify = FALSE # 不简化结果,返回列表 ) # 查看第一个窗口的回撤结果 rolling_dd_list[[1]]
额外:滚动夏普比率的正确写法
针对你提到的SharpeRatio报错问题,同样需要让函数返回单值:
rolling_sharpe <- rollapply( data = x, width = 60, FUN = function(rets) { # 指定无风险利率为0,返回第一个结果(单值) SharpeRatio(rets, Rf = 0)[[1]] }, by.column = TRUE, fill = NA )
关键注意事项
- 当使用
rollapply时,一定要确保你的FUN返回的结果格式和rollapply的预期匹配:如果要得到结构化的xts结果,最好让FUN返回单值;如果需要多值结果,用simplify=FALSE返回列表。 - 优先使用
rollapply而非apply.rolling,因为后者已经被PerformanceAnalytics标记为弃用函数。
内容的提问来源于stack exchange,提问作者paulb_82
相关产品推荐
相关产品推荐

