【Python】基金/股票 最大回撤率计算与绘图详解(附源码和数据)

如果你想找的是求最大回撤的算法,请跳转:[Python] 使用动态规划求解最大回撤详解

0. 起因

前一段时间投了一家金融公司的Python开发工程师,让我做以下事情:

  1. 以月为窗口,挑选一只基金or股票,查看它近2年最大回撤率;
  2. 找到从08年-至今的金融危机时间段,并呈现在这些危机时间段内,该基金or股票的历次回撤率。

给了3天时间,代码我1天不到就写完了,写完之后我就去做自己的项目了,沉迷技术无法自拔~~~

3天过后,没想到打电话过来的是产品经理,完全不问代码的事情,问我平时是怎么学习的;问我有没有考虑为什么要分析这些东西;问我以后的方向;问我学习中遇到过的最大的问题是什么,我说了我最近做的一个网站遇到的问题;

我觉得自己答的都还不错,也许是没答到人家内心里去吧,问了几个问题之后,我感觉人家貌似情绪有点不对了。隔了几天才收到技术面,问的都是NumPy和Pandas,因为几个月前学的还不错,加上问的比较基础(没有涉及到时间序列和透视表那些),所以大部分问题都答上来了。不过还是没有收到Offer,缘分未到~

言归正传,我选了一家老牌的基金 github 源码和数据

1. 大成沪深300指数A 519300 最大回撤率分析

数据来源:http://fund.eastmoney.com/519300.html?spm=search
天天基金官网:大成沪深300指数A 519300

0. 基金走势图 2007 - 2020

在这里插入图片描述
官网上分析数据接口,清洗数据之后,我绘制出来的图 2006 - 2020
在这里插入图片描述

1. 以月为窗口,挑选一只基金or股票,查看它近2年最大回撤率;

在这里插入图片描述

2.找到从08年-至今的金融危机时间段,并呈现在这些危机时间段内,该基金or股票的历次回撤率。

很多基金成立年限都不高没有经历过金融危机,这只基金是我找了些资料才找出来的,成立了14个年头

2. 绘制走势图和最大回撤的函数封装

封装了两个函数,一个用于绘制走势图,一个用于绘制走势图和回撤率。效果如下:

import matplotlib.pyplot as plt
import pylab as pl


def draw_trend_chart(xs, ys, title):
    """ 根据数据绘制折线走势图 """
    plt.rcParams['font.sans-serif'] = ['SimHei']
    plt.rcParams['axes.unicode_minus'] = False
    plt.plot(xs, ys)  # 根据数据绘制折线走势图
    plt.title(title)
    plt.show()


def draw_trend_and_withdraw(xs, ys, title, max_x, max_y, show_max_str, min_x, min_y, show_min_str, 
                            withdraw, withdraw_x=None, withdraw_y=None, x_ticks_rotation=None):
    """ 根据数据绘制折线走势图和最大回撤信息 """
    """
    xs: x轴数组
    ys: y轴数组
    title: 走势图标题
    max_x, max_y: 最大回撤最高点的x值和y值
    min_x, min_y: 最大回撤最低点的x值和y值
    show_max_str: 最大回撤最高点的标记提示
    show_min_str: 最大回撤最低点的标记提示
    withdraw: 最大回撤值
    withdraw_x: 最大回撤值提示点的x值
    withdraw_y: 最大回撤值提示点的y值
    """
    plt.rcParams['font.sans-serif'] = ['SimHei']
    plt.rcParams['axes.unicode_minus'] = False
    plt.plot(xs, ys)  # 根据数据绘制折线走势图
    plt.title(title)

    plt.scatter(min_x, min_y, color='r')  # 标记最低点
    plt.scatter(max_x, max_y, color='r')  # 标记最高点
    plt.annotate(show_min_str, xytext=(min_x, min_y), xy=(min_x, min_y))  # 标记提示
    plt.annotate(show_max_str, xytext=(max_x, max_y), xy=(max_x, max_y))  # 标记提示

    plt.plot([min_x, max_x], [min_y, max_y], color='b', linestyle='--')  # 连接最低净值点和最高净值点
    if withdraw_x is None or withdraw_y is None:
        plt.annotate(withdraw, xytext=((max_x + min_x) / 2, (max_y + min_y) / 2), xy=((max_x + min_x) / 2, (max_y + min_y) / 2))  # 标记提示
    else:
        plt.annotate(withdraw, xytext=(withdraw_x, withdraw_y), xy=(withdraw_x, withdraw_y))  # 标记提示

    if x_ticks_rotation is not None:    # 旋转 x 轴的标记
        pl.xticks(rotation=60)

    plt.show()


if __name__ == '__main__':
    xs = range(0, 9)
    arr = [3, 7, 2, 6, 4, 1, 9, 8, 5]
    _max, _min = 1, 5   # 最高点索引和最低点索引
    max_rate = 6        # 最大回撤
    draw_trend_chart(xs, arr, title=f'{arr}')
    draw_trend_and_withdraw(list(range(0, 9)), arr, f'{arr}', _max, arr[_max], f'最高点索引:{_max}',
                            _min, arr[_min], f'最低点索引:{_min}', max_rate)

3. 从0到1分析最大回撤率

0. 求取最大回撤的函数

除了两个绘图函数,还有求最大的回撤的函数:

def _withdraw_with_high_low(arr):
    """ 传入一个数组,返回最大回撤和对应的最高点索引、最低点索引 """
    _dp = 0  # 使用 _dp 表示 i 点的最大回撤
    i_high = 0  # 遍历时,0 ~ i - 1 中最高的点的索引,注意是索引

    # 全局最大回撤和对应的最高点和最低点的索引,注意是索引
    g_withdraw, g_high, g_low = float('-inf'), -1, -1

    for i in range(1, len(arr)):
        # 注意:此处求的是
        if arr[i_high] < arr[i-1]:  # 若 0 ~ i - 1 中最高的点小于当前点
            i_high = i-1  # 0 ~ i - 1 中最高的点的索引

        _dp = arr[i_high
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值