In [1]:
# 基础库导入,注意第一次运行时会比较慢,要做数据的解压等处理操作
from __future__ import print_function
from __future__ import division
import warnings
warnings.filterwarnings('ignore')
warnings.simplefilter('ignore')
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
import os
import sys
# 使用insert 0即只使用github,避免交叉使用了pip安装的abupy,导致的版本不一致问题
sys.path.insert(0, os.path.abspath('../'))
import abupy
In [2]:
# 使用沙盒数据,目的是和书中一样的数据环境
abupy.env.enable_example_env_ipython()
abupy.env.enable_example_env_ipython()的目的是使用abupy中内置的测试金融时间序列数据,即不从网络获取数据, 只从本地获取数据,优点是所有人在任何时间运行代码的结果都是一致的,因为数据是一致,在编写使用文档的使用,为了所有人在所有时间点可以运行出一致的结果,本教程中大多数示例都使用abupy中内置的测试金融时间序列数据
abupy中内置的k线数据有
V0(PVC) P0(棕榈) M0(豆粕) I0(铁矿石) JD0(鸡蛋) L0(塑料) PP0(PP) FB0(纤维板) BB0(胶合板) Y0(豆油) C0(玉米) A0(豆一) B0(豆二) J0(焦炭) JM0(焦煤) CS0(玉米淀粉) TA0(PTA) OI0(菜油) RS0(菜籽) RM0(菜粕) ZC0(动力煤) WH0(强麦) JR0(粳稻) SR0(白糖) CF0(棉花) RI0(早籼稻) MA0(郑醇) FG0(玻璃) LR0(晚籼稻) SF0(硅铁) SM0(锰硅) FU0(燃油) AL0(沪铝) RU0(橡胶) ZN0(沪锌) CU0(沪铜) AU0(黄金) RB0(螺纹钢) WR0(线材) PB0(沪铅) AG0(白银) BU0(沥青) HC0(热轧卷板) SN0(沪锡) NI0(沪镍)
NID(伦敦镍) PBD(伦敦铅) SND(伦敦锡) ZSD(伦敦锌) AHD(伦敦铝) CAD(伦敦铜) XAU(伦敦金) XAG(伦敦银) XPT(伦敦铂金) S(美黄豆) W(美小麦) C(美玉米) BO(美豆油) SM(美豆粕) HG(纽约铜) SI(纽约白银) GC(纽约黄金) CL(纽约原油) NG(纽约天然气)
enable_example_env_ipython的情况下,当请求不在内置数据中的数据时,也不会从网络去获取数据,只会返回空
eg: 使用ABuSymbolPd请求不在内置数据中的京东(usJD)
In [4]:
from abupy import ABuSymbolPd
ABuSymbolPd.make_kl_df('usJD') is None
Out[4]:
使用abupy.env.disable_example_env_ipython关闭沙盒数据后,即可以使用正常的数据获取模式,非本地沙盒数据
eg: 使用ABuSymbolPd请求不在内置数据中的京东(usJD)
In [5]:
abupy.env.disable_example_env_ipython()
us_jd = ABuSymbolPd.make_kl_df('usJD')
# 再次开启沙盒环境,本节的示例都是在沙盒数据环境下运行
abupy.env.enable_example_env_ipython()
tail = None
if us_jd is not None:
tail = us_jd.tail()
tail
Out[5]:
备注:关于abupy更多环境配置,数据源切换,市场切换,存贮方式等切换等在后续章节会讲解
量化系统一般分为回测模块、实盘模块。
回测模块最重要的组成部份是择时、选股:
只有在对的时间买入对的股票才能获利,就像下面张小娴的名言一样,可以把‘股票’ 代替 ‘人’完全合乎逻辑。
在对的时间,遇见对的人(股票),是一种幸福
在对的时间,遇见错的人(股票),是一种悲伤
在错的时间,遇见对的人(股票),是一声叹息
在错的时间,遇见错的人(股票),是一种无奈
本节首先讲解择时(什么时候投资), 后面的小节将讲解选股
In [3]:
from abupy import AbuFactorBuyXD, BuyCallMixin
class AbuFactorBuyBreak(AbuFactorBuyXD, BuyCallMixin):
"""示例继承AbuFactorBuyXD完成正向突破买入择时类, 混入BuyCallMixin,即向上突破触发买入event"""
def fit_day(self, today):
"""
针对每一个交易日拟合买入交易策略,寻找向上突破买入机会
:param today: 当前驱动的交易日金融时间序列数据
:return:
"""
# 今天的收盘价格达到xd天内最高价格则符合买入条件
if today.close == self.xd_kl.close.max():
# 生成买入订单, 由于使用了今天的收盘价格做为策略信号判断,所以信号发出后,只能明天买
return self.buy_tomorrow()
return None
上AbuFactorBuyBreak即是完成了海龟突破策略的代码实现:
更多买入因子实现代码请阅读AbuFactorBuyBase
本节首先通过分解流程方式一步一步实现使用AbuFactorBuyBreak进行回测,目的是为了更清晰的说明内部操作流程, 编码过程会显的有些复杂臃肿,但实际上在编写完成一个策略后只需要使用一行代码即可以完成回测,在后面的小节中会进行讲解。
通过字典形式初始化买入buy_factors,首先实现针对一支股票的择时操作:
In [4]:
from abupy import AbuBenchmark
from abupy import AbuCapital
# buy_factors 60日向上突破,42日向上突破两个因子
buy_factors = [{'xd': 60, 'class': AbuFactorBuyBreak},
{'xd': 42, 'class': AbuFactorBuyBreak}]
benchmark = AbuBenchmark()
capital = AbuCapital(1000000, benchmark)
择时ABuPickTimeExecute主要驱动方式为时间驱动,即通过时间序列一天一天递进,通过买入因子卖出因子的fit来查询是否有事件生成(买入卖出行为),另外也有框架使用事件驱动,它们分别有各自的优点,原始的abu框架就是时间驱动+事件驱动的,它最大的优点是执行效率比时间驱动高,但是灵活性及扩展性要比时间驱动差。
下面使用ABuPickTimeExecute开始进行择时交易回测,ABuPickTimeExecute实际上不是最简洁的回测接口,更简单的接口可以使用abu.run_loop_back()函数,在后面的章节将会示例使用,本节目的是为了更清晰的说明内部操作流程。
由回测结果图可看出由于AbuPickTimeWorker没有设置sell_factors,所以所有的交易单子都一直保留没有卖出:
In [5]:
from abupy import ABuPickTimeExecute
orders_pd, action_pd, _ = ABuPickTimeExecute.do_symbols_with_same_factors(['usTSLA'],
benchmark,
buy_factors,
None,
capital, show=True)
In [9]:
from abupy import AbuFactorSellXD, ESupportDirection
class AbuFactorSellBreak(AbuFactorSellXD):
"""示例继承AbuFactorBuyXD, 向下突破卖出择时因子"""
def support_direction(self):
"""支持的方向,只支持正向"""
return [ESupportDirection.DIRECTION_CAll.value]
def fit_day(self, today, orders):
"""
寻找向下突破作为策略卖出驱动event
:param today: 当前驱动的交易日金融时间序列数据
:param orders: 买入择时策略中生成的订单序列
"""
# 今天的收盘价格达到xd天内最低价格则符合条件
if today.close == self.xd_kl.close.min():
for order in orders:
self.sell_tomorrow(order)
上AbuFactorSellBreak即是完成了卖出突破策略的代码实现:
更多具体卖出因子实现代码请阅读AbuFactorSellBase
备注:之后章节的期货示例讲讲解如何使用ESupportDirection做反向交易,buy put
同理使用字典组装卖出因子:
In [20]:
# 使用120天向下突破为卖出信号
sell_factor1 = {'xd': 120, 'class': AbuFactorSellBreak}
# buy_factors 60日向上突破,42日向上突破两个因子
buy_factors = [{'xd': 60, 'class': AbuFactorBuyBreak},
{'xd': 42, 'class': AbuFactorBuyBreak}]
# 只使用120天向下突破为卖出因子
sell_factors = [sell_factor1]
capital = AbuCapital(1000000, benchmark)
orders_pd, action_pd, _ = ABuPickTimeExecute.do_symbols_with_same_factors(['usTSLA'],
benchmark,
buy_factors,
sell_factors,
capital, show=True)
从上图可以看到,大多数的交易卖出因子都生效了,但效果很不好, 下一节将继续通过增加多个卖出因子同时作用于策略上来提高策略的效果。
abu量化系统文档教程持续更新中,请关注公众号中的更新提醒。
更多关于量化交易相关请阅读《量化交易之路》
更多关于量化交易与机器学习相关请阅读《机器学习之路》
更多关于abu量化系统请关注微信公众号: abu_quant