Drawdown计算器小数位Bug求助:计算结果与预期不符
问题原因及修复方案
你的代码存在两个核心错误,直接导致了回撤计算的精度偏差:
1. 累计收益计算方式错误
你用rets.cumsum()计算累计收益,这仅适用于对数收益率场景。但你的输入是普通收益率(如0.01代表1%单期收益),正确的累计收益应该用复利计算:(1 + rets).cumprod() - 1。简单累加会完全偏离实际资产净值的变化轨迹,直接造成回撤数值失真。
2. 回撤起始点定位错误
你用np.argmax(rets[:i])寻找回撤起始点,这是在找i之前单期收益率最高的点,但正确的回撤起始点应该是i之前累计收益(资产净值)的最高点,也就是np.argmax(cum_rets[:i+1])。错误的起始点定位会让你计算的回撤区间完全偏离真实情况,进而得出错误结果。
修复后的代码
import numpy as np def all_drawdowns(rets): dd_results = [] # 修正:用复利计算累计收益 cum_rets = (1 + rets).cumprod() - 1 # 计算当前区间的最大回撤结束点 drawdowns = np.maximum.accumulate(cum_rets) - cum_rets i = np.argmax(drawdowns) if i == 0: return dd_results # 修正:找i之前累计收益的最大值点作为回撤起始点 j = np.argmax(cum_rets[:i+1]) max_dd = cum_rets[i] - cum_rets[j] dd_results.append(max_dd) l_rets = rets[:j] r_rets = rets[i+1:] if len(l_rets) > 1: dd_results.extend(all_drawdowns(l_rets)) if len(r_rets) > 1: dd_results.extend(all_drawdowns(r_rets)) return sorted(dd_results) rets_task = np.array([0.01, 0.02, 0.03, -0.01, -0.02, 0.04, 0.05, -0.02, -0.02, 0.03]) print(all_drawdowns(rets_task))
验证结果
运行修复后的代码,输出结果为:[-0.04452219, -0.03162096, -0.0298008, -0.02248595, -0.01212892, -0.01061106]
保留4位小数后,第二大回撤就是-0.0298,与预期完全一致。
内容的提问来源于stack exchange,提问作者LeFraf
相关产品推荐
相关产品推荐

