python量化代码_【手把手教你】动量指标的Python量化回测

原标题:【手把手教你】动量指标的Python量化回测

我认为投资专业的学生只需要两门教授得当的课堂:如何评估一家公司,以及如何考虑市场价格。——巴菲特

01 引言

本文延续“手把手教你使用Python的TA-Lib”系列,以资金流量指标(MFI)为例,使用Python编写简单的回测框架,着重介绍动量指标(Momentum Indicators)及其运用。前面推文【手把手教你】股市技术分析利器之TA-Lib(一)主要探讨了重叠指标的相关原理与Python实现,【手把手教你】股市技术分析利器之TA-Lib(二) 着重介绍TA-Lib中强大的数学运算、数学变换、统计函数、价格变换、周期指标和波动率指标函数及其应用实例。【手把手教你】量价关系分析与Python实现,则主要介绍了交易量指标(Volume Indicators)及其运用。TA-Lib的安装与使用见之前推文。

02 动量指标概述

动量指标,英文全称为 Momentum Indicators,是一种利用动力学原理,研究股价在波动过程中趋势与反转现象的技术指标。动量指标建立在价格与供求关系的基础上,认为股价的涨跌幅随着时间的推移逐渐变小,股价变化的速度和能量慢慢减缓后,行情可能发生反转。常见的动量指标包括ADX、CMO、MACD、RSI、KDJ、动量指数(MOM)和威廉指标等。TA-Lib 库里的动量指标类函数如下表所示。

03 MFI 指标分析框架

下面以大家比较少见的资金流量指标(Money Flow Index, 简称MFI)为例,详细介绍动量类指标的分析框架和应用。MFI指标(Money Flow Index)是1989年3月由JWellesWilder's提出来的,结合考虑了价和量,相当于成交量的RSI指标。一般而言,价涨量增及价跌量缩是一种惯性作用.股价进行波段涨升时,成交量必须伴随上升。

计算方法

典型价格(TP)=当日最高、最低与收盘价均值

资金流量(MF)=TP×N日内成交量

若当日MF>昨日MF,则视为正资金流量(PMF)

若当日MF

MFI=100-[100/(1+PMF/NMF)]

参数N一般设为14日。

应用法则

超买超卖信号:当MFI>80时为超买,在其回头向下跌破80时,为短线卖出时机。

当MFI<20时为超卖,当其回头向上突破20时,为短线买进时机。

当MFI>80,而产生背离现象时,视为卖出信号。

当MFI<20,而产生背离现象时,视为买进信号。

04

MFI 指标 Python 应用实例

下面结合MFI 指标的超买超卖法则,以上证指数为标的,使用 Python 对其进行历史回测,主要利用了pandas、numpy、talib和matplotlib进行数据处理和可视化。

#先引入后面可能用到的包(package)

import pandas as pd

import numpy as np

import matplotlib.pyplot as plt

#注意下面的%命令只能在jupyter notebook上运行,否则需要删除或注释掉

%matplotlib inline

#正常显示画图时出现的中文和负号

from pylab import mpl

mpl.rcParams['font.sans-serif']=['SimHei']

mpl.rcParams['axes.unicode_minus']=False

#引入TA-Lib库

import talib as ta

import tushare as ts

df=ts.get_k_data('sh',start='2000-01-01')

df.index=pd.to_datetime(df.date)

df=df.sort_index()

df['ret']=df.close/df.close.shift(1)-1

df.head()

high,low,close,volume=df.high.values,df.low.values,df.close.values,df.volume.values

df['mfi']=ta.MFI(high, low, close, volume, timeperiod=14)

plt.figure(figsize=(16,14))

plt.subplot(211)

df['close'].plot(color='r')

plt.xlabel('')

plt.title('上证综指走势',fontsize=15)

plt.subplot(212)

df['mfi'].plot()

plt.title('MFI指标',fontsize=15)

plt.xlabel('')

plt.show()

#当前日的MFI<20,而当日的MFI>20时,买入信号设置为1

for i in range(15,len(df)):

if df['mfi'][i]>20 and df['mfi'][i-1]<20:

df.loc[df.index[i],'收盘信号']=1

if df['mfi'][i]<80 and df['mfi'][i-1]>80:

df.loc[df.index[i],'收盘信号']=0

#计算每天的仓位,当天持有上证指数时,仓位为1,当天不持有上证指数时,仓位为0

pd.options.mode.chained_assignment = None

df['当天仓位']=df['收盘信号'].shift(1)

df['当天仓位'].fillna(method='ffill',inplace=True)

from datetime import datetime,timedelta

d=df[df['当天仓位']==1].index[0]-timedelta(days=1)

df_new=df.loc[d:]

df_new['ret'][0]=0

df_new['当天仓位'][0]=0

#当仓位为1时,买入上证指数,当仓位为0时,空仓,计算资金指数

df_new['资金指数']=(df_new.ret*df['当天仓位']+1.0).cumprod()

df_new['指数净值']=(df_new.ret+1.0).cumprod()

df.close.plot(figsize=(16,7))

for i in range(len(df)):

if df['收盘信号'][i]==1:

plt.annotate('买',xy=(df.index[i],df.close[i]),arrowprops=dict(facecolor='r',shrink=0.05))

if df['收盘信号'][i]==0:

plt.annotate('卖',xy=(df.index[i],df.close[i]),arrowprops=dict(facecolor='g',shrink=0.1))

plt.title('上证指数2000-2019年MFI买卖信号',size=15)

plt.xlabel('')

ax=plt.gca()

ax.spines['right'].set_color('none')

ax.spines['top'].set_color('none')

plt.show()

#查看最近两年情况

df1=df.loc['2016-01-01':,]

df1.close.plot(figsize=(16,7))

for i in range(len(df1)):

if df1['收盘信号'][i]==1:

plt.annotate('买',xy=(df1.index[i],df1.close[i]),arrowprops=dict(facecolor='r',shrink=0.05))

if df1['收盘信号'][i]==0:

plt.annotate('卖',xy=(df1.index[i],df1.close[i]),arrowprops=dict(facecolor='g',shrink=0.1))

plt.title('上证指数2016-2019年MFI买卖信号',fontsize=15)

plt.xlabel('')

ax=plt.gca()

ax.spines['right'].set_color('none')

ax.spines['top'].set_color('none')

plt.show()

df1['策略净值']=(df1.ret*df1['当天仓位']+1.0).cumprod()

df1['指数净值']=(df1.ret+1.0).cumprod()

df1['策略收益率']=df1['策略净值']/df1['策略净值'].shift(1)-1

df1['指数收益率']=df1.ret

下面将数据获取、策略计算和历史回测打包成一个strategy函数,对不同参数组合和时间区间进行历史回测,通过下图不难发现,经验总结得出的20/80超卖超买信号效果并不理想,但将超买值改为90后,反而获得了更好的效果。总体而言,MFI指标相对于不择时而言,最大回撤要小很多,即持仓风险小,但是也意味着可能赚不到疯狂上涨的钱。此外,2016年或2017年以来MFI回测效果比较好,特别是将超买值改为90后,而2000、2005或2009以来的回测效果可能还不如大盘,反映了时间周期越长,MFI指标的效果越差,事实上,MFI指标是一个提供中短期买卖信号的技术指标。

strategy('sh','2009-05-12',20,80)

strategy('sh','2009-04-12',20,90)

strategy('sh','2009-04-12',20,95)

strategy('sh','2009-04-12',30,95)

strategy('sh','2009-04-12',15,95)

strategy('sh','2016-01-01',20,90)

strategy('sh','2000-01-01',20,80)

strategy('sh','2000-01-01',20,92)

strategy('sh','2017-04-12',20,80)

strategy('sh','2017-04-12',20,92)

strategy('cyb','2017-04-01',20,80)

05 结语

本文以MFI指标为例,简要介绍了动量指标的原理及其Python量化运用实例,由于篇幅有限,只给出了部分核心代码,完整代码可通过加入知识星球获取。

在指标运用中,不少交易者会产生困惑,有时指标严重超买,股价却继续上涨,或指标严重超卖,股价仍未止跌企稳。其实这是混淆了技术指标与股价的关系,指标并不能决定股价涨跌,股价才决定指标的大小,股价是因,指标是果,由因可推出果,但由果来导出因可能不准确。既然那样,技术指标还有什么用呢?

其实技术分析就如温度计,能够测量当前温度,却不能预测也不能决定未来温度。换句话说,技术指标虽不能预测未来走势,但可以衡量当前市场交投情况,用于确认趋势。也就是说技术指标可以作为辅助参考作用,当股价趋势继续上涨或下跌时,指标也将继续超买或超卖,而当股价一旦发生转势,指标随后也会发生转势买卖信号,为仓位管理和择时提供技术上的参考。

关于Python金融量化

专注于分享Python在金融量化领域的应用。加入知识星球,可以免费获取30多g的量化投资视频资料、公众号文章Python完整源码、量化投资前沿分析框架,与博主直接交流、结识圈内朋友等。返回搜狐,查看更多

责任编辑:

你可能感兴趣的:(python量化代码)