新闻中心

【手把手教你】获取股票数据并进行量化回测——基于ADX和MACD趋势策略(获取股票数据接口api)

2023-10-21
浏览次数:
返回列表

01引言

不少喜欢量化的读者向我反馈,虽然已经掌握了Python的编程基础,但仍不知道如何切入到股票量化分析上,一是对如何获取股票数据还不太熟悉;二是拿到股票数据后不知道怎么做量化回测。实际上公众号分享了很多这方面的文章,可以作为参考模板的包括:《【手把手教你】Python获取交易数据》、《【手把手教你】搭建自己的量化分析数据库》、《【手把手教你】Python面向对象编程入门及股票数据管理应用实例》;《手把手教你用Python搭建自己的量化回测框架【均值回归策略】》、《【手把手教你】用Python量化海龟交易法则》、《A股存在月份效应吗?构建月度择时策略【附Python源码】》、《北向资金能预示大盘涨跌?【附Python源码】》,专业量化回测框架可以参考backtrader的系列文章(如【手把手教你】入门量化回测最强神器backtrader(一))。目前公众号文章主要是以tusahre来获取数据,实际上Python可用的获取数据api还是很多的,如开源的有akshare、baostock、pandas_datareader(国内外数据丰富,但外网访问常连接不上)、alpha_vantage(国外)、quandl(国外)、yfinance(原雅虎财经,外网访问常连接不上);非开源的有WindPy(Wind付费插件)、恒有数hs_udata(恒生云)、聚宽JQData(可试用)等等。关于这些库或数据api的详细介绍大家可以直接百度进入官网了解,此处不做进一步展开,本文主要介绍如何使用开源数据包获取数据并进行量化回测,实现最简单的代码输出专业的分析图表。

02数据获取

下面分别对tusahre、tushare pro、akshare和baostock四个当前较流行的开源数据包构建统一参数的数据获取函数,比较程序编写的复杂程度和获取数据所需时间。

先导入pandas、matplotlib等常用包。

import pandas as pd import numpy as np import matplotlib.pyplot as plt #正常显示画图时出现的中文和负号 from pylab import mpl mpl.rcParams[font.sans-serif]=[SimHei] mpl.rcParams[axes.unicode_minus]=False #不显示警告信息 import warnings warnings.filterwarnings(ignore)

构建统一参数的数据获取函数,复权、起始和结束时间设置为默认参数,注意tushare pro需要注册获取token(https://tushare.pro/register?reg=218422)才能使用,某些数据权限受积分限制,其旧版非常接口简洁好用但不再维护。akshare相当于连接全网开放数据源api的数据网站(如新浪财经、同花顺、东方财富等),某些函数由于包更新不可用。basostock无需注册且免费,但函数调用稍显麻烦。 logout success!

baostock耗时:1.6439秒

比较四个api获取的“300002”后复权价格数据,结果显示四个接口得到的数据存在一些差别,其中tushare和baostock数据接近,二者与akshare差别较大,可能是计算方式存在差异。由于采用后复权,随着时间拉长,分红次数增加,差异越来越大。

data.tail() (data[tushare pro]-data[akshare]).plot(figsize=(12,5),c=r);

03策略回测

下面以tushare旧版接口为例,获取数据并基于技术指标进行量化回测。图中显示,“300002”的股价在2010.1.4-2021.11.5期间波动非常大,累计收益率-14.5%,年化收益率-1.4%,年化波动率53.8%,最大回撤高达89%,日VaR为-6.7%。换句话说,如果从2010年1月4日开始持有该股票,至2021年11月5日将亏损14.5%,但如果是在其最高点买入最大亏损为89%;当然,如果你是在2012年12月买入,持有到2015年6月21日,股价差不多增长了10倍。现实的情况往往是,大量股民像韭菜一样在股价不断波动的过程中被收割。

df=get_from_tushare(300002) df.close.plot(figsize=(12,6)); plt.title(神州泰岳股价走势\n2010-2021,size=15)import pyfolio as pf pf.create_simple_tear_sheet((df.close.pct_change()).fillna(0).tz_localize(UTC))

下面以趋势指标ADX结合均线和MACD指标构建交易策略进行量化回测。ADX是一种常用的趋势衡量指标,指标值越大代表趋势越强,但指标本身无法告诉你趋势的发展方向,与均线和MACD指标配合运用,可以确认市场是否存在趋势,并衡量趋势的强度。下面以13、55、89日均线(斐波那契数列),MACD(12,26,9)和ADX(阈值设置为前值和25)指标为例,得到下列回测结果。

#技术分析包import talib as ta def adx_strategy(df,ma1=13,ma2=55,ma3=89,adx=25): #计算MACD和ADX指标 df[EMA1] = ta.EMA(df.close,ma1) df[EMA2] = ta.EMA(df.close,ma2) df[EMA3] = ta.EMA(df.close,ma3) df[MACD],df[MACDSignal],df[MACDHist] = ta.MACD(df.close,12,26,9) df[ADX] = ta.ADX(df.high,df.low,df.close,14) #设计买卖信号:21日均线大于42日均线且42日均线大于63日均线;ADX大于前值小于25;MACD大于前值 df[Buy_Sig] =(df[EMA1]>df[EMA2])&(df[EMA2]>df[EMA3])&(df[ADX]<=adx)\ &(df[ADX]>df[ADX].shift(1))&(df[MACDHist]>df[MACDHist].shift(1)) df.loc[df.Buy_Sig,Buy_Trade] = 1 df.loc[df.Buy_Trade.shift(1)==1,Buy_Trade] = " " #避免最后三天内出现交易 df.Buy_Trade.iloc[-3:] = " " df.loc[df.Buy_Trade==1,Buy_Price] = df.close df.Buy_Price = df.Buy_Price.ffill() df[Buy_Daily_Return]= (df.close - df.Buy_Price)/df.Buy_Price df.loc[df.Buy_Trade.shift(3)==1,Sell_Trade] = -1 df.loc[df.Sell_Trade==-1,Buy_Total_Return] = df.Buy_Daily_Return df.loc[(df.Sell_Trade==-1)&(df.Buy_Daily_Return==0),Buy_Total_Return] = \ (df.Buy_Price - df.Buy_Price.shift(1))/df.Buy_Price.shift(1) df.loc[(df.Sell_Trade==-1)&(df.Buy_Trade.shift(1)==1),Buy_Total_Return] = \ (df.close-df.Buy_Price.shift(2))/df.Buy_Price.shift(2) #返回策略的日收益率 return df.Buy_Total_Return.fillna(0)

回测结果显示,使用该交易策略可获得11.3%的年化收益率,累计收益率221.5%,最大回撤-24.2%,夏普比率0.63。使用策略后各项指标得到有效改善。

import pyfolio as pf pf.create_simple_tear_sheet(adx_strategy(df).tz_localize(UTC))

04结语

对于tushare、tushare pro、akshare、baostock开源数据api,本文构建了统一参数的数据获取函数,获取个股后复权数据并以技术指标ADX结合均线和MACD构建交易策略进行量化回测。本文旨在为大家利用开源数据进行量化分析提供一个思路和模板,各位读者可以在此基础上结合自身对市场的理解进行深入拓展。值得注意的是,文中提及的交易策略仅供学习参考,切勿直接拿来做真实交易。实际上,文中对‘300002’单个标的进行回测得到结果不代表该交易策略就有效,可能正好适合该股票和该段时间走势,任何基于技术指标的交易策略均具有一定的局限性,具体问题具体分析。

搜索