最大回撤率(Python实现)

最大回撤率


    在选定周期内任一历史时点往后推,产品净值走到最低点时的收益率回撤幅度的最大值。最大回撤用来描述买入产品后可能出现的最糟糕的情况。最大回撤是一个重要的风险指标,对于对冲基金和数量化策略交易,该指标比波动率还重要。
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.
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值