量化投资:第8节 A股市场的回测
作者: 阿布
阿布量化版权所有 未经允许 禁止转载
之前的小节回测示例都是使用美股,本节示例A股市场的回测。
买入因子,卖出因子等依然使用相同的设置,如下所示:
# 设置初始资金数
read_cash = 1000000
# 买入因子依然延用向上突破因子
buy_factors = [{'xd': 60, 'class': AbuFactorBuyBreak},
{'xd': 42, 'class': AbuFactorBuyBreak}]
# 卖出因子继续使用上一节使用的因子
sell_factors = [
{'stop_loss_n': 1.0, 'stop_win_n': 3.0,
'class': AbuFactorAtrNStop},
{'class': AbuFactorPreAtrNStop, 'pre_atr_n': 1.5},
{'class': AbuFactorCloseAtrNStop, 'close_atr_n': 1.5}
]
1. A股市场的回测示例
择时股票池使用沙盒缓存数据中的如下股票:
A股市场:
- 科大讯飞(002230)
- 乐视网(300104)
- 东方财富(300059)
- 中国中车(601766)
- 同仁堂(600085),
- 招商银行(600036)
- 山西汾酒(600809)
- 万科A(000002)
- 比亚迪(002594)
- 万达电影(002739)
- 上证指数(sh000001)
代码如下所示:
# 择时股票池
choice_symbols = ['002230', '300104', '300059', '601766', '600085', '600036', '600809', '000002', '002594', '002739']
# 使用run_loop_back运行策略
abu_result_tuple, kl_pd_manger = abu.run_loop_back(read_cash,
buy_factors,
sell_factors,
n_folds=6,
choice_symbols=choice_symbols)
AbuMetricsBase.show_general(*abu_result_tuple, only_show_returns=True)
买入后卖出的交易数量:169
买入后尚未卖出的交易数量:1
胜率:55.6213%
平均获利期望:17.4736%
平均亏损期望:-6.6848%
盈亏比:3.5702
策略收益: 164.6985%
基准收益: 75.7668%
策略年化收益: 41.1746%
基准年化收益: 18.9417%
策略买入成交比例:88.2353%
策略资金利用率比例:34.8566%
策略共执行1008个交易日
上面的回测结果虽然可以正常运行,但是很多交易细节还是使用的默认设置中的美股交易模式,因为默认的设置EMarketTargetType.E_MARKET_TARGET_US是美股,它会影响到一年多少个交易日等等交易细节,基准标尺等问题,如注意观察上面使用使用show_general显示的最终收益对比图,可以发现策略收益对比的是纳斯达克指数,并不是A股大盘。
正确的做法是首先将abupy量化环境设置为A股,代码如下所示:
abupy.env.g_market_target = EMarketTargetType.E_MARKET_TARGET_CN
abu_result_tuple, kl_pd_manger = abu.run_loop_back(read_cash,
buy_factors,
sell_factors,
n_folds=6,
choice_symbols=choice_symbols)
AbuMetricsBase.show_general(*abu_result_tuple, only_show_returns=True)
买入后卖出的交易数量:252
买入后尚未卖出的交易数量:2
胜率:43.6508%
平均获利期望:17.5752%
平均亏损期望:-6.9084%
盈亏比:2.1424
策略收益: 114.8238%
基准收益: 20.6036%
策略年化收益: 19.8870%
基准年化收益: 3.5685%
策略买入成交比例:83.0709%
策略资金利用率比例:38.6073%
策略共执行1455个交易日
2. 涨跌停的特殊处理
下面主要讲解一下A股市场中比较特殊的地方:涨停,跌停,首先看一下下面这笔交易:
orders_pd = abu_result_tuple.orders_pd
view_orders = orders_pd[(orders_pd['symbol'] == '601766') & (orders_pd['buy_date'] == 20150417)]
view_orders
从交易单来看似乎一切ok,虽然最终交易亏损了,下面使用plot_candle_from_order可视化view_orders,plot_candle_from_order标记出了买入和卖出点
trade_df = ABuMarketDrawing.plot_candle_from_order(view_orders)
ABuMarketDrawing.plot_candle_from_order返回的trade_df是这笔交易的持股周期内的金融时间序列,如下所示,看第一条数据
2015-04-17交易日即为买入交易日,可以发现close,high,low的价格都是一样的,这代表了在集合竞价阶段股票已经涨停,但在我们回测中默认使用的
滑点买入类依然认为可以买入。
备注:滑点类相关内容请阅读:滑点策略与交易手续费
print('买入价格为:{}'.format(view_orders.ix[0].buy_price))
trade_df.head()
买入价格为:35.61
和买入类似,注意下面这笔交易:
view_orders = orders_pd[(orders_pd['symbol'] == '000002') & (orders_pd['sell_date'] == 20160704)]
trade_df = ABuMarketDrawing.plot_candle_from_order(view_orders.ix[0])
print('卖出价格为:{}'.format(view_orders.ix[0].sell_price))
trade_df.tail()
卖出价格为:21.27
上面ABuMarketDrawing.plot_candle_from_order返回的trade_df是这笔交易的持股周期内的金融时间序列,看第最后一条数据
2016-07-04交易日即为卖出交易日,可以发现close,high,low的价格都是一样的,这代表了在集合竞价阶段股票已经跌停,但在我们回测中默认使用的
滑点卖出类依然认为可以卖出。
类似的情况还有下面这种虽然并不是在集合竞价阶段股票涨停,但是涨停下依然使用当天最高最低均价买入,买入价格为:1.175显然也不合适,同理在非集合竞价跌停的情况下以当天的平均价格卖出也不合适。
备注:默认滑点类使用均价买入卖出,详情阅读AbuSlippageSellBase,AbuSlippageBuyBase
view_orders = orders_pd[(orders_pd['symbol'] == '300059') & (orders_pd['buy_date'] == 20120222)]
trade_df = ABuMarketDrawing.plot_candle_from_order(view_orders.ix[0])
print('买入价格为:{}'.format(view_orders.ix[0].buy_price))
trade_df.head(1)
买入价格为:1.175
为解决上述问题abupy中有针对A股涨停和跌停的特殊装饰器封装在滑点模块中:
具体实现原理不在这里展开,效果为:
- 针对非集合竞价阶段的涨停,滑点买入价格以高概率在接近涨停的价格买入
- 针对非集合竞价阶段的跌停,滑点卖出价格以高概率在接近跌停的价格卖出
- 集合竞价阶段的涨停根据设置中的买入成功概率进行买入决策
- 集合竞价阶段的跌停根据设置中的卖出成功概率进行卖出决策
具体实现请阅读源代码AbuSlippageSellBase,AbuSlippageBuyBase。
下面的代码即将上述4个针对A股涨停和跌停的特殊设置打开:
from abupy import slippage
# 开启针对非集合竞价阶段的涨停,滑点买入价格以高概率在接近涨停的价格买入
slippage.sbb.g_enable_limit_up = True
# 将集合竞价阶段的涨停买入成功概率设置为0,如果设置为0.2即20%概率成功买入
slippage.sbb.g_pre_limit_up_rate = 0
# 开启针对非集合竞价阶段的跌停,滑点卖出价格以高概率在接近跌停的价格卖出
slippage.ssb.g_enable_limit_down = True
# 将集合竞价阶段的跌停卖出成功概率设置为0, 如果设置为0.2即20%概率成功卖出
slippage.ssb.g_pre_limit_down_rate = 0
其它的回测因子等设置都不变,重新使用abu.run_loop_back进行回测,代码如下:
abu_result_slippage, kl_pd_manger = abu.run_loop_back(read_cash,
buy_factors,
sell_factors,
n_folds=6,
choice_symbols=choice_symbols)
AbuMetricsBase.show_general(*abu_result_slippage, only_show_returns=True)
买入后卖出的交易数量:249
买入后尚未卖出的交易数量:2
胜率:42.9719%
平均获利期望:16.4189%
平均亏损期望:-6.8735%
盈亏比:1.8920
策略收益: 89.4554%
基准收益: 20.6036%
策略年化收益: 15.4933%
基准年化收益: 3.5685%
策略买入成交比例:82.4701%
策略资金利用率比例:39.7315%
策略共执行1455个交易日
上面的度量显示买入后卖出的交易数量:249,之前没开启涨跌停时是252,即可知道有三笔交易由于开启了涨跌停没有进行买入,但是怎么能知道那些交易发生了变化呢?
备注:读者可尝试使用 ABU量化系统使用文档-第九节 港股市场的回测 中讲解的AbuSDBreak对上面A股交易进行回测,度量结果。
3. 对多组交易结果进行分析
AbuOrderPdProxy是abupy中内置的针对交易单对象进行并集,交集,差集等交易单分析使用的工具,通过EOrderSameRule使用不同的判断为是否相同使用的交易单规则,更多实现详情请阅读AbuOrderPdProxy源代码,下面示例使用:
from abupy import AbuOrderPdProxy, EOrderSameRule
orders_pd_slippage = abu_result_slippage.orders_pd
# 通过orders_pd构造AbuOrderPdProxy
proxy = AbuOrderPdProxy(orders_pd)
with proxy.proxy_work(abu_result_slippage.orders_pd) as (order, order_slippage):
print('order == order_slippage: {}'.format(order == order_slippage))
print('order > order_slippage: {}'.format(order > order_slippage))
diff_a = order - order_slippage
diff_b = order_slippage - order
order == order_slippage: False
order > order_slippage: True
下面对比一下两个差集的第一个数据,可以发现不同点是买入价格:
- 未使用涨跌停控制的diff_a的交易依然是使用1.17的价格买入股票
- 使用涨跌停控制的diff_b的交易使用接近涨停价格1.23的价格买入股票
备注:读者可以输出diff_a,diff_b自行一个一个对比一下看看,这里不再详对
diff_a.head(1)
diff_b.head(1)
下面通过EOrderSameRule.ORDER_SAME_BD做为AbuOrderPdProxy的参数,这样构造的AbuOrderPdProxy即切换了对交易单相同的规则:
class EOrderSameRule(Enum):
"""对order_pd中对order判断为是否相同使用的规则"""
"""order有相同的symbol和买入日期就认为是相同"""
ORDER_SAME_BD = 0
"""order有相同的symbol, 买入日期,和卖出日期,即不考虑价格,只要日期相同就相同"""
ORDER_SAME_BSD = 1
"""order有相同的symbol, 买入日期,相同的买入价格,即单子买入时刻都相同"""
ORDER_SAME_BDP = 2
"""order有相同的symbol, 买入日期, 买入价格, 并且相同的卖出日期和价格才认为是相同,即买入卖出时刻都相同"""
ORDER_SAME_BSPD = 3
使用相同的symbol和买入日期就认为是相同的规则,结果如下:
proxy = AbuOrderPdProxy(orders_pd, EOrderSameRule.ORDER_SAME_BD)
with proxy.proxy_work(abu_result_slippage.orders_pd) as (order, order_slippage):
diff_c = order - order_slippage
diff_c
ABuSymbolPd.make_kl_df('601766', start='20150417', end='20150417')
ABuSymbolPd.make_kl_df('300104', start='20131009', end='20131009')
可以看到diff_c中展示的三个交易单都是在集合竞价阶段已涨停了的股票交易,在开启了涨跌停控制后这三笔交易都没有进行买入。
如上述使用的AbuOrderPdProxy等工具,abupy不仅仅提供了对交易进行回测的功能,有许多分析,统计,机器学习,以及可视化工具在项目中可以帮助你分析策略,分析回测结果,以及为产生新的策略产生基础阀值等功能,在之后的教程中将陆续讲解使用以及示例。
abu量化文档目录章节
- 择时策略的开发
- 择时策略的优化
- 滑点策略与交易手续费
- 多支股票择时回测与仓位管理
- 选股策略的开发
- 回测结果的度量
- 寻找策略最优参数和评分
- A股市场的回测
- 港股市场的回测
- 比特币,莱特币的回测
- 期货市场的回测
- 机器学习与比特币示例
- 量化技术分析应用
- 量化相关性分析应用
- 量化交易和搜索引擎
- UMP主裁交易决策
- UMP边裁交易决策
- 自定义裁判决策交易
- 数据源
- A股全市场回测
- A股UMP决策
- 美股全市场回测
- 美股UMP决策
abu量化系统文档教程持续更新中,请关注公众号中的更新提醒。
更多关于abu量化系统请关注微信公众号: abu_quant
量化投资:第8节 A股市场的回测的更多相关文章
- 中国A股市场缘何遭遇9连跌?
端午长假刚过,当投资者对“红六月”预期信心满满的时候,A股市场却遭遇了诡异的跌势,截止6月17日收盘,A股出现了罕见的“9连跌”.不仅上证综指失守2200点年线整数位,深证成指跌幅则高达3%以上,而且 ...
- A股市场暴跌背后的三大元凶?
周一两市低开低走,盘中空方连续打压股指,大盘一路下行,沪指2000点关口告急,收于1963.24点,跌幅超过了5%.行业板块全线溃败.银行.证券领衔大幅杀跌,板块跌幅一度超过5%:继上周五中国石油A股 ...
- Python量化投资知识总结贴
Ricequant 量化社区的初衷让各位爱好量化的人士可以碰撞思维,在分享和争辩中学习到有用且实战的量化知识.有赖于各位在社区中贡献满满的干货以及有质量的讨论,从编程入门教学到技术指标再到多因子选股. ...
- 三分钟玩转微软AI量化投资开源库QLib
更多精彩内容,欢迎关注公众号:数量技术宅,也可添加技术宅个人微信号:sljsz01,与我交流. 微软QLib简介 微软亚洲研究院发布了 AI 量化投资开源平台"微矿 Qlib".Q ...
- 《量化投资:以MATLAB为工具》连载(2)基础篇-N分钟学会MATLAB(中)
http://www.matlabsky.com/thread-43937-1-1.html <量化投资:以MATLAB为工具>连载(3)基础篇-N分钟学会MATLAB(下) ...
- 《量化投资:以MATLAB为工具》连载(1)基础篇-N分钟学会MATLAB(上)
http://blog.sina.com.cn/s/blog_4cf8aad30102uylf.html <量化投资:以MATLAB为工具>连载(1)基础篇-N分钟学会MATLAB(上) ...
- A股市场各行业龙头股一览表
A股市场各行业龙头股一览表 一.指标股: 工商银行.中国银行.中国石化.中国国航.宝钢股份. 中国神华.建设银行.招商银行.华能国际.中国联通. 长江电力.中国人寿.中国石油 二.金融: 招商银行.浦 ...
- Python金融应用编程(数据分析、定价与量化投资)
近年来,金融领域的量化分析越来越受到理论界与实务界的重视,量化分析的技术也取得了较大的进展,成为备受关注的一个热点领域.所谓金融量化,就是将金融分析理论与计算机编程技术相结合,更为有效的利用现代计算技 ...
- 量化投资技术分析工具---ipython使用
量化投资实际上就是分析数据从而做出决策的过程python数据处理相关模块NumPy:数组批量计算pandas:灵活的表计算Matplotlib:数据可视化 学习目标:用NumPy+pandas+Mat ...
随机推荐
- 201521123042 Java第一周学习总结
1. 201521123042 <Java程序设计>第一周学习总结 a.用notepad++和eclipse编写Java程序 b.安装Java Q1.为什么java程序可以跨平台运行?执行 ...
- Java第九周学习总结
1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常相关内容. 2. 书面作业 本次PTA作业题集异常 1.常用异常 题目5-1 1.1 截图你的提交结果(出现学号) 1.2 自己 ...
- Eclipse rap 富客户端开发总结(11) : rcp/rap与spring ibatis集成
1. rcp/rap 与 spring 集成 Activator 是rcp/rap 启动时需要加载的类, 只需要加载一遍,所以与spring 集成的时候一般是在这个类里面加载spring 的Appli ...
- 安装wampserve之前需要安装vc++2012.
本人是64位系统下载了wampserver3.0.6之后安装好,启动报错缺少msvcr110.dll. 于是从网上下载了msvcr110.dll放到了windows的syswow64文件夹下,甚至还重 ...
- MongoDB中的映射,限制记录和记录拼排序 文档的插入查询更新删除操作
映射 在 MongoDB 中,映射(Projection)指的是只选择文档中的必要数据,而非全部数据.如果文档有 5 个字段,而你只需要显示 3 个,则只需选择 3 个字段即可. find() 方法 ...
- Vue.js 服务端渲染业务入门实践
作者:威威(沪江前端开发工程师) 本文原创,转载请注明作者及出处. 背景 最近, 产品同学一如往常笑嘻嘻的递来需求文档, 纵使内心万般拒绝, 身体倒是很诚实. 接过需求,好在需求不复杂, 简单构思 后 ...
- 【京东详情页】——原生js爬坑之标签页
一.引言 要做详情页的商品评价等5个li的标签页转换,效果如下: 二.实现原理 有一个特别的地方:上面五个li,但下面只有四个容器(table/div). 设计的目的:无论点哪个li,只有前四个div ...
- 深入浅出AQS之共享锁模式
在了解了AQS独占锁模式以后,接下来再来看看共享锁的实现原理. 原文地址:http://www.jianshu.com/p/1161d33fc1d0 搞清楚AQS独占锁的实现原理之后,再看共享锁的实现 ...
- 《MATLAB从入门到放弃》二维曲线和图形绘制基础(一): 什么是图形对象和句柄 ?
图形对象 一个图形包含了不同的对象 图形包括 核心对象和绘制对象 . 核心对象 线条对象 : line 文本对象 : text 矩形对象 : rectangle 补丁对象 : patch 图像对象 ...
- js特效遮罩层(弹出层)
<!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>& ...