您当前的位置:首页 > 财经百科 > 股票 > 基础

获取股票数据并进行量化回测——基于ADX和MACD趋势策略

时间:2021-11-10 09:39:20  来源:  作者:Python金融量化

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无需注册且免费,但函数调用稍显麻烦。

 

#使用tushare旧版获取数据
import tushare as ts
def get_from_tushare(code,adj='hfq',start='2010-01-01',end='2021-11-05'):
    df=ts.get_k_data(code,autype=adj,start=start,end=end)
    df.index=pd.to_datetime(df.date)
    #原数据已默认按日期进行了排序
    return df

#使用tushare pro获取数据
import tushare as ts
token='输入你自己的token'
pro=ts.pro_api(token)
ts.set_token(token)
def get_from_tushare_pro(code,adj='hfq',start='2010-01-01',end='2021-11-05'):
    #code:输入数字字符串,如‘300002’
    #start和end输入'年-月-日'需转为'年月日'格式
    if code.startswith('6'):
        code=code+'.SH'
    else:
        code=code+'.SZ'
    start=''.join(start.split('-'))
    end=''.join(end.split('-'))
    df=ts.pro_bar(ts_code=code,adj=adj,start_date=start,end_date=end)
    #原数据是倒序的,所以将时间设置为索引,根据索引重新排序
    df.index=pd.to_datetime(df.trade_date)
    df=df.sort_index()
    return df

#使用akshare获取数据,其数据源来自新浪,与tushare旧版本相似
import akshare as ak
def get_from_akshare(code,adj='hfq',start='2010-01-01',end='2021-11-05'):
    if code.startswith('6'):
        code='sh'+code
    else:
        code='sz'+code
    start=''.join(start.split('-'))
    end=''.join(end.split('-'))
    df = ak.stock_zh_a_daily(symbol=code, start_date=start, end_date=end, adjust=adj)
    return df

#使用baostock获取数据
import baostock as bs
def get_from_baostock(code,adj='hfq',start='2010-01-01',end='2021-11-05'):
    if code.startswith('6'):
        code='sh.'+code
    else:
        code='sz.'+code
    #转换复权为数字
    if adj=='hfq':
        adj='1'
    elif adj=='qfq':
        adj='2'
    else:
        adj='3'
    #必须登陆和登出系统
    bs.login() #登陆系统
    rs = bs.query_history_k_data_plus(code,
       fields="date,code,open,high,low,close,volume",
       start_date=start, end_date=end,
       frequency="d", adjustflag=adj)
    #adjustflag:复权类型,默认不复权:3;1:后复权;2:前复权
    data_list = []
    while (rs.error_code == '0') & rs.next():
        data_list.Append(rs.get_row_data())
    #将数据转为dataframe格式
    df = pd.DataFrame(data_list, columns=rs.fields)
    df.index=pd.to_datetime(df.date)
    bs.logout() #登出系统 
    return df

 

下面分别使用这四个api接口获取数据并比较耗用时间,结果显示,tushare pro和akshare耗用时间均较短,获取‘300002’于2010.1-2021.11期间数据只需0.6-0.8秒,tushare旧版接口代码最简洁,但需1.05秒,而baostock则需1.6,当然结果会受网络状态影响。

func={'tushare':get_from_tushare,
           'tushare pro':get_from_tushare_pro,
           'akshare':get_from_akshare,
           'baostock':get_from_baostock}
#以个股神州泰岳为例
code='300002'
from time import time
data=pd.DataFrame()
for name,f in func.items():
    t0=time()
    data[name]=f(code).close
    t1=time()
    print(f'{name}耗时:{t1-t0:.04f}秒')

输出结果:
tushare耗时:1.0488秒
tushare pro耗时:0.6780秒
akshare耗时:0.7795秒
login success!
logout success!
baostock耗时:1.6439秒

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

 

data.tail()
获取股票数据并进行量化回测——基于ADX和MACD趋势策略

 

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

 

获取股票数据并进行量化回测——基于ADX和MACD趋势策略

 

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)

 

获取股票数据并进行量化回测——基于ADX和MACD趋势策略

 

import pyfolio as pf
pf.create_simple_tear_sheet((df.close.pct_change()).fillna(0).tz_localize('UTC'))

 

获取股票数据并进行量化回测——基于ADX和MACD趋势策略

 


获取股票数据并进行量化回测——基于ADX和MACD趋势策略

 

下面以趋势指标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'))
获取股票数据并进行量化回测——基于ADX和MACD趋势策略

 


获取股票数据并进行量化回测——基于ADX和MACD趋势策略

 

04

结语

 

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



Tags:量化   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
01引言 不少喜欢量化的读者向我反馈,虽然已经掌握了Python的编程基础,但仍不知道如何切入到股票量化分析上,一是对如何获取股票数据还不太熟悉;二是拿到股票数据后不知道怎么做...【详细内容】
2021-11-10  Tags: 量化  点击:(44)  评论:(0)  加入收藏
“好货不便宜,便宜没好货。”这是市场上主流的观点,比如高高在上的茅台、宁德时代、比亚迪等大白马越不敢买越涨,某些垃圾股越便宜越能跌。这逼得很多投资者不得不追高,不得不去...【详细内容】
2021-11-03  Tags: 量化  点击:(61)  评论:(0)  加入收藏
一、量化交易好不好?2015年股灾被称祸首之一量化交易其实在A股市场,就一直反复出现这个词,但真正震惊到市场的是2015年A股股灾被介的俄罗斯人的伊世顿。伊世顿在A股期货市场操...【详细内容】
2021-10-18  Tags: 量化  点击:(74)  评论:(0)  加入收藏
最近一段时间,很多人觉得股票越来越难做了,板块加速切换,市场走势极端,一些中线趋势良好的板块个股完全无视基本面突然连续大幅杀跌。有人说,这是因为量化交易成为了我们的对手盘...【详细内容】
2021-10-12  Tags: 量化  点击:(71)  评论:(0)  加入收藏
A股市场连续破万亿元,是否和量化交易的兴起有关?综合多家机构、专家观点来看,机构大幅调仓、散户频繁交易、量化交易活跃共同驱动A股扩容。但无论量化交易发展多快,终离不开监管...【详细内容】
2021-10-12  Tags: 量化  点击:(101)  评论:(0)  加入收藏
在这个三步一貂蝉,五步一昭君,美女遍地的时代,没点变美的小技巧傍身,还怎么愉快地行走江湖呢?传说亚洲有四大邪术,化妆为其一,相信姐妹们都略有耳闻吧?今天就来教你用简单易学的三...【详细内容】
2021-10-11  Tags: 量化  点击:(57)  评论:(0)  加入收藏
最近,因为股市成交量暴增,量化交易也走到了台前,但是估计大部分非专业投资者可能并不是特别了解啥是量化交易,笔者来做一个简单的介绍。量化,毫无疑问,数量化,既然数量化了,手动肯定...【详细内容】
2021-09-09  Tags: 量化  点击:(319)  评论:(0)  加入收藏
第一,没有爆仓风险,吃的香,睡的好。第二,科学合理控制仓位,不会站在高点。第三,克服人性交易弱点,贪婪和恐惧是交易最大的敌人,价高不舍得出,价低不敢进货先说我个人的经验吧,我是从20...【详细内容】
2021-08-18  Tags: 量化  点击:(53)  评论:(0)  加入收藏
序言 05 October 2020每次购物,都要花大量的时间去看看货品是否合适,尺寸、接口、规范等等都要一一审核,认真烦。每次遇到非官方的扫脸验证,总是嘀咕扫描数据放哪里了?是不是保管...【详细内容】
2020-10-05  Tags: 量化  点击:(174)  评论:(0)  加入收藏
什么是量化交易A股三大指数今日集体收涨,其中深成指与创业板指涨幅接近1%,沪指与创业板指日K线都是三连阳。市场成交量略有萎缩,两市合计成交仅有7000多亿元。行业板块涨跌互现...【详细内容】
2020-09-15  Tags: 量化  点击:(122)  评论:(0)  加入收藏
▌简易百科推荐
当有人在纪念钱钟书去世23周年之际,那句“越是聪明人,越要懂得下笨功夫”的名言警句又被拎出来了。 的确,再次重温,心灵上仍有冲击。 胡适之也有类似的一句话,“这个世界聪明人...【详细内容】
2021-12-27  闲闲财经    Tags:股市   点击:(2)  评论:(0)  加入收藏
氢能源是国家未来大力发展的方向之一,是“十四五”规划的重点。氢能是公认的清洁能源,作为低碳和零碳能源正在脱颖而出。21世纪,我国和美国、日本、加拿大、欧盟等都制定了氢能...【详细内容】
2021-12-27  财经浩然兄    Tags:氢能源   点击:(3)  评论:(0)  加入收藏
什么是氢能源:氢在地球上主要以化合态的形式出现,是宇宙中分布最广泛的物质,它构成了宇宙质量的75%,是二次能源。氢能在21世纪有可能在世界能源舞台上成为一种举足轻重的能源,氢...【详细内容】
2021-12-27  纵股论金    Tags:氢能源   点击:(2)  评论:(0)  加入收藏
周末没事干刷某球,看到一哥们,今年买股票从50万炒到了12.9万。 这篇文章挺火的,4000多个评论,1500个点赞。 我大概看了一下,这哥们一开始打算开通科创板,因为自己资金不够向亲戚借...【详细内容】
2021-12-27  价值成长  今日头条  Tags:投资   点击:(3)  评论:(0)  加入收藏
一、 指数分析指数21年整体是急跌慢涨的走势,随着22年全面注册制后,股票会越来越多,指数会继续延续急跌慢涨震荡上行的走势,以及会继续延续板块的高低切换风格,结构化行情将是常...【详细内容】
2021-12-27  股市成长记丶    Tags:股市   点击:(3)  评论:(0)  加入收藏
科创板以及创业板注册制已经有了成功的模板,所以目前我国具备了全面推行注册制的条件。在实行全面注册制之后,对资本市场来说是一个利好消息,对于众多散户来说,同样是一个利好消...【详细内容】
2021-12-21  毒舌财经    Tags:注册制   点击:(8)  评论:(0)  加入收藏
炒股就是八个字:只干龙头,不干杂毛!下面就给大家列举各领域的龙头公司,看了这篇文章,以后千万不要再什么股票都买了!喝最烈的酒,骑最快的马,拿最快的剑,登最高的山! 其实一直以来我...【详细内容】
2021-12-08  股里论道  今日头条  Tags:龙头公司   点击:(23)  评论:(0)  加入收藏
网络安全板块是什么 1、网络安全网络安全是计算机行业中网络、计算、储存外的第四个基础设施。是计算机行业中增速最快的超千亿的板块。2、近几个月来大涨四个原因滴滴事件...【详细内容】
2021-12-08  朱赫    Tags:网络安全   点击:(18)  评论:(0)  加入收藏
作为交易者,我们都应该知晓市场可能处于趋势阶段,也可能处于震荡阶段。通常,大多数市场都处于区间震荡走势中,只有不到三分之一的时候表现出趋势行为,而趋势则是我们最容易获利的...【详细内容】
2021-12-07  汇商    Tags:均值回归交易策略   点击:(19)  评论:(0)  加入收藏
一,心法想要在市场长期舒服的生存下去,先要明白一点,股市不能用常规数理化一样的科学来理解,更不能通过计算机对其模式化操作,那样也行不通,股市实际上更像乐理,美学等一样如一门艺...【详细内容】
2021-12-07  禅股论道    Tags:A股   点击:(17)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条