年化率,夏普率,最大回撤计算方法

已知本金100 , 在10天交易了6段 , 下面是6段交易的回报
rt = [10,12,15,18,-6,-9]
(某一天可能存在0交易 , 也就是该天的rt = 0, 也可能某段交易存在跨天的情况 , 则该段rt属于交易结束那天)
由于第一段交易和第二段交易都是在第一天结束的 , 所以第一天的rt = 10+ 12 = 22, 。则10天的rt可以写为
rt = [22,15,18,-6,-9, 0,0,0,0,0]
由于后面几天都没有交易 , 所以后面几天的rt 都为0 。
10内的pnl:sum(rt) = 22+ 15+ 18-6-9 = 40
年化率 = sum(rt)/本金/交易发生的时间*一年总时间 = 40/100/10*252=1008%
(数字货币一年总时间就是365)
计算的方法:

年化率,夏普率,最大回撤计算方法

文章插图
夏普率 = 年化率/std(rt)/
=0.064
最大回撤率
def MaxDrawdown(rt):'''最大回撤率'''i = np.argmax((np.maximum.accumulate(rt) - rt)/np.maximum.accumulate(rt))# 结束位置if i == 0:return 0j = np.argmax(rt[:i])# 开始位置return (rt[j] - rt[i])/rt[j]
1. 先说一种错误的做法 , 若rt 表示的是现在钱包的总净值 , 则
先将6段交易rt = [10,12,15,18,-6,-9]转化成净利润 [10,22,37,55,49,40] , 再加上本金100元 , rt为
[110, 122, 137, 155, 149, 140]
其中的最大回撤为(155-140)/155 = 0.097
年化率,夏普率,最大回撤计算方法

文章插图
如下所示:
rt = np.cumsum(li)rt = [x+100 for x in rt]print(rt)#[110, 122, 137, 155, 149, 140]print(MaxDrawdown(rt))# 0.0967741935483871
这样子看上去没有问题 , 但实际是错误的 , 当rt = [18,-6,-9]时 , 和原rt的回撤应该是一致的 , 这没有争议 。用上述方法转换一下 , rt为
[118,112,103]
其中的最大回撤为 (118-103)/118 = 0.127
这与上述结果不一致 。
2. 再来说一说正确的做法 , rt表示的应该是每一段交易的净值 。
rt = [x+100 for x in li]print(rt)#[110, 112, 115, 118, 94, 91, 100, 100, 100, 100, 100]print(MaxDrawdown(rt))# 0.2288135593220339
这里换一种方法依旧可以算出正确的结果
【年化率,夏普率,最大回撤计算方法】def max(li):rt = [x/100+1 for x in li]pnl = pd.DataFrame({'rtt':rt})D = pnl['rtt'].cummax() - pnl['rtt']X = D/(D+pnl['rtt'])return X.max()print(max(li))#0.2288135593220339