最大回撤率
在选定周期内任一历史时点往后推,产品净值走到最低点时的收益率回撤幅度的最大值。最大回撤用来描述买入产品后可能出现的最糟糕的情况。最大回撤是一个重要的风险指标,对于对冲基金和数量化策略交易,该指标比波动率还重要。
D为某一天的净值,i为某一天,j为i后的某一天,Di为第i天的产品净值,Dj则是Di后面某一天的净值
drawdown就是最大回撤率
drawdown=max(Di-Dj)/Di,其实就是对每一个净值进行回撤率求值,然后找出最大的。
举个栗子,
A看好蓝筹白马股,于是花1万买入了某只大蓝筹的基金。在初期时候由于市场利好频出,所以资金账户的净值由1万元变成了1.2万元。后来市场热度从蓝筹白马转向创业板,于是1.2万缩水了变成了0.7万。再接着,国家队进场救市伸大盘,所以0.7万又变成1万。可是没过久,市场风云突变,大盘飞流直下,一直跌到了0.5万。当心灰意冷时割肉时,此基一飞冲天从0.5万直窜到1.5万!这从净值最高点1.5万到最低点0.5万的过程,就是A账户上的最大资金回撤!
根据公式计算,也就是A的最大回撤率为:1.5万 -0.5万/1.5w= 66.67%
在实现前,先来理解几个函数:
1.cumsum函数定义:
- cumsum(a, axis=None, dtype=None, out=None)
- a.cumsum(axis=None, dtype=None, out=None)
返回:沿着指定轴的元素累加和所组成的数组,其形状应与输入数组a一致
其中cumsum函数的参数:
- a:数组
- axis:轴索引,整型,若a为n维数组,则axis的取值范围为[0,n-1]
- dtype:返回结果的数据类型,若不指定,则默认与a一致。
- out:数据类型为数组。用来放置结果的替代输出数组,它必须具有与输出结果具有相同的形状和缓冲长度
2.numpy.maximum:比较两个数组并返回一个包含元素最大值的新数组
3.numpy.ufunc.accumulate: 累计将运算符应用于所有元素的结果。
代码如下:
import numpy as np
import matplotlib.pyplot as plt
def MaxDrawdown(return_list):
'''最大回撤率'''
i = np.argmax((np.maximum.accumulate(return_list) - return_list) / np.maximum.accumulate(return_list)) # 结束位置
if i == 0:
return 0
j = np.argmax(return_list[:i]) # 开始位置
return (return_list[j] - return_list[i]) / (return_list[j])
return_list=[12,12,21,15,27,16,21,22,25,20,16,17]
print(MaxDrawdown(return_list))
例如,return_list=[12,12,21,15,27,16,21,22,25,20,16,17]
那么折线代表return_list的点,蓝点代表从左至右累计出的最大值。
可知,在第五天最大回撤结束,第四天回撤开始。
故输出值为:drawdown=0.4074074074074074
简单点,
假如不用从左至右累计出的最大值的函数np.maximum.accumulate的话,我们可以自己写一个方法,那么就变成这样:
def maxdrawdown(return_list):
"""最大回撤率"""
maxac=np.zeros(len(return_list))
b=return_list[0]
for i in range(0,len(return_list)): #遍历数组,当其后一项大于前一项时,赋值给b
if return_list[i]>b:
b=return_list[i]
maxac[i]=b
print(maxac)
i=np.argmax((maxac-return_list)/maxac) #结束位置
if i == 0:
return 0
j = np.argmax(return_list[:i]) # 开始位置
return (return_list[j] - return_list[i]) / (return_list[j])
下面我们来试试函数cumsum(沿着指定轴的元素累加和所组成的数组)
先 生成服从标准正态分布的100个随机数,然后累加起来,作为数组return_list,
return_list=np.random.randn(100).cumsum()
进行试验,分别
print(MaxDrawdown(return_list))#法一
print(maxdrawdown(return_list))#法二
print(MaxDrawdown(return_list)==maxdrawdown(return_list))结果为True.