volemont/insights:chart.EquityCurve.R:绘制累积 return 峰值的错误?

volemont/insights:chart.EquityCurve.R: a bug in graphing peaks of cumulative return?

我遇到了绘制累积 return 策略和 return 峰值的函数,这是结合 shiny 和 quantstrat 的一个很好的例子,感谢 Simon Otziger。源代码是here。该代码大部分时间都运行良好,但对于某些数据,它无法正确绘制峰值。

简化了代码,但没有改变关键逻辑。我 运行 从三个示例策略复制的具有三组数据(cumPNL1、cumPNL2、cumPNL3)的代码,其中第一个数据将导致代码无法正确绘制峰值。

我运行下面的代码分别用cumPNL1、cumPNL2、cumPNL3。使用 cumPNL2 和 cumPNL3,代码可以成功生成累积 return 线和峰值点。然而,对于 cumPNL1,代码只能生成线,但峰不在正确的位置。

我注意到基于 cumPNL2 和 cumPNL3 的 peakIndex 的第一个值为 TRUE,因此当我通过添加一行 peakIndex[1] <- TRUE 更改代码时,cumPNL1 将在修改后的代码中正常工作。

虽然现在它可以使用修改后的代码,但我不知道为什么它会这样。谁能看看?谢谢

cumPNL1 <- c(-193,-345,-406,-472,-562,-543,-450,-460,-544,-659,-581,-342,-384,276,-858,-257.99)
cumPNL2 <- c(35.64,4.95,-2.97,-6.93,11.88,-19.8,-26.73,-39.6,-49.5,-50.49,-51.48,-48.51,-50.49,-55.44,143.55,770.22,745.47,691.02,847.44,1141.47,1007.82,1392.93,1855.26,1863.18,2536.38,2778.93,2811.6,2859.12,2417.58)
cumPNL3 <- c(35.64,4.95,-2.97,-6.93,11.88,-19.8,-26.73,-39.6,-49.5,-50.49,-51.48,-48.51,-50.49,-55.44,143.55,770.22,745.47,691.02,847.44,1141.47,1007.82,1392.93,1855.26,1863.18,2536.38,2778.93,2811.6,2859.12,2417.58)


peakIndex <- c(cumPNL3[1] > 0, diff(cummax(cumPNL3)) > 0)
# peakIndex[1] <- TRUE

dev.new()

plot(cumPNL3, type='n', xlab="index of trades", ylab="returns in cash", main="cumulative returns and peaks")
grid()
lines(cumPNL3)    
points(cbind(1 : length(cumPNL3), cumPNL3)[peakIndex, ], 
       pch=19, col='green', cex=0.6)

legend(
    x='bottomright', inset=0.1,
    legend=c('Net Profit','Peaks'),
    lty=c(1, NA), pch=c(NA, 19),
    col=c('black','green')
)

cumPNL1 有一个单峰,R 将维度从数值矩阵缩减为长度为 2 的数值向量。points 函数使用 y 轴绘制两个数值向量值x 轴索引 1 和 2:

peakIndex1 <- c(cumPNL1[1] > 0, diff(cummax(cumPNL1)) > 0)
peakIndex3 <- c(cumPNL3[1] > 0, diff(cummax(cumPNL3)) > 0)

str(cbind(1 : length(cumPNL1), cumPNL1)[peakIndex1,])
str(cbind(1 : length(cumPNL3), cumPNL3)[peakIndex3,])

输出:

> str(cbind(1 : length(cumPNL1), cumPNL1)[peakIndex1,])
 num [1:12, 1:2] 1 15 16 19 20 22 23 24 25 26 ...
 - attr(*, "dimnames")=List of 2
  ..$ : NULL
  ..$ : chr [1:2] "" "cumPNL1"
> str(cbind(1 : length(cumPNL3), cumPNL3)[peakIndex3,])
 Named num [1:2] 14 276
 - attr(*, "names")= chr [1:2] "" "cumPNL3"

通常设置 plot = FALSE 会保留对象,例如 str(cbind(1 : length(cumPNL3), cumPNL3)[peakIndex3, drop = FALSE]),在这种情况下不知何故不起作用。但是,将 points 行更改为以下内容可以解决问题:

points(seq_along(cumPNL3)[peakIndex], cumPNL3[peakIndex], pch = 19, 
  col = 'green', cex = 0.6)

感谢您报告问题。我明天会把修复推送到 GitHub。