Python量策风指标
转 Python量化策略风险指标
如何衡量一个量化策略的好坏?一是比较稳定的收益,二是有严谨的回测,三是有清晰的逻辑。——刘富兵
引言
尽管过去不能代表未来,通过历史回测来评估量化策略仍然是量化投资非常重要的一环。量化回测过程中常用到的指标有年化收益率、最大回撤、beta、alpha、夏普比率、信息比率等(见下图)。目前很多量化网站都能提供Python的量化回测框架,如聚宽 、优矿、万矿、Zipline 、vnpy 和pyalgotrade等,为我们评估量化策略提供了很好的交互平台。毕竟平台的使用有其局限性,如果不借助平台, 如何使用python写一个简单的量化回测框架呢?本文将一步一步为你展示如何使用python计算量化策略风险指标。文中提及股票仅供学习示例,不构成投资建议。
指标含义及公式
1.累计收益率与年化收益率
年化收益率是把当前收益率(日收益率、周收益率、月收益率)换算成年收益率来计算的,是一种理论收益率,并不是真正的已取得的收益率。因为年化收益率是变动的,所以年收益率不一定和年化收益率相同。
累计收益率:
其中,PT是期末卖出时的价格,Pt是期初买入时的价格。
年化收益率:
其中,R是期间总收益率,m是与n(可以是天数、周数、月数)相对应的计算周期,根据计算惯例,m=250、52、12分别指代日、周、月向年化的转换。
2.最大回撤
在选定周期内任一历史时点往后推,于最低点时的收益率回撤幅度的最大值。最大回撤用来描述可能出现的最糟糕的情况。最大回撤是一个重要的风险指标,对于量化策略交易,该指标比波动率还重要。
P为某一天的净值,i为某一天,j为i后的某一天,Pi为第i天的产品净值,Pj则是Pi后面某一天的净值
则该基金的最大回撤计算如下:
即通过对每一个净值进行回撤率求值,然后找出最大的。
3.Beta和Alpha
Beta:相当于业绩评价基准收益的总体波动性,计算如下:
Pi和Pm分别指代个股(组合)、市场(如上证综指)的收益率序列,beta值也常被用来衡量某一策略的系统性风险。
其含义可以简单理解为:如果Beta为1,策略和市场(如沪深300指数)波动相同;如果Beta大于1,策略波动大于市场,如2,则市场上涨10%时,策略上涨20%;反之亦然。如果Beta小于1,则策略波动小于市场,如为0.8,市场上涨10%时,策略上涨8%;反之亦然。
Beta值如何看呢?这得具体问题具体分析,如果是牛市,个股、大盘狂涨,Beta值大的策略占优;如果是熊市,Beta值小的策略占优。
Alpha:实际收益和按照Beta系数计算的期望收益之间的差额。代表策略多大程度上跑赢了预期的收益率。
可以使用资本资产定价模型(CAPM)来估计策略的beta和alpha的值:
E(ri)是股票i的预期收益率,rf是无风险利率,rm是市场指数收益率;beta系数在评估股市波动风险与投资机会的方法中,常用来衡量结构性与系统性风险,可以简单理解为个股波动相对大盘波动的偏离程度。CAPM的计量模型可以表示为:
alpha可以理解为超额收益率,最后一项是随机扰动,可以理解为个体风险。
4.夏普比率和信息比率
夏普比率代表每多承担一份风险,可以获得几份回报,即单位风险所获得的超额回报,该比率越高,策略承担单位风险得到的超额回报越高,所以夏普比率越高越好。
其中,Rp为策略年化收益率,Rf是无风险收益率,QP为年化标准差。
信息比率:含义与夏普比率类似,只不过其参照基准不是无风险收益率,而是策略的市场基准收益率。
其中,Rp为策略年化收益率,Rm为基准年化收益率(如沪深300指数),
Qt为策略与基准每日收益率差值的年化标准差。
Python计算量化指标
使用tushare获取交易数据,考虑最简单的策略:买入持有!分别计算期间总收益率,年化收益率,最大回撤,beta、alpha系数,夏普比率和信息比率。
#先引入后面可能用到的包(package)
importpandasaspd
importnumpyasnp
importmatplotlib.pyplotasplt
%matplotlib inline
#正常显示画图时出现的中文和负号
frompylabimportmpl
mpl.rcParams['font.sans-serif']=['SimHei']
mpl.rcParams['axes.unicode_minus']=False
### 获取数据:tushare开源库(确认已安装好:pip install tushare)
importtushareasts
#起始和结束日期可以自行输入,否则使用默认
defget_data(code,start_date="2009-01-01", end_date="2019-01-18"):
df = ts.get_k_data(code, start=start_date, end=end_date)
df.index=pd.to_datetime(df.date)
returndf.close
#返回收盘价
#以上证综指、贵州茅台、工商银行、中国平安为例
stocks={'sh':'上证综指','600519':'贵州茅台',
'601398':'工商银行','601318':'中国平安'}
#获取上述股票(指数)的每日前复权收盘价
df=pd.DataFrame()
forcode,nameinstocks.items():
df[name]=get_data(code)
df.head()
#以第一交易日2009年1月5日收盘价为基点,计算净值
df_new=df/df.iloc[0]
#将上述股票在回测期间内的净值可视化
df_new.plot(figsize=(16,7))
#图标题
plt.title('股价净值走势',fontsize=15)
#设置x轴坐标
my_ticks = pd.date_range('2008-01-01','2019-01-18',freq='Y')
plt.xticks(my_ticks,fontsize=12)
#去掉上、右图的线
ax=plt.gca()
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
plt.show()
1.累计收益率和年化收益率
收益率可以根据上面公式计算,或使用对数收益率,下面直接根据上面的累计净值来推出累计收益率(累计净值-1)。
### 区间累计收益率(绝对收益率)
total_ret=df_new.iloc[-1]-1
TR=pd.DataFrame(total_ret.values,columns=['累计收益率'],index=total_ret.index)
TR
2.最大回撤
实际上,numpy和pandas借助库函数均可以实现一行代码计算最大回撤。
#numpy:np.maximum.accumulate计算序列累计最大值
code='上证综指'
n_d=((np.maximum.accumulate(df[code])-df[code])/np.maximum.accumulate(df[code])).max()
#pandas使用cummax()计算序列累计最大值
p_d=((df[code].cummax()-df[code])/df[code].cummax()).max()
#打印结果
print(f'numpy方法计算结果:{round(n_d*100,2)}%')
print(f'pandas方法计算结果:{round(p_d*100,2)}%')numpy方法计算结果:52.3%
pandas方法计算结果:52.3%
###年化收益率,假设一年以250交易日计算annual_ret=pow(1+total_ret,250/len(df_new))-1
AR=pd.DataFrame(annual_ret.values,columns=['年化收益率'],index=annual_ret.index)
AR
#定义成函数,减少重复工作
defmax_drawdown(df):
md=((df.cummax()-df)/df.cummax()).max()
returnround(md,4)
md={}
forcode,nameinstocks.items():
md[name]=max_drawdown(df[name])
#最大回撤率结果:
MD=pd.DataFrame(md,index=['最大回撤']).T
MD
3.alpha和beta
#计算每日收益率
#收盘价缺失值(停牌),使用前值代替
rets=(df.fillna(method='pad')).apply(lambdax:x/x.shift(1)-1)[1:]
rets.head()
#市场指数为x,个股收益率为y
fromscipyimportstats
x=rets.iloc[:,0].values
y=rets.iloc[:,1:].values
AB=pd.DataFrame()
alpha=[]
beta=[]
foriinrange(3):
#使用scipy库中的stats.linregress线性回归
#python回归有多种实现方式,
#如statsmodels.api的OLS,sklearn库等等
b,a,r_value,p_value,std_err=stats.linregress(x,y[:,i])
#alpha转化为年化
alpha.append(round(a*250,3))
beta.append(round(b,3))
AB['alpha']=alpha
AB['beta']=beta
AB.index=rets.columns[1:]
#输出结果:
AB
#使用公式法直接计算beta值(见前文公式):
beta1=rets[['上证综指','贵州茅台']].cov().iat[0,1]/rets['上证综指'].var()
beta2=rets[['上证综指','工商银行']].cov().iat[0,1]/rets['上证综指'].var()
beta3=rets[['上证综指','中国平安']].cov().iat[0,1]/rets['上证综指'].var()
print(f'贵州茅台beta:{round(beta1,3)}')
print(f'工商银行beta:{round(beta2,3)}')
print(f'中国平安beta:{round(beta3,3)}')
#输出结果:贵州茅台beta:0.637
工商银行beta:0.614
中国平安beta:1.071
#使用公式法直接计算beta值(见前文公式):
#annual_ret是前文计算出来的年化收益率
alpha1=(annual_ret[1]-annual_ret[0]*beta1)
alpha2=(annual_ret[2]-annual_ret[0]*beta2)
alpha3=(annual_ret[3]-annual_ret[0]*beta3)
print(f'贵州茅台alpha:{round(alpha1,3)}')
print(f'工商银行alpha:{round(alpha2,3)}')
print(f'中国平安alpha:{round(alpha3,3)}')
#输出结果:贵州茅台alpha:0.244
工商银行alpha:0.077
中国平安alpha:0.138
4.夏普比率和信息比率
#超额收益率以无风险收益率为基准
#假设无风险收益率为年化3%
exReturn=rets-0.03/250
#计算夏普比率
sharperatio=np.sqrt(len(exReturn))*exReturn.mean()/exReturn.std()
#夏普比率的输出结果
SHR=pd.DataFrame(sharperatio,columns=['夏普比率'])
SHR
###信息比率
#超额收益率以指数收益率或其他为基准
#这里以上证综指为基准
ex_return=pd.DataFrame()
ex_return['贵州茅台']=rets.iloc[:,1]-rets.iloc[:,0]
ex_return['工商银行']=rets.iloc[:,2]-rets.iloc[:,0]
ex_return['中国平安']=rets.iloc[:,3]-rets.iloc[:,0]a
#计算信息比率
information=np.sqrt(len(ex_return))*ex_return.mean()/ex_return.std()
#信息比率的输出结果
INR=pd.DataFrame(information,columns=['信息比率'])
INR
将上述指标合并成一张表,不难看出,在回测期间内(2009年01月01日至2019月01月18日期间),贵州茅台各项指标表现非常出色,其实贵州茅台近几年业绩表现非常优秀,每股收益在整个A股中是最高的。但是,其最大回撤却高达53.3%,意味着如果是在这期间的高点买入的,中间可能出现浮亏53.3%,要上涨114%才能回本,长期投资还真不是普通人心理能承受的。
indicators=pd.concat([TR,AR,MD,AB,SHR,INR],axis=1,
join='outer',sort='False')
#结果保留三位小数
indicators.round(3)
定义一个函数plot_max_drawdown(),对上述历史回撤的收益和风险指标进行可视化,函数代码相当于整合了上述计算过程,由于篇幅所限,此处省略。
#贵州茅台买入持有策略回测可视化
plot_max_drawdown(df,'贵州茅台')
#工商银行买入持有策略回测可视化
plot_max_drawdown(df,'工商银行')
#中国平安买入持有策略回测可视化
plot_max_drawdown(df,'中国平安')
来源:Python金融量化
--------------------------------------------------------------------------------------
拓展阅读:
《算法导论 第三版英文版》_高清中文版
《深度学习入门:基于Python的理论与实现》_高清中文版
《深入浅出数据分析》_高清中文版
《Python编程:从入门到实践》_高清中文版
《Python科学计算》_高清中文版
《深度学习入门:基于Python的理论与实现》_高清中文版
《深入浅出数据分析》_高清中文版
《Python编程:从入门到实践》_高清中文版
Python量策风指标相关推荐
- python分析股票MACD指标
股民朋友肯定熟悉股票中的MACD指标,比如5日均线.10日均线.15日均线等等.通过这些指标可以辅助进行交易的决策(比如经典的金叉.死叉理论),下面就以5日均线和20日均线为例,用python来画出指 ...
- 【手把手教你】使用Python构建股票财务指标打分系统
01 引言 最近受到知识星球圈友[禄子₇]的启发,利用Python基于财务指标打分构建价值投机股票的选股系统.首先感谢他给我发的电子书<价值投机>和他自己写的code(公众号回复" ...
- 分享股票level2接口的量价趋势指标源码
分享股票level2接口的量价趋势指标源码: 价趋势:MA(C,3)LINETHICK2 COLORGRAY; AMOL:=LOG(MA(AMO/C/100,M)); AMOH:=LOG(MA(AMO ...
- python:talib 市场情绪指标 BRAR
情绪指标,简称 ARBR 或 BRAR,由人气指标(AR)和意愿指标(BR)构成. AR 和 BR 都是对通过对历史股价走势的分析,反映市场当前情况下多空双方的力量强弱对比,推断市场交易情绪,从而对趋 ...
- python实现均值类指标差异分析-Mann-Whitney U-test(完整代码+实现效果)
实现功能: 对于均值类指标的差异分析,采用单因素方差分析,若指标分布服从正态分布,对于2个独立样本采用T检验或者Z检验,对于多个(大于2个)独立样本采用F检验,若分布不服从正态分布,对于2个独立样本采 ...
- 成交量指标: QRSI 量相对强弱指标
--指标原理 量相对强弱指标QRSI根据成交量来计测市场供需关系和买卖力道.与相对强弱指标RSI相比,计算方法和判断原则基本相同, 但它更多地考虑了量的因素,根据量比价先行的道理,能较好地超前判断走势 ...
- python 监控_了解指标并使用Python进行监控
python 监控 当我第一次遇到counter和gauge以及带有颜色和数字的图表时,我的React是避免使用该图表,这些图表的颜色和数字分别标记为"平均"和" 90以 ...
- 突破天量 通达信指标公式 副图 源码 贴图
股市有句名言"天量见天价",投资者往往认为当一只个股放出天量时,股价基本见顶,有反转的危险,因此投资者往往在某只股票放出天量时果断出局,但是后面发现牛股的天量往往在主升浪行情的初期 ...
- 风变编程python网址_风变编程Python:如何打造职场差异化竞争优势
吴军在<浪潮之巅>里指出,21世界最终会是人工智能的世纪,我们要么成为他们的奴隶,要么成为他们的神.每次开学我都会问学生们一个问题:如何才能比别人更优秀?更好的学历?更丰富的工作经验?事实 ...
最新文章
- JS实现录音,播放完整代码带示例图
- mysql导入sql脚本出现there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE
- Windows server 2003 DNS 全攻略(一)
- 一款好用 mongodb 可视化工具
- 第 21 章 radiusd - Authentication, Authorization and Accounting server
- 关于Python Profilers性能分析器
- Leetcode--279. 完全平方数
- C# 之 提高WebService性能大数据量网络传输处理
- 计算机视觉深度学习实战三:频域分析及其变换
- JS模块化规范对比以及在Node.js的实现
- pythonfor循环语句例子_Python for循环学习总结
- MySQL Innodb Engine -- 文件格式(innodb_file_format)
- 添加固态硬盘后系统迁移
- 洛谷:P2832 行路难(堆优化Dijkstra(错解)bfs(正解) + 记录路径)
- 微信小程序支付(基于Java实现微信JSAPI支付):支付,提现,退款
- CDN加速-内容分发网络
- 中国县城生活实录:上楼因特网,下楼码长城
- 既生 useState 何生 useReducer (主讲useReducer)
- 前端日历,vue日历,一周的日历
- python中横向制表符_python中制表符是什么意思
热门文章
- [ 数据通信面试篇 ] 数通面试题大集合(详解),看完直怼面试官(一)
- css怎样让字体变细,css怎么把字体变细?
- matlab bar 填充花纹,转:使用matlab绘画柱状图,且使用不同的图案填充
- Android网络通信(HttpURLConnection)和 数据传输格式(JSON)
- 正则表达式中Pattern类、Matcher类和matches()方法简析
- 如何下载win10原装镜像
- 解决Python安装pyqt5-tool出现的系列问题:ERROR: Could not find a version that satisfies the requirement xxx
- 数学不好 学软件测试能学会吗,英语差、数学烂,我还能学好编程吗?
- dnf锁定计算机,DNF老电脑福音 教你如何提升游戏流畅度
- linux18安装anyconnect4.9遇到I/O问题