-
2021-03-18 18:11:23
给定一个净值序列,计算年化收益、最大回撤、夏普比率
数据准备:净值序列
以HS300的收盘价,作为策略的净值
获取数据准备工作
-
安装JQDdata库,JQData使用说明。
-
在聚宽申请账号,并且申请开通JQData权限。
-
Python版本: Python3.7
# 从聚宽JQData获取HS300从2015至2018年底,每个交易日的收盘价 # 导入JQData库 from jqdatasdk import * import pandas as pd # ID是申请时所填写的手机号;Password为聚宽官网登录密码 auth('18800119212','Hsh19980121') pd.set_option('display.max_rows', 10) # 获取HS300每日收盘价,时间:2015-01-01至2018-12-31 df = get_price('000300.XSHG', start_date=&#
更多相关内容 -
-
pandas_计算最大回撤
2022-01-20 14:24:382. 计算财富指数(也就是净值)【PS:初始净值为1】 3. 计算上一个最高点 4. 计算回撤率 5. 找出最大回撤 日期 收益率 财富指数(净值) 上一个高点 回撤率 02-19 0.014483 1*(1+0.014483) ...目录
概念
计算方法
1. 将收益率做成时间序列
2. 计算财富指数(也就是净值)【PS:初始净值为1】
3. 计算上一个最高点
4. 计算回撤率
5. 找出最大回撤日期 收益率 财富指数(净值) 上一个高点 回撤率 02-19 0.014483 1*(1+0.014483)
=1.014483
1.014483 0 02-20 -0.010259 1.014483*(1-0.010259)
=1.004075
1.014483 -0.010259 02-21 -0.022635 1.004075*(1-0.022635)
=0.981348
1.014483 -0.032662 02-24 -0.047500 0.981348*(1-0.047500)
=0.934734
1.014483 -0.078611 02-25 -0.033872 0.934734*(1-0.033872)
=0.903072
1.014483 -0.109820 02-26 0.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'] <= temp_lv: # 当前值小于此前的最小值,说明数值还在往下走 temp_lv = row['value'] temp_lv_date = row['date'] temp_lv_loc= row['count'] temp_duration = temp_hv-temp_lv # 最后一次的回撤:最后的价格一直没有超过此前一次的最高价,最后一次的回撤会无法触发记录的条件 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])
# 抽取出回撤大于等于10%的区间,并在图中标出 final_list = [] for item in res_list: if item[-2]>=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)
-
python计算股票净值和复利
2018-12-03 19:42:05# -*- coding: utf-8 -*- """ Created on Wed Mar 14 21:38:49 2018 E-mail: Eric2014_Lv@sjtu.edu.cn @author: DidiLv ""...from pandas import DataFrame odata = pd.r...# -*- coding: utf-8 -*- """ Created on Wed Mar 14 21:38:49 2018 E-mail: Eric2014_Lv@sjtu.edu.cn @author: DidiLv """ import pandas as pd import numpy as np from pandas import DataFrame odata = pd.read_csv('investment_rate.csv') Profit_pool = pd.DataFrame(odata) # size m, n = Profit_pool.shape np_profit_pool = np.array(Profit_pool) date = np_profit_pool[:,0] num_date = m # 确定跳跃点即时间不连续点 skip_id = [-1] for id in range(num_date-1): if date[id + 1] - date[id] >= 3: skip_id.append(id) skip_id.append(m-1) skip_id = np.array(skip_id) # 确定添加复利和净值后的矩阵大小 num_skip = len(skip_id)-1 profit_pool_week_and_month_profit = np.zeros([1,n]) week_profit_month = np.ones([2,n-1]) print("-----------skip-------------") print(skip_id) for count in range(len(skip_id)-1): np_week = np_profit_pool[skip_id[count]+1:skip_id[count+1]+1,1:n] profit_pool_week_and_month_profit = np.vstack((profit_pool_week_and_month_profit,np_profit_pool[skip_id[count]+1:skip_id[count+1]+1,:])) # 计算复利和净值 mm,nn = np_week.shape np_week_new = np_week + np.ones([mm,nn]) week_profit_month[0,:] = np_week_new.prod(axis = 0) for ii in range(n-1): week_profit_month[0,ii] -= 1 week_profit_month[1,ii] *= week_profit_month[0,ii] + 1 #这里只是用2e10和2e11做成一个表示符表示复利和净值 temp = np.column_stack((np.array((2e10,2e11)),week_profit_month)) profit_pool_week_and_month_profit = np.vstack((profit_pool_week_and_month_profit,temp)) print("-----np_week-----------") print(np_week) print("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++") np.savetxt('profit_pool_week_and_month_profit.csv', profit_pool_week_and_month_profit, delimiter = ',')
-
pandas_计算年化收益率
2022-01-20 14:44:31计算过程(jupyter notebook): import pandas as pd df = pd.read_csv('./temptemp.csv',encoding='utf-8') df['o_date'] = df['date'] df['o_date'] = pd.to_datetime(df['o_date']) df.目录
一、当数据为净值,求年化收益率
前置:
文章中用到的数据
链接:https://pan.baidu.com/s/1rKLM45dq_xIKxcI54Nq0qg
提取码:c298公式:
计算过程(jupyter notebook):
import pandas as pd df = pd.read_csv('./temptemp.csv',encoding='utf-8') 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.head()
# value值从1开始,每一日的value是当日的净值 # 对应到公式,第一行的value为初始净值,最后一行的value为最终净值 first_one = df.iloc[0] last_one = df.iloc[-1] annual_profilt = pow(last_one['value']/first_one['value'],250/len(df))-1 annual_profilt
二、当数据为收盘价,求年化收益率
推导:
设,
1. 周期为p,例如p可以是日、周、月、季度等,对应的就是日收益率、周收益率、月收益率、季度收益率等;数据个数为N
2. 每期收益率为Rp,每期平均收益率为
,年化平均收益率为
3. 对应周期p,一年有m个周期p,例如:p为日,m为252;p为周,m为52;p为月,m为12等
求,
1. 每期平均收益率
2. 年化收益率
代码:
import numpy as np import pandas as pd import matplotlib.pyplot as plt %matplotlib inline df_aapl = pd.read_csv('AAPL.csv',encoding='utf-8') df_aapl.head()
df_aapl['ret'] = df_aapl['Close'].pct_change() df_aapl.head()
df_aapl['ret'].plot(figsize=(8,4))
# 计算日平均收益率 # prod() 将所有数值乘起来 r_daily_mean = ((1+df_aapl['ret']).prod())**(1/df_aapl.shape[0])-1 r_daily_mean # out: 0.0006941719590121131 # 计算年收益率 annual_rets = (1+r_daily_mean)**252-1 annual_rets # out: 0.19109213356890775 # 适用不同周期收益率计算年化收益率函数 def annualize_rets(returns,n_periods): ''' 给定一系列的收益率和期数,算出年化收益率 ''' # 每一期的平均收益 r_periodic_mean = ((1+returns).prod())**(1/returns.shape[0])-1 return (1+r_periodic_mean)**n_periods-1 annualize_rets(df_aapl['ret'],252) # out: 0.19109213356890775
-
【邢不行|量化小讲堂系列36-python量化入门】如何通过3行Python代码计算最大回撤
2020-12-09 23:23:35如何通过3行Python代码计算最大回撤作者:陈可桐 修改:邢不行如何评价一个量化策略的好坏?我自己的话,首先是看年化收益。收益太差,基本就不用看了。其次我就看最大回撤。最大回撤属于风险指标... -
Pandas个人操作练习(1)创建dataframe及插入列、行操作
2018-08-03 17:30:28使用pandas之前要导入包: import numpy as np import pandas as pd import random #其中有用到random函数,所以...pandas.DataFrame(data=None,index=None,columns=None,dtype=None,copy=False) data:numpy... -
python 计算收益回撤比
2022-04-17 20:50:45最大回撤是指在选定周期内任一历史时点往后推,产品净值走到最低点时的收益率回撤幅度的最大值,收益回撤比是收益与最大回撤比值 -
python:pandas DataFrame 连接表
2019-12-07 13:41:16以画基金净值与龙头股收盘价比较图为例: 512071.csv 数据格式 date,jz,ljjz 2016-01-04,1.7296,1.7296 600030.csvtushare 数据格式 ,date,open,close,high,low,volume,code 0,2017-04-11,15.537,15.546,15.565,... -
Python Pandas dataframe.pct_change()用法及代码示例
2020-11-28 17:29:48Pandas dataframe.pct_change()函数计算当前元素与先前元素之间的百分比变化。默认情况下,此函数计算前一行的百分比变化。注意:此功能在时间序列数据中最有用。用法: DataFrame.pct_change(period... -
padas数据结构:DataFrame
2017-12-07 11:33:41padas数据结构:DataFrame文档地址: http://pandas.pydata.org/pandas-docs/stable/dsintro.html#dataframeimport pandas as pd user1 = pd.Series(["jack","男",22], index=["name","sex","age"]) user2 = pd.... -
【python量化】用Python获取基金历史净值数据
2020-08-03 11:30:00日增长率的计算方式是:(当前交易日净值-上一交易日净值)/上一交易日净值。在上面的返回结果中,还需要注意的是,记录一共有36条,有两页数据,返回的结果是第一页。 代码编写 在分析完接口以及返回数据类型之后,... -
python pandas DataFrame.pct_change用法及代码示例
2020-12-02 11:41:01当前元素与先前元素之间的百分比变化。...fill_method:str, 默认为 ‘pad’在计算百分比变化之前如何处理资产净值。limit:int, 默认为 None停止前要填充的连续NA数。freq:DateOffset, timedelta, 或 ... -
pandas计算年化收益波动率
2022-01-20 14:56:17前置: 文章中用到的数据 ...提取码:c298 公式: 样本标准差公式 ...计算过程(jupyter notebook): import pandas as pd import math df = pd.read_csv('temptemp.csv',encoding='utf-8') df['o_dat.. -
Python爬虫周记之案例篇——基金净值Selenium动态爬虫
2020-12-08 06:07:50在成功完成基金净值爬虫的爬虫后,简单了解爬虫的一些原理以后,心中不免产生一点困惑——为什么我们不能直接通过Request获取网页的源代码,而是通过查找相关的js文件来爬取数据呢?有时候我们在用requests抓取页面... -
vn.py源码解读(八、回测结果计算代码解析)
2018-12-29 17:52:25我们核心关注一下calculateBacktestingResult这个方法,这个方法中最核心的是一个大循环。 for trade in self.tradeDict.values(): ... # 若不进行复制直接操作,则计算完后所有成交的数量会变成0 ... -
【爬虫】爬取天天基金历史净值数据&基金收益可视化~
2021-04-18 23:44:22一部分为爬虫,根据基金代码爬取历史净值数据; 一部分为可视化,通过pyecharts绘制基金收益图表; 爬虫 这边以诺安成长混合基金为例,其他基金也一样; 接口获取 打开... -
Python获取基金收益计算
2021-01-10 22:26:53将数据转换为Dataframe对象 np_records = np.array(records) fund_df = pd.DataFrame() for col, col_name in enumerate(heads): fund_df[col_name] = np_records[:, col] # 按照日期排序 fund_df['净值日期'] = pd.... -
python:基金净值与龙头股收盘价 数据的相关性分析
2020-10-24 23:04:03广发消费升级股票基金净值 与 贵州茅台收盘价数据的相关性分析: diff_corr_2.py # coding: utf-8 import os, sys from datetime import datetime import matplotlib.pyplot as plt import pandas as pd # ... -
计算风险指标:最大回撤、计算风险收益指标:夏普比率、利用最大回撤和夏普比筛选基金、比较3只股票的夏普...
2021-12-26 08:29:05接着上一次获取股票数据【实时更新股票数据、创建你的股票数据】、计算交易...最大回撤是指在选定周期内任一历史时点往后推,产品净值走到最低点时的收益率回撤幅度的最大值,是一个非常重要的风险指标。 如何计算 -
股票python量化交易016-计算最大回撤
2022-05-22 22:35:15资产分析中的最大回撤指的是在投资期间内可能出现最大损失的情况,即产品净值走到最低点时股票收益率撤回幅度的最大值,用来衡量账户的抗风险能力,是一个非常重要的风险指标! 如何计算最大回撤? 在选定的... -
【Python】基金/股票 最大回撤率计算与绘图详解(附源码和数据)
2020-05-20 21:33:15t = [groupby_year_month.index[0], _[_max], _[_min], _[_max] - _[_min], (_[_max] - _[_min]) / _[_max] * 100] # date、max、min、diff、rate res.append(t) # 转DataFrame result = pd.DataFrame(res, columns=... -
Python计算量化策略评估指标
2019-09-09 17:40:02年化收益率是把当前收益率(日收益率、周收益率、月收益率)换算成年收益率来计算的,是一种理论收益率,并不是真正的已取得的收益率。因为年化收益率是变动的,所以年收益率不一定和年化收益率相同。 总收益率:R=... -
Rank IC 的计算问题
2020-06-17 21:59:17最近实习中研究基金经理的风格归因,需要计算因子的Rank IC。数据集是matlab的.mat文件。 主要涉及的知识点: .mat文件的加载 pandas数据处理 先贴下结果: mark一下源码: # -*- coding: utf-8 -*- """ Created ... -
pandas计算最大回撤
2020-03-23 18:04:47因参考文章实现的是一个series的数据,而我需要处理整个dataframe里面的指标,而这时还不太清楚pandas.groupby.apply的用法 pandas.groupby.agg是对分组中的某一列进行处理,是将该列传递给agg的函数,当需要同时... -
python:np.diff() 计算差值和升跌幅百分比
2020-01-29 13:17:01计算基金净值的差值和升跌幅百分比 基金净值文件数据格式: date,jz,ljjz 2016-01-04,1.1141,1.1141 2016-01-05,1.1161,1.1161 2016-01-06,1.1350,1.1350 csv2txt.py # coding=utf-8 import os, sys import ... -
量化选股后,每个选股周期股票组合的资金曲线计算,groupby和numpy的结合使用,用于回测
2021-01-03 19:56:41计算规则:根据每只股票的下周日涨跌幅,算出每只股票下周的日资金曲线,同时等权买入,再将每日计算的资金曲线取平均,相当于最后将以上数据输出一个有5个数值的list。(一周有5个交易日) 量化框架中的代码: # ...
收藏数
276
精华内容
110