ABU量化系统使用文档

第19节 数据源

作者: 阿布

阿布量化版权所有 未经允许 禁止转载

abu量化系统github地址 (欢迎+star)

本节ipython notebook

abupy除了之前章节讲解示例时使用的内置沙盒数据外,也内置了几个数据源,支持实时获取美股,A股,港股,期货和比特币等类型数据,内置的数据源仅供学习使用,abupy提供了接入外部数据源的接口和规范,本节的示例将讲解内置数据源的切换,以及接入用户外部的数据源的接口规范。

首先导入abupy中本节使用的模块:


In [2]:
# 基础库导入

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

# 使用沙盒数据,目的是和书中一样的数据环境
abupy.env.enable_example_env_ipython()


enable example env will only read RomDataBu/df_kl.h5

In [3]:
from abupy import abu, EMarketTargetType, AbuMetricsBase, ABuMarketDrawing, ABuProgress, ABuSymbolPd, get_price, ABuIndustries
from abupy import EMarketDataFetchMode, EDataCacheType, EMarketSourceType, FuturesBaseMarket, TCBaseMarket, ABuDateUtil
from abupy import AbuDataParseWrap, StockBaseMarket, SupportMixin, ABuNetWork, Symbol, code_to_symbol

和之前的章节不一样,关闭沙盒数据接口,使用实时数据源提供数据:


In [4]:
abupy.env.disable_example_env_ipython()


disable example env

1. 数据模式的切换

使用g_data_fetch_mode可以查看当前的数据模式:


In [5]:
abupy.env.g_data_fetch_mode


Out[5]:
<EMarketDataFetchMode.E_DATA_FETCH_NORMAL: 0>

默认使用模式为E_DATA_FETCH_NORMAL,NORMAL的意义是默认优先从缓存中获取,如果缓存中不存在,再访问网络,尝试从网络获取,除此之外还有一些优化,比如虽然缓存中的数据也无法满足要求,但是缓存索引纪录今天已经尝试从网络获取,这种情况下也不再访问网络。

更多详情请阅读ABuDataSource代码

E_DATA_FETCH_FORCE_NET为强制使用网络进行数据更新,一般不推荐使用,如果切换了数据源,或者缓存中的数据存在问题的情况下会使用:


In [8]:
abupy.env.g_data_fetch_mode = EMarketDataFetchMode.E_DATA_FETCH_FORCE_NET

In [6]:
ABuSymbolPd.make_kl_df('usBIDU').tail()


Out[6]:
atr14 atr21 close date date_week high key low open p_change pre_close volume
2017-08-02 9.7977 8.4559 221.96 20170802 2 224.64 499 218.58 224.12 -1.613 225.60 3688218
2017-08-03 9.4807 8.3617 227.39 20170803 3 227.97 500 220.55 221.00 2.446 221.96 3433083
2017-08-04 9.3339 8.3634 226.05 20170804 4 230.34 501 225.70 227.28 -0.589 227.39 3520335
2017-08-07 8.6520 7.9867 227.16 20170807 0 228.99 502 224.77 225.60 0.491 226.05 2998194
2017-08-08 8.4744 7.9261 229.45 20170808 1 233.37 503 226.54 226.60 1.008 227.16 4021199

E_DATA_FETCH_FORCE_LOCAL为强制从缓存获取,实际上在做回测的时候,使用的一般都是这种模式,因为比如编写了一个策略进行回测结果度量,通常情况下需要反复的修改策略,重新进行回测,强制使用缓存的好处是:

  1. 保证使用的数据集没有发生变化,度量结果有可比性
  2. 提高回测运行效率,特别是针对全市场回测
  3. 分类数据获取和回测,方便问题排除

In [7]:
abupy.env.g_data_fetch_mode = EMarketDataFetchMode.E_DATA_FETCH_FORCE_LOCAL

In [8]:
ABuSymbolPd.make_kl_df('usBIDU').tail(1)


Out[8]:
atr14 atr21 close date date_week high key low open p_change pre_close volume
2017-08-08 8.4744 7.9261 229.45 20170808 1 233.37 503 226.54 226.6 1.008 227.16 4021199

下面把数据获取模式恢复为默认的E_DATA_FETCH_NORMAL:


In [12]:
abupy.env.g_data_fetch_mode = EMarketDataFetchMode.E_DATA_FETCH_NORMAL

2. 数据存储的切换

默认的缓存数据存储模式为CSV,如下所示:


In [6]:
abupy.env.g_data_cache_type


Out[6]:
<EDataCacheType.E_DATA_CACHE_CSV: 1>

缓存的csv数据存贮文件路径在~/abu/data/csv/,可使运行下面命令直接打开目录:


In [7]:
if abupy.env.g_is_mac_os:
    !open $abupy.env.g_project_kl_df_data_csv
else:
    !echo $abupy.env.g_project_kl_df_data_csv

可以通过g_data_cache_type切换其它存贮模式,如下使用HDF5进行数据存贮:


In [8]:
abupy.env.g_data_cache_type = EDataCacheType.E_DATA_CACHE_HDF5

缓存的hdf5文件路径在~/abu/data/df_kl.h5,可使运行下面命令直接打开目录, 或者显示完整路径:


In [9]:
if abupy.env.g_is_mac_os:
    !open $abupy.env.g_project_data_dir
else:
    !echo $abupy.env.g_project_data_dir

In [13]:
ABuSymbolPd.make_kl_df('usTSLA').tail()


Out[13]:
close high low p_change open pre_close volume date date_week atr21 atr14 key
2017-08-02 315.96 319.22 311.41 -1.130 319.00 319.57 119040 20170802 2 14.8108 14.7172 497
2017-08-03 347.09 350.00 343.15 9.853 345.33 315.96 13535033 20170803 3 16.2307 16.8122 498
2017-08-04 356.91 357.27 343.30 2.829 347.00 347.09 9268909 20170804 4 18.5106 20.0786 499
2017-08-07 355.17 359.48 352.75 -0.488 357.35 356.91 6324480 20170807 0 17.9542 19.0535 500
2017-08-08 365.22 368.58 357.40 2.830 357.53 355.17 7449837 20170808 1 17.3829 18.0690 501

下面仍然切换回默认的csv模式,csv的优点是存贮空间需要小,可以并行读写,且针对不同平台兼容性好:


In [10]:
abupy.env.g_data_cache_type = EDataCacheType.E_DATA_CACHE_CSV

3. 数据源的切换

如下显示当前的数据源g_market_source为百度数据源:


In [17]:
abupy.env.g_market_source


Out[17]:
<EMarketSourceType.E_MARKET_SOURCE_bd: 0>

如下想要获取比特币的数据,但是输出显示百度的数据源不支持比特币:


In [23]:
ABuSymbolPd.make_kl_df('btc')


Exception kline_pd symbol:btc e:BDApi don't support tc_COIN:btc!

切换数据源为火币数据源,即可正常获取数据,如下:


In [22]:
abupy.env.g_market_source = EMarketSourceType.E_MARKET_SOURCE_hb_tc
ABuSymbolPd.make_kl_df('btc').tail()


Out[22]:
open close high low volume date pre_close date_week p_change key atr21 atr14
2017-08-05 19310.05 21191.00 21540.00 19113.03 23110 20170805 19339.00 5 9.577 499 1652.5121 1667.0629
2017-08-06 21198.00 21959.73 22490.00 21126.45 13821 20170806 21191.00 6 3.628 500 1788.7382 1864.9212
2017-08-07 21959.00 22200.00 22833.00 21258.00 12381 20170807 21959.73 0 1.094 501 1775.3984 1835.1984
2017-08-08 22200.00 22588.08 23398.96 21940.00 15933 20170808 22200.00 1 1.748 502 1746.6313 1785.0332
2017-08-09 22588.08 22380.01 23149.99 22360.00 4679 20170809 22588.08 2 -0.921 503 1674.2093 1673.6941

类似,下面想要获取期货鸡蛋的数据,但是输出显示火币的数据源不支持期货市场:


In [25]:
ABuSymbolPd.make_kl_df('jd0')


Exception kline_pd symbol:jd0 e:HBApi don't support futures_cn_DCE:JD0!

切换数据源为新浪期货数据源,即可正常获取数据,如下:


In [28]:
abupy.env.g_market_source = EMarketSourceType.E_MARKET_SOURCE_sn_futures

In [29]:
ABuSymbolPd.make_kl_df('jd0').tail()


Out[29]:
open close high low volume date pre_close date_week p_change key atr21 atr14
2017-08-02 4060.0 4107.0 4122.0 4052.0 69136.0 2.0171e+07 3982.0 2.0 3.139 485 110.7679 109.0249
2017-08-03 4096.0 4088.0 4111.0 4080.0 55790.0 2.0171e+07 4107.0 3.0 -0.463 486 112.4254 111.6882
2017-08-04 4120.0 4260.0 4290.0 4117.0 248006.0 2.0171e+07 4088.0 4.0 4.207 487 118.8413 121.1965
2017-08-07 4298.0 4295.0 4410.0 4272.0 249786.0 2.0171e+07 4260.0 0.0 0.822 488 137.3103 147.9703
2017-08-08 4295.0 4345.0 4358.0 4281.0 175570.0 2.0171e+07 4295.0 1.0 1.164 489 133.7366 141.3076

4. 全市场数据的更新

在之前的章节使用abu.run_loop_back进行交易回测,使用的都是沙盒数据,如果需要使用实时数据,特别是回测交易多的情况下,比如全市场测试,推荐在使用abu.run_loop_back进行回测前先使用abu.run_kl_update将数据进行更新。

在run_kl_update中会首先强制使用网络数据进行全市场数据更新,在更新完毕后会将全市场的交易数据都写入缓存,再abu.run_loop_back运行回测的时候使用本地数据模式,即实现数据更新与策略回测分离,运行效率提高。

下面的代码将分别获取美股,A股,港股,期货,比特币,莱特币6年的交易数据,在后面的章节将分别使用这些数据做回测示例,读者可只获取自己关心的市场的交易数据,不必全部运行。

所有获取的数据已经存放在百度云盘上,后面的章节使用的数据都是本节更新的数据,建议直接从云盘下载入库完毕的数据库,不需要从各个数据源再一个一个的下载数据进行入库,百度云地址如下:

csv格式美股,A股,港股,币类,期货6年日k数据 密码: gvtr

下面数据存贮格式为hdf5数据,由于hdf5文件解压后非常大,还需要区分python版本,所以如果没有足够的存贮空间 特别是python2下,建议使用csv格式的缓存文件:

mac系统python3 美股,A股,港股,币类,期货6年日k数据 密码: ecyp

mac系统python2 A股6年日k数据: 密码: sid8

mac系统python2 美股6年日k数据: 密码: uaww

windows python3 美股,A股,港股,币类,期货6年日k数据 密码: 3cwe

windows python2 A股6年日k数据: 密码: 78mb

windows python2 美股6年日k数据: 密码: 63r3

下载完毕上述数据后,hdf5解压得到df_kl.h5文件,csv解压得到csv文件夹,解压后放到下面路径下即可


In [4]:
if abupy.env.g_is_mac_os:
    !open $abupy.env.g_project_data_dir
else:
    !echo $abupy.env.g_project_data_dir

如果不想通过直接下载数据文件的方式,也可下面通过切换至腾讯数据源,然后进行美股数据全市场更新:

备注:耗时操作,大概需要运行15分钟左右,可以在做其它事情的时候运行


In [ ]:
%%time
abupy.env.g_market_source = EMarketSourceType.E_MARKET_SOURCE_tx
abupy.env.g_data_cache_type = EDataCacheType.E_DATA_CACHE_CSV
abu.run_kl_update(start='2011-08-08', end='2017-08-08', market=EMarketTargetType.E_MARKET_TARGET_US, n_jobs=10)

如果不想通过直接下载数据文件的方式,也可切换至百度数据源,然后进行A股数据全市场更新:

备注:耗时操作,大概需要运行20分钟左右,可以在做其它事情的时候运行


In [6]:
%%time
abupy.env.g_market_source = EMarketSourceType.E_MARKET_SOURCE_bd
abupy.env.g_data_cache_type = EDataCacheType.E_DATA_CACHE_CSV
abu.run_kl_update(start='2011-08-08', end='2017-08-08', market=EMarketTargetType.E_MARKET_TARGET_CN, n_jobs=10)


CPU times: user 19min 21s, sys: 2min 48s, total: 22min 9s
Wall time: 21min 11s

如果不想通过直接下载数据文件的方式,也可切换至网易数据源,然后进行港股数据全市场更新:

备注:耗时操作,大概需要运行5分钟左右,可以在做其它事情的时候运行


In [7]:
%%time
abupy.env.g_market_source = EMarketSourceType.E_MARKET_SOURCE_nt
abupy.env.g_data_cache_type = EDataCacheType.E_DATA_CACHE_CSV
abu.run_kl_update(start='2011-08-08', end='2017-08-08', market=EMarketTargetType.E_MARKET_TARGET_HK, n_jobs=10)


CPU times: user 5min 9s, sys: 50.9 s, total: 6min
Wall time: 5min 41s

切换至新浪期货数据源,然后进行期货数据全市场更新:

备注:非耗时操作,大概30秒


In [32]:
%%time
abupy.env.g_market_source = EMarketSourceType.E_MARKET_SOURCE_sn_futures
abupy.env.g_data_cache_type = EDataCacheType.E_DATA_CACHE_CSV
abu.run_kl_update(start='2011-08-08', end='2017-08-08', market=EMarketTargetType.E_MARKET_TARGET_FUTURES_CN, n_jobs=4)


CPU times: user 12.9 s, sys: 2.04 s, total: 14.9 s
Wall time: 19.5 s

切换至火币数据源,然后进行比特币,莱特币数据全市场更新:

备注:非耗时操作,大概需要5秒


In [33]:
%%time
abupy.env.g_market_source = EMarketSourceType.E_MARKET_SOURCE_hb_tc
abupy.env.g_data_cache_type = EDataCacheType.E_DATA_CACHE_CSV
abu.run_kl_update(start='2011-08-08', end='2017-08-08', market=EMarketTargetType.E_MARKET_TARGET_TC, n_jobs=2)


CPU times: user 718 ms, sys: 418 ms, total: 1.14 s
Wall time: 3.19 s

5. 接入外部数据源,股票数据源

abupy中内置的数据源:

  • 美股市场:腾讯数据源,百度数据源,网易数据源,新浪数据源
  • 港股市场:腾讯数据源,百度数据源,网易数据源
  • A股市场: 腾讯数据源,百度数据源,网易数据源
  • 期货市场:新浪期货数据源,新浪国际期货数据源
  • 比特币,莱特币:火币网数据源

这些数据源都只是为用户学习使用,并不能保证数据一直通畅,而且如果用户很在乎数据质量,比如有些数据源会有前复权数据错误问题,有些数据源成交量不准确等问题,那么就需要接入用户自己的数据源。

下面首先示例接入股票类型的数据源,首先实现一个数据源返回数据解析类,如下所示:


In [56]:
@AbuDataParseWrap()
class SNUSParser(object):
    """snus数据源解析类,被类装饰器AbuDataParseWrap装饰"""
    def __init__(self, symbol, json_dict):
        """
        :param symbol: 请求的symbol str对象
        :param json_dict: 请求返回的json数据
        """
        data = json_dict
        # 为AbuDataParseWrap准备类必须的属性序列
        if len(data) > 0:
            # 时间日期序列
            self.date = [item['d'] for item in data]
            # 开盘价格序列
            self.open = [item['o'] for item in data]
            # 收盘价格序列
            self.close = [item['c'] for item in data]
            # 最高价格序列
            self.high = [item['h'] for item in data]
            # 最低价格序列
            self.low = [item['l'] for item in data]
            # 成交量序列
            self.volume = [item['v'] for item in data]

上面编写的SNUSParser即为一个数据源返回数据解析类:

  1. 数据源解析类需要被类装饰器AbuDataParseWrap装饰
  2. 完成__init__函数,根据这里的数据json_dict来拆分成self.date,self.open,self.close,self.high,self.low,self.volume

如本例中每一条json数据的格式为:

{'d': '2017-08-08', 'o': '102.29', 'h': '102.35', 'l': '99.16', 'c': '100.07', 'v': '1834706'}

init函数目的就是通过拆解网络原始数据形成上述的五个基本序列,之后在类装饰器AbuDataParseWrap中会进行数据的再次加工以及规范标准化处理

更多详情请阅读源代码ABuDataParser

备注:这里拆解的过程没有在乎效率,只为好理解过程

在编写数据解析类后就需要编写个数据源类,如下所示,以新浪美股数据源为例:


In [46]:
class SNUSApi(StockBaseMarket, SupportMixin):
    """snus数据源,支持美股"""
    K_NET_BASE = "http://stock.finance.sina.com.cn/usstock/api/json_v2.php/US_MinKService.getDailyK?" \
                 "symbol=%s&___qn=3n"

    def __init__(self, symbol):
        """
        :param symbol: Symbol类型对象
        """
        super(SNUSApi, self).__init__(symbol)
        # 设置数据源解析对象类
        self.data_parser_cls = SNUSParser

    def _support_market(self):
        """声明数据源支持美股"""
        return [EMarketTargetType.E_MARKET_TARGET_US]

    def kline(self, n_folds=2, start=None, end=None):
        """日k线接口"""
        url = SNUSApi.K_NET_BASE % self._symbol.symbol_code
        data = ABuNetWork.get(url=url, timeout=(10, 60)).json()
        kl_df = self.data_parser_cls(self._symbol, data).df
        if kl_df is None:
            return None
        return StockBaseMarket._fix_kline_pd(kl_df, n_folds, start, end)

    def minute(self, n_fold=5, *args, **kwargs):
        """分钟k线接口"""
        raise NotImplementedError('SNUSApi minute NotImplementedError!')

上面编写的SNUSApi即为一个股票数据源类:

  1. 股票类型数据源类需要继承StockBaseMarket
  2. __init__函数中指定数据源解析类
  3. 数据源类需要混入SupportMixin类,实现_support_market方法,声明支持的市场,本例只支持美股市场
  4. 数据源类需要实现kline接口,完成获取指定symbol的日线数据,将日线数据交给数据源解析类进行处理
  5. 数据源类需要实现分钟k线接口,也可以直接raise NotImplementedError

下面示例使用,如下通过check_support检测是否支持A股,结果显示False:


In [47]:
SNUSApi(code_to_symbol('sh601766')).check_support(rs=False)


Out[47]:
False

如下通过check_support检测是否支持美股,结果显示True:


In [48]:
SNUSApi(code_to_symbol('usSINA')).check_support(rs=False)


Out[48]:
True

如下通过kline接口获取数据,如下所示:


In [42]:
SNUSApi(code_to_symbol('usSINA')).kline().tail()


Out[42]:
open close high low volume date pre_close date_week p_change
2017-08-02 95.91 93.97 96.61 92.37 895105 20170802 95.90 2 -2.013
2017-08-03 94.37 96.26 97.04 93.52 671606 20170803 93.97 3 2.437
2017-08-04 96.87 96.12 98.00 95.54 1052727 20170804 96.26 4 -0.145
2017-08-07 97.25 100.33 100.79 97.16 2330438 20170807 96.12 0 4.380
2017-08-08 102.29 100.07 102.35 99.16 1834706 20170808 100.33 1 -0.259

接入SNUSApi至abupy系统中,只需要将数据源类名称直接赋予abupy.env.g_private_data_source:


In [50]:
abupy.env.g_private_data_source = SNUSApi

下面使用make_kl_df接口获取sh601766数据,显示SNUSApi不支持:


In [53]:
ABuSymbolPd.make_kl_df('sh601766')


Exception kline_pd symbol:sh601766 e:SNUSApi don't support hs_sh:601766!

下面使用make_kl_df接口获取美股数据, 返回的数据即是通过上面实现的SNUSApi返回的:


In [54]:
ABuSymbolPd.make_kl_df('usSINA').tail()


Out[54]:
open close high low volume date pre_close date_week p_change atr21 atr14 key
2017-08-02 95.91 93.97 96.61 92.37 895105 20170802 95.90 2 -2.013 3.3232 3.2947 499
2017-08-03 94.37 96.26 97.04 93.52 671606 20170803 93.97 3 2.437 3.3411 3.3248 500
2017-08-04 96.87 96.12 98.00 95.54 1052727 20170804 96.26 4 -0.145 3.4037 3.4188 501
2017-08-07 97.25 100.33 100.79 97.16 2330438 20170807 96.12 0 4.380 3.5061 3.5670 502
2017-08-08 102.29 100.07 102.35 99.16 1834706 20170808 100.33 1 -0.259 3.7537 3.9220 503

6. 接入外部数据源,期货数据源

下面示例接入期货类型的数据源,首先实现一个数据源返回数据解析类,如下所示:


In [12]:
@AbuDataParseWrap()
class SNFuturesParser(object):
    """示例期货数据源解析类,被类装饰器AbuDataParseWrap装饰"""
    # noinspection PyUnusedLocal
    def __init__(self, symbol, json_dict):
        """
        :param symbol: 请求的symbol str对象
        :param json_dict: 请求返回的json数据
        """
        data = json_dict
        # 为AbuDataParseWrap准备类必须的属性序列
        if len(data) > 0:
            # 时间日期序列
            self.date = [item[0] for item in data]
            # 开盘价格序列
            self.open = [item[1] for item in data]
            # 最高价格序列
            self.high = [item[2] for item in data]
            # 最低价格序列
            self.low = [item[3] for item in data]
            # 收盘价格序列
            self.close = [item[4] for item in data]
            # 成交量序列
            self.volume = [item[5] for item in data]

上面编写的SNFuturesParser与SNUSParser基本相同:被类装饰器AbuDataParseWrap装饰,实现__init__函数

如本例中每一条json数据的格式为, 所以通过序号解析对应的值:

['2017-08-08', '4295.000', '4358.000', '4281.000', '4345.000', '175570']

在编写数据解析类后就需要编写个数据源类,如下所示,以新浪期货数据源为例:


In [58]:
class SNFuturesApi(FuturesBaseMarket, SupportMixin):
    """sn futures数据源,支持国内期货"""

    K_NET_BASE = "http://stock.finance.sina.com.cn/futures/api/json_v2.php/" \
                 "IndexService.getInnerFuturesDailyKLine?symbol=%s"

    def __init__(self, symbol):
        """
        :param symbol: Symbol类型对象
        """
        super(SNFuturesApi, self).__init__(symbol)
        # 设置数据源解析对象类
        self.data_parser_cls = SNFuturesParser

    def _support_market(self):
        """声明数据源支持期货数据"""
        return [EMarketTargetType.E_MARKET_TARGET_FUTURES_CN]

    def kline(self, n_folds=2, start=None, end=None):
        """日k线接口"""
        url = SNFuturesApi.K_NET_BASE % self._symbol.symbol_code
        data = ABuNetWork.get(url=url, timeout=(10, 60)).json()
        kl_df = self.data_parser_cls(self._symbol, data).df
        if kl_df is None:
            return None
        return FuturesBaseMarket._fix_kline_pd(kl_df, n_folds, start, end)

上面编写的SNFuturesApi即为一个期货数据源类:

  1. 期货类型数据源类需要继承FuturesBaseMarket
  2. __init__函数中指定数据源解析类
  3. 数据源类需要混入SupportMixin类,实现_support_market方法,声明支持的市场,本例只支持期货市场
  4. 数据源类需要实现kline接口,完成获取指定symbol的日线数据,将日线数据交给数据源解析类进行处理

下面示例使用,如下通过check_support检测是否支持美股,结果显示False:


In [26]:
SNFuturesApi(code_to_symbol('usSINA')).check_support(rs=False)


Out[26]:
False

如下通过check_support检测是否支持期货,结果显示True:


In [6]:
SNFuturesApi(code_to_symbol('jd0')).check_support(rs=False)


Out[6]:
True

接入SNFuturesApi至abupy系统中, 使用make_kl_df接口获取期货鸡蛋连续数据:


In [34]:
abupy.env.g_private_data_source = SNFuturesApi
ABuSymbolPd.make_kl_df('jd0').tail()


Out[34]:
open close high low volume date pre_close date_week p_change key atr21 atr14
2017-08-02 4060.0 4107.0 4122.0 4052.0 69136.0 2.0171e+07 3982.0 2.0 3.139 485 110.7679 109.0249
2017-08-03 4096.0 4088.0 4111.0 4080.0 55790.0 2.0171e+07 4107.0 3.0 -0.463 486 112.4254 111.6882
2017-08-04 4120.0 4260.0 4290.0 4117.0 248006.0 2.0171e+07 4088.0 4.0 4.207 487 118.8413 121.1965
2017-08-07 4298.0 4295.0 4410.0 4272.0 249786.0 2.0171e+07 4260.0 0.0 0.822 488 137.3103 147.9703
2017-08-08 4295.0 4345.0 4358.0 4281.0 175570.0 2.0171e+07 4295.0 1.0 1.164 489 133.7366 141.3076

与期货市场类似的是美股期权市场,abupy同样支持美股期权市场的回测分析等操作,但由于暂时没有合适的可对外的数据源提供,所以暂时无示例,用户也可以在abupy中接入自己的美股期权数据源。

7. 接入外部数据源,比特币,莱特币数据源

下面示例接入币类市场数据源,首先实现一个数据源返回数据解析类,如下所示:


In [60]:
@AbuDataParseWrap()
class HBTCParser(object):
    """示例币类市场数据源解析类,被类装饰器AbuDataParseWrap装饰"""
    def __init__(self, symbol, json_dict):
        """
        :param symbol: 请求的symbol str对象
        :param json_dict: 请求返回的json数据
        """
        data = json_dict
        # 为AbuDataParseWrap准备类必须的属性序列
        if len(data) > 0:
            # 时间日期序列
            self.date = [item[0] for item in data]
            # 开盘价格序列
            self.open = [item[1] for item in data]
            # 最高价格序列
            self.high = [item[2] for item in data]
            # 最低价格序列
            self.low = [item[3] for item in data]
            # 收盘价格序列
            self.close = [item[4] for item in data]
            # 成交量序列
            self.volume = [item[5] for item in data]

            # 时间日期进行格式转化,转化为如2017-07-26格式字符串
            self.date = list(map(lambda date: ABuDateUtil.fmt_date(date), self.date))

上面编写的HBTCParser与上面的数据解析类基本相同:被类装饰器AbuDataParseWrap装饰,实现__init__函数

如本例中每一条json数据的格式为, 所以通过序号解析对应的值:

['20170809000000000', 22588.08, 23149.99, 22250.0, 22730.0, 7425.5134]

所以需要使用ABuDateUtil.fmt_date将时间进行格式转化,下面编写对应的数据源类,如下所示,以火币数据源为例:


In [62]:
class HBApi(TCBaseMarket, SupportMixin):
    """hb数据源,支持币类,比特币,莱特币"""

    K_NET_BASE = 'https://www.huobi.com/qt/staticmarket/%s_kline_100_json.js?length=%d'

    def __init__(self, symbol):
        """
        :param symbol: Symbol类型对象
        """
        super(HBApi, self).__init__(symbol)
        # 设置数据源解析对象类
        self.data_parser_cls = HBTCParser

    def _support_market(self):
        """只支持币类市场"""
        return [EMarketTargetType.E_MARKET_TARGET_TC]

    def kline(self, n_folds=2, start=None, end=None):
        """日k线接口"""
        req_cnt = n_folds * 365
        if start is not None and end is not None:
            # 向上取整数,下面使用_fix_kline_pd再次进行剪裁, 要使用current_str_date不能是end
            folds = math.ceil(ABuDateUtil.diff(ABuDateUtil.date_str_to_int(start),
                                               ABuDateUtil.current_str_date()) / 365)
            req_cnt = folds * 365

        url = HBApi.K_NET_BASE % (self._symbol.symbol_code, req_cnt)
        data = ABuNetWork.get(url=url, timeout=(10, 60)).json()
        kl_df = self.data_parser_cls(self._symbol, data).df
        if kl_df is None:
            return None
        return TCBaseMarket._fix_kline_pd(kl_df, n_folds, start, end)

    def minute(self, *args, **kwargs):
        """分钟k线接口"""
        raise NotImplementedError('HBApi minute NotImplementedError!')

上面编写的HBApi即为一个支持比特币,莱特币数据源类:

  1. 期货类型数据源类需要继承TCBaseMarket
  2. __init__函数中指定数据源解析类
  3. 数据源类需要混入SupportMixin类,实现_support_market方法,声明支持的市场,本例只支持币类市场
  4. 数据源类需要实现kline接口,完成获取指定symbol的日线数据,将日线数据交给数据源解析类进行处理
  5. 数据源类需要实现分钟k线接口minute,也可raise NotImplementedError

下面示例使用,如下通过check_support检测是否支持美股,结果显示False:


In [63]:
HBApi(code_to_symbol('usSINA')).check_support(rs=False)


Out[63]:
False

如下通过check_support检测是否支持比特币,结果显示True:


In [18]:
HBApi(code_to_symbol('btc')).check_support(rs=False)


Out[18]:
True

接入HBApi至abupy系统中, 使用make_kl_df接口获取期货比特币数据:


In [20]:
abupy.env.g_private_data_source = HBApi
ABuSymbolPd.make_kl_df('btc').tail()


Out[20]:
open close high low volume date pre_close date_week p_change key atr21 atr14
2017-08-05 19310.05 21191.00 21540.00 19113.03 23110 20170805 19339.00 5 9.577 499 1652.5121 1667.0629
2017-08-06 21198.00 21959.73 22490.00 21126.45 13821 20170806 21191.00 6 3.628 500 1788.7382 1864.9212
2017-08-07 21959.00 22200.00 22833.00 21258.00 12381 20170807 21959.73 0 1.094 501 1775.3984 1835.1984
2017-08-08 22200.00 22588.08 23398.96 21940.00 15933 20170808 22200.00 1 1.748 502 1746.6313 1785.0332
2017-08-09 22588.08 22380.01 23149.99 22360.00 4679 20170809 22588.08 2 -0.921 503 1674.2093 1673.6941

小结:

abupy内置的数据源仅供学习使用,abupy提供了接入外部数据源的接口和规范,推荐购买数据源接入使用,特别是在实盘中。

abu量化文档目录章节

  1. 择时策略的开发
  2. 择时策略的优化
  3. 滑点策略与交易手续费
  4. 多支股票择时回测与仓位管理
  5. 选股策略的开发
  6. 回测结果的度量
  7. 寻找策略最优参数和评分
  8. A股市场的回测
  9. 港股市场的回测
  10. 比特币,莱特币的回测
  11. 期货市场的回测
  12. 机器学习与比特币示例
  13. 量化技术分析应用
  14. 量化相关性分析应用
  15. 量化交易和搜索引擎
  16. UMP主裁交易决策
  17. UMP边裁交易决策
  18. 自定义裁判决策交易
  19. 数据源
  20. A股全市场回测
  21. A股UMP决策
  22. 美股全市场回测
  23. 美股UMP决策

abu量化系统文档教程持续更新中,请关注公众号中的更新提醒。

《量化交易之路》目录章节及随书代码地址

  1. 第二章 量化语言——Python
  2. 第三章 量化工具——NumPy
  3. 第四章 量化工具——pandas
  4. 第五章 量化工具——可视化
  5. 第六章 量化工具——数学:你一生的追求到底能带来多少幸福
  6. 第七章 量化系统——入门:三只小猪股票投资的故事
  7. 第八章 量化系统——开发
  8. 第九章 量化系统——度量与优化
  9. 第十章 量化系统——机器学习•猪老三
  10. 第十一章 量化系统——机器学习•ABU
  11. 附录A 量化环境部署
  12. 附录B 量化相关性分析
  13. 附录C 量化统计分析及指标应用

更多阿布量化量化技术文章

更多关于量化交易相关请阅读《量化交易之路》

更多关于量化交易与机器学习相关请阅读《机器学习之路》

更多关于abu量化系统请关注微信公众号: abu_quant