pandas

您所在的位置:网站首页 基金净值收益计算是与你开始买的计算吗 pandas

pandas

2024-07-17 09:00| 来源: 网络整理| 查看: 265

目录

概念 

一、数据为收盘价,计算最大回撤

二、数据为净值,计算最大回撤

概念 

计算方法

1. 将收益率做成时间序列 2. 计算财富指数(也就是净值)【PS:初始净值为1】 3. 计算上一个最高点 4. 计算回撤率 5. 找出最大回撤

日期收益率财富指数(净值)上一个高点回撤率02-190.014483

1*(1+0.014483)

=1.014483

1.014483002-20-0.010259

1.014483*(1-0.010259)

=1.004075

1.014483-0.01025902-21-0.022635

1.004075*(1-0.022635)

=0.981348

1.014483-0.03266202-24-0.047500

0.981348*(1-0.047500)

=0.934734

1.014483-0.07861102-25-0.033872

0.934734*(1-0.033872)

=0.903072

1.014483-0.10982002-260.015864

0.903072*(1+0.015864)

=0.917398

1.014483-0.095699 一、数据为收盘价,计算最大回撤 import pandas as pd import numpy as np import matplotlib.pyplot as plt %matplotlib inline df_aapl = pd.read_csv('AAPL.csv',encoding='utf-8') df_aapl['ret'] = df_aapl['Close'].pct_change() df_aapl['Date'] = pd.to_datetime(df_aapl['Date']) df_aapl.set_index('Date',inplace=True) df = df_aapl.iloc[-504:] df.head()

 

# 构建财富指数 wealth = 1*(1+df['ret']).cumprod() wealth.head()

 

wealth.plot()

 

# 计算上一个最高点 previos_max = wealth.cummax() previos_max.plot()

 

# 计算回撤率 drawdowns = (wealth-previos_max)/previos_max drawdowns.plot()

 

# 找出最大回撤 drawdowns.min() # out: -0.30668685958066383 # 最大回撤对应的日期 drawdowns.idxmin() # out: Timestamp('2020-03-23 00:00:00')

 将上面的计算过程组合成一个函数

def drawdown(return_series:pd.Series): ''' 把一个时间序列做成最大回撤的表格 表格字段为: 财富指数 上一个最大值 回撤率 ''' wealth = 1*(1+return_series).cumprod() previos_max = wealth.cummax() drawdowns = (wealth-previos_max)/previos_max return pd.DataFrame({'wealth':wealth, 'previos_max':previos_max, 'drawdowns':drawdowns}) res_df = drawdown(df['ret']) res_df.head()

 

res_df.plot(y=['wealth','previos_max'],figsize=(8,4))

 

res_df.plot(y='drawdowns',figsize=(8,4),color='k')

 

 

二、数据为净值,计算最大回撤

前置: 

文章中用到的数据

链接:https://pan.baidu.com/s/1rKLM45dq_xIKxcI54Nq0qg  提取码:c298

最终效果图:

计算过程(jupyter notebook):

import matplotlib.pyplot as plt import pylab as pl import pandas as pd import math df = pd.read_csv('./temptemp.csv',encoding='utf-8') df.head()

# 绘制折线图,标记回撤区域 def draw_trend_and_withdraw(xs,ys,title,res_points): plt.figure(figsize=(20,10)) plt.rcParams['font.sans-serif'] = ['SimHei'] plt.rcParams['axes.unicode_minus'] = False xs00 = range(len(xs)) plt.plot(xs00,ys) # 只显示10个x轴刻度 xs00_=[] xs_ =[] for i in range(0,len(xs),math.floor(len(xs)/10)): xs00_.append(i) xs_.append(xs[i]) plt.xticks(xs00_,xs_,rotation=30) plt.title(title) for item in res_points: min_x = item['min_x'] min_y = item['min_y'] max_x = item['max_x'] max_y = item['max_y'] show_min_str = item['show_min_str'] show_max_str = item['show_max_str'] withdraw = item['withdraw'] 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='--') # 连接最低净值点和最高净值点 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)) # 标记提示 pass plt.show() df['o_date'] = df['date'] df['o_date'] = pd.to_datetime(df['o_date']) df.dropna(inplace=True) df.sort_values(by='o_date',ascending=True,inplace=True) df['count'] = range(len(df)) # count用于标识折线图x轴的位置 res_list = [] temp_hv = None # 记录当前最大值 temp_hv_date = None # 记录当前最大值对应的日期 temp_hv_loc = None # 记录当前最大值所在的位置 temp_lv = None # 记录当前最小值 temp_lv_date = None # 记录当前最小值对应的日期 temp_lv_loc = None # 记录当前最小值所在的位置 temp_duration = None # 最大值与最小值之间的差 for i,row in df.iterrows(): if temp_hv is None: temp_hv = row['value'] temp_hv_date = row['date'] temp_hv_loc = row['count'] temp_lv = row['value'] temp_lv_date = row['date'] temp_lv_loc = row['count'] temp_duration = 0 else: if row['value'] > temp_hv: # 如果值大于此前的最大值,说明要进行新一轮的回撤,记录当前这一轮回撤的信息 # 计算回撤百分比 temp_pct = (temp_duration/temp_hv)*100 res_list.append([temp_hv_loc,temp_hv_date,temp_hv,temp_lv_loc,temp_lv_date,temp_lv,temp_pct,temp_duration]) temp_hv = row['value'] temp_hv_date = row['date'] temp_hv_loc = row['count'] temp_lv = row['value'] temp_lv_date = row['date'] temp_lv_loc = row['count'] temp_duration = 0 pass else: if row['value'] =10: pct_ = round(item[-2],2) final_list.append({ "min_x":item[0], "min_y":item[2], "max_x":item[3], "max_y":item[5], "show_min_str":item[1], "show_max_str":item[4], "withdraw":str(pct_)+'%' }) xs = df['date'].values.tolist() ys = df['value'].values.tolist() title_str = '回撤大于等于10%' draw_trend_and_withdraw(xs,ys,title_str,final_list)



【本文地址】


今日新闻


推荐新闻


    CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3