最大回撤python_最大回撤,最大回撤恢复时间与最大回撤持续期
概要
这两个概念在刚接触量化分析时,实在时折腾了许久,故在此作下总结。
内容
最大回撤(Max Drawdown)
简单来说最大回撤就是从一个高点到一个低点最大的下跌幅度,用来描述一个策略可能出现的最糟糕的情况,衡量了最极端可能的亏损。如果一个策略的最大回撤是 50%,那么它的意思是,运气不好的话,我们的持有价值可能要拦腰截断了。计算公式为
\begin{align} \label{e6}
MaxDrawDown_t = \max(1-\frac{P_j}{P_i} )
\end{align}
其中
\(MaxDrawDown_t\) 为 \(t\) 日的最大回撤
\(P_i\) 和 \(P_j\) 分别为 \(i\) 日和 \(j\) 日的策略总资产,且需要满足 \(t \geqslant j >i\)
有的教程给出的计算公式是刚好反过来的,即取负值,实际计算公式是一样的,了解下即可。公式可能看起来为容易理解,用语言描述就是
\begin{align} \label{e7}
MaxDrawDown_t = 1-\frac{t \text{日持有价值}}{t \text{日之前持有最高价值}}
\end{align}
这样是不是容易理解多了。
最大回撤恢复时间(Max Drawdown)
这个我的理解是:从最大回撤结束时间开始,需要多久才能达到回撤前的顶峰状态。这个可以参考图示。
最大回撤持续期(MaxDrawDownDuration)
最大回撤持续期描述的是持有价值从回撤开始到再创新高所经历的时间,如果说最大回撤是在资产空间维度上描述资产的波动风险,那么最大回撤持续期则是在资产的时间维度上给出一个风险描述。直观地说就是资产创新高的频率是怎样的。
图示
下边一张图展示了我们介绍的三个概念,直观地表示了三个概念范围。
图 1:回撤效果图!
源代码
本篇用的代码(python)如下,该代码也包含了 python 绘折线图的大部分设置,可以作为参考。
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sun Jun 2 15:32:13 2019
@author: zk
"""
import datetime
import matplotlib.pyplot as plt
import matplotlib.dates as mdate
import matplotlib.ticker as ticker
import numpy as np
import random
DAYS = 365
def Init():
timedelta = datetime.timedelta(days = 1)
startdate = datetime.date.today()
xdate = [startdate+i*timedelta for i in range(DAYS)]
ycapital = [3000]
for _ in range(DAYS-1):
ycapital.append(ycapital[-1]+random.uniform(-1, 1.1))
return xdate, ycapital
def max_drawdown(xdate, ycapital):
# 计算每日的回撤
drawdown = []
tmp_max_capital = ycapital[0]
for c in ycapital:
tmp_max_capital = max(c, tmp_max_capital)
drawdown.append(1 - c / tmp_max_capital)
# 最大回撤
MaxDrawdown = max(drawdown)
# 计算最大回撤日期范围
endidx = np.argmax(drawdown)
#enddate = xdate[endidx]
startidx = np.argmax(ycapital[:endidx])
#startdate = xdate[startidx]
#仅仅画图的话,我们只要索引值更加方便
return MaxDrawdown, startidx, endidx
def max_drawdown_duration(xdate, ycapital):
duration = []
tmp_max_capital = ycapital[0]
for c in ycapital:
if c >= tmp_max_capital:
duration.append(0)
else:
duration.append(duration[-1]+1)
tmp_max_capital = max(c, tmp_max_capital)
MaxDDD = max(duration)
#fig, ax = plt.subplots(figsize = (21, 9))
#plt.plot(xdate, duration)
#ax.xaxis.set_major_formatter(mdate.DateFormatter('%Y-%m-%d'))
endidx = np.argmax(duration)
startidx = endidx - MaxDDD
return MaxDDD, startidx, endidx
def max_drawdown_restore_time(startidx, endidx, xdate, ycapital):
"""
startidx:表示最大回撤的开始时间在 xdate 中的索引,由 max_drawdown 方法返回
endidx:表示最大回撤的结束时间在 xdate 中的索引,由 max_drawdown 方法返回
"""
maxdd_resore_time = 0
restore_endidx = np.inf
for t in range(endidx, len(xdate)):
if ycapital[t] >= ycapital[startidx]:
restore_endidx = t
break
else:
maxdd_resore_time += 1
restore_endidx = min(restore_endidx, len(xdate)-1)
return maxdd_resore_time, restore_endidx
def plot(xdate, ycapital):
# 指定画布大小
fig, ax = plt.subplots(figsize = (21, 9))
# 绘图并设置颜色,图例标签,线宽
plt.plot(xdate, ycapital, 'red', label = 'My Strategy', linewidth = 2)
# 绘制最大回撤日期范围标识 marker = 'v'
MaxDrawdown, startidx, endidx = max_drawdown(xdate, ycapital)
print("最大回撤为:", MaxDrawdown)
plt.scatter([xdate[startidx], xdate[endidx]], [ycapital[startidx], ycapital[endidx]],
s = 100, c = 'b', marker = 's', label = 'MaxDrawdown')
# 绘制最大回撤恢复时间
maxdd_resore_time, restore_endidx = max_drawdown_restore_time(startidx, endidx, xdate, ycapital)
print("最大回撤恢复时间为(天):", maxdd_resore_time)
plt.scatter([xdate[endidx], xdate[restore_endidx]], [ycapital[endidx], ycapital[restore_endidx]],
s = 100, c = 'cyan', marker = 'D', label = 'MaxDrawdown Restore Time')
# 绘制最大回撤持续期标识 marker = 'D'
MaxDDD, startidx, endidx = max_drawdown_duration(xdate, ycapital)
plt.scatter([xdate[startidx], xdate[endidx]], [ycapital[startidx], ycapital[endidx]],
s = 80, c = 'g', marker = 'v', label = 'MaxDrawdown Duration')
print("最大回撤持续期为(天):", MaxDDD)
# 设置刻度值颜色
plt.yticks(color = 'gray')
# 设置 y 轴百分比显示,注意将 y 轴数据乘以 100
#ax.yaxis.set_major_formatter(ticker.FormatStrFormatter('%.2f%%'))
# 颜色,旋转刻度
plt.xticks(color = 'gray',rotation = 15)
# 指定字体,大小,颜色
fontdict = {"family":"Times New Roman", 'size':12, 'color':'gray'} #Times New Roman, Arial
plt.title("random account value", fontdict = fontdict)
plt.xlabel("date(day)", fontdict = fontdict)
plt.ylabel("account value", fontdict = fontdict)
# 去掉边框 top left right bottom
ax.spines['top'].set_visible(False)
ax.spines['left'].set_visible(False)
ax.spines['right'].set_visible(False)
# 设置 x 轴颜色
ax.spines['bottom'].set_color('lightgray')
#设置时间标签显示格式
ax.xaxis.set_major_formatter(mdate.DateFormatter('%Y-%m-%d'))
#设置时间刻度间隔
#timedelta = (xdate[-1] - xdate[0]) / 10 # 这种方式不能保证显示最后一个日期
#plt.xticks(mdate.drange(xdate[0], xdate[-1], timedelta))
# 分成 10 份
delta = round(len(xdate) / 9)
plt.xticks([xdate[i*delta] for i in range(9)] + [xdate[-1]])
#通过修改tick_spacing的值可以修改x轴的密度
#ax.xaxis.set_major_locator(ticker.MultipleLocator(10))
# 去掉 y 轴刻度线,四个方向均可设置
plt.tick_params(left = 'off')
# 设置刻度的朝向,宽,长度
plt.tick_params(which = 'major', direction = 'out', width = 0.2, length = 5) # in, out or inout
# 设置刻度显示在哪个方向上
#tick_params(labeltop='on',labelbottom='off',labelleft='off',labelright='off')
# 设置 y 轴方向的网络线
plt.grid(axis = 'y', color = 'lightgray', linestyle = '-', linewidth = 0.5)
# 设置图例 列宽:columnspacing=float (upper left)
plt.legend(loc = 'best', fontsize = 12, frameon=False, ncol = 1)
# 设置图例字体颜色
#leg = 上一行 plt.legend 的返回值
#for line,text in zip(leg.legendHandles, leg.get_texts()):
# text.set_color(line.get_color())
fig.show()
# fig.savefig("test.png") # dpi = 150
if __name__ == '__main__':
# 构造绘图数据
xdate, ycapital = Init()
plot(xdate, ycapital)
#max_drawdown_duration(xdate, ycapital)
最大回撤python_最大回撤,最大回撤恢复时间与最大回撤持续期相关推荐
- 最大回撤,最大回撤恢复时间与最大回撤持续期
概要 这两个概念在刚接触量化分析时,实在时折腾了许久,故在此作下总结. 最大回撤 最大回撤恢复时间 最大回撤持续期 图示 源代码 内容 最大回撤(Max Dra ...
- matlab最长回撤期,最大回撤,最大回撤恢复时间与最大回撤持续期
概要 这两个概念在刚接触量化分析时,实在时折腾了许久,故在此作下总结. 内容 最大回撤(Max Drawdown) 简单来说最大回撤就是从一个高点到一个低点最大的下跌幅度,用来描述一个策略可能出现的最 ...
- c语言判断回文字符串递归,用递归实现判断一个字符串是否为回文串
//用递归实现判断一个字符串是否为回文串 import java.util.Scanner; public class Palindrome { //判断是否为回文串 in型参数代表字符串起止位置 p ...
- 统计5个字符串回文个数c语言,第一章 字符串 – 1.5 最长回文子串 - 编程之法:面试和算法心得...
最长回文子串 题目描述 给定一个字符串,求它的最长回文子串的长度. 分析与解法 最容易想到的办法是枚举所有的子串,分别判断其是否为回文.这个思路初看起来是正确的,但却做了很多无用功,如果一个长的子串包 ...
- “回文串”是一个正读和反读都一样的字符串,比如“level”或者“noon”等等就是回文串。花花非常喜欢这种拥有对称美的回文串,生日的时候她得到两个礼物分别是字符串A和字符串B。
1.题目描述 "回文串"是一个正读和反读都一样的字符串,比如"level"或者"noon"等等就是回文串. 花花非常喜欢这种拥有对称美的回文 ...
- 回文数,给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false 。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。
力扣题目回文数 给你一个整数 x ,如果 x 是一个回文整数,返回 true :否则,返回 false . 回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数. 例如,121 是回文,而 1 ...
- python回测a股_第20节 A股全市场回测
第20节 A股全市场回测 作者: 阿布 阿布量化版权所有 未经允许 禁止转载 在第19节'数据源'中分别获取了各个市场的6年交易数据,本节将做A股市场全市场回测. 买入因子,卖出因子等依然使用相同的设 ...
- java最长回文子序列_在一个字符串里面怎么找出最长回文子序列长度
回文字符串是什么?类似于level,noon,abbba这种,就是从左读和从右读都是同一个字符串.... 先说一下我的思路: 比如现在有字符串:"12212321" 1,先在每个字 ...
- 计算风险指标:最大回撤、计算风险收益指标:夏普比率、利用最大回撤和夏普比筛选基金、比较3只股票的夏普指数
接着上一次获取股票数据[实时更新股票数据.创建你的股票数据].计算交易指标[买入.卖出信号.计算持仓收益.计算累计收益率] - cexo - 博客园的量化交易往下学习. 计算风险指标:最大回撤 什么是 ...
最新文章
- 多条件组合查询+分页
- 奇淫怪巧之在Delphi中调用不申明函数
- 【Linux入门连载一】[Win10下安装Linux虚拟机]VMWare15运行CentOS7(亲测有效)
- python实现分布式_Python如何快速实现分布式任务
- 前端:JS操作数字类库
- 有效的形成传感器(执行器)的控制方式
- 漫步数学分析十七——连续映射上的运算
- 如何实现文件上传 - JavaWeb
- 智能语音识别系统-解决方案.pdf
- Ambari HDP 完整安装手册
- AcWing 874. 筛法求欧拉函数(欧拉函数)
- [C/C++] C/C++延伸学习系列之STL及Boost库概述
- Windows Server 2013 安装zune 4.8中文版
- 【bzoj 3815】卡常数
- 小白学习java连通、操作mysql数据库小记(更新中)
- 报错——xxx is not defined
- 讓TQ2440也用上設備樹(1)
- Android照片处理——涂鸦和拼图实现
- 华为新系统鸿蒙接入,魅族宣布接入鸿蒙系统,支持华为,给力!
- String类型的测量长度
热门文章
- 那些超好听却不红的歌
- 最快的计算机操作,自学电脑操作怎样比较快?
- 腾讯漫画(js逆向)
- 大象知道“故事怎么讲”
- 【2021-12-22】【Kotlin】Type inference failed. Expected type mismatch: inferred type is HashSet but Set
- 《淘宝网开店 拍摄 修图 设计 装修 实战150招》导读
- 人生的三把钥匙,太经典了!
- 位、字节、字、字长的概念以及存储单位的的换算
- MATLAB | solve函数求解析解时不支持分段函数的解决方案
- Spyder学习笔记1-Jack Xu