Skip to content

Commit

Permalink
索引, 国际期货市场的回测, 内置沙盒数据融入国际期货
Browse files Browse the repository at this point in the history
  • Loading branch information
bbfamily committed Aug 25, 2017
1 parent 52fe8fb commit f8e0cb2
Show file tree
Hide file tree
Showing 43 changed files with 462 additions and 60 deletions.
12 changes: 11 additions & 1 deletion abupy/CoreBu/ABuEnv.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,10 @@ class EMarketSourceType(Enum):
"""新浪 美股"""
E_MARKET_SOURCE_sn_us = 3

"""新浪 期货"""
"""新浪 国内期货"""
E_MARKET_SOURCE_sn_futures = 100
"""新浪 国际期货"""
E_MARKET_SOURCE_sn_futures_gb = 101

"""火币 比特币,莱特币"""
E_MARKET_SOURCE_hb_tc = 200
Expand Down Expand Up @@ -214,6 +216,14 @@ class EMarketSubType(Enum):
ZZCE = 'ZZCE'
"""上海期货交易所SHFE'"""
SHFE = 'SHFE'

"""伦敦金属交易所"""
LME = 'LME'
"""芝加哥商品交易所"""
CBOT = 'CBOT'
"""纽约商品交易所"""
NYMEX = 'NYMEX'

"""币类子市场COIN'"""
COIN = 'COIN'

Expand Down
35 changes: 34 additions & 1 deletion abupy/MarketBu/ABuDataFeed.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
from ..CoreBu import ABuEnv
from ..MarketBu import ABuNetWork
from ..MarketBu.ABuDataBase import StockBaseMarket, SupportMixin, FuturesBaseMarket, TCBaseMarket
from ..MarketBu.ABuDataParser import BDParser, TXParser, NTParser, SNUSParser, SNFuturesParser, HBTCParser
from ..MarketBu.ABuDataParser import BDParser, TXParser, NTParser, SNUSParser
from ..MarketBu.ABuDataParser import SNFuturesParser, SNFuturesGBParser, HBTCParser
from ..UtilBu import ABuStrUtil, ABuDateUtil, ABuMd5
from ..CoreBu.ABuDeprecated import AbuDeprecated
# noinspection PyUnresolvedReferences
Expand Down Expand Up @@ -339,6 +340,38 @@ def kline(self, n_folds=2, start=None, end=None):
return FuturesBaseMarket._fix_kline_pd(kl_df, n_folds, start, end)


class SNFuturesGBApi(FuturesBaseMarket, SupportMixin):
"""sn futures数据源,支持国际期货"""

K_NET_BASE = "http:https://stock2.finance.sina.com.cn/futures/api/jsonp.php/" \
"var %s%s=/GlobalFuturesService.getGlobalFuturesDailyKLine?symbol=%s&_=%s"

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

def _support_market(self):
"""声明数据源支持期货数据, 支持国际期货市场"""
return [EMarketTargetType.E_MARKET_TARGET_FUTURES_GLOBAL]

def kline(self, n_folds=2, start=None, end=None):
"""日k线接口"""
today = ABuDateUtil.current_str_date().replace('-', '_')
url = SNFuturesGBApi.K_NET_BASE % (self._symbol.symbol_code, today, self._symbol.symbol_code, today)
data = ABuNetWork.get(url=url, timeout=(10, 60))
text = data.text
# 返回的是Javascript字符串解析出dict
js_dict = ABuNetWork.parse_js(text[text.find('=(') + 2:text.rfind(')')])
kl_df = self.data_parser_cls(self._symbol, js_dict).df
if kl_df is None:
return None
return FuturesBaseMarket._fix_kline_pd(kl_df, n_folds, start, end)


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

Expand Down
26 changes: 26 additions & 0 deletions abupy/MarketBu/ABuDataParser.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,32 @@ def __init__(self, symbol, json_dict):
self.volume = [item[5] for item in data]


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


@AbuDataParseWrap()
class HBTCParser(object):
"""示例币类市场数据源解析类,被类装饰器AbuDataParseWrap装饰"""
Expand Down
3 changes: 2 additions & 1 deletion abupy/MarketBu/ABuDataSource.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import numpy as np

from ..MarketBu.ABuDataBase import BaseMarket
from ..MarketBu.ABuDataFeed import BDApi, TXApi, NTApi, HBApi, SNUSApi, SNFuturesApi
from ..MarketBu.ABuDataFeed import BDApi, TXApi, NTApi, HBApi, SNUSApi, SNFuturesApi, SNFuturesGBApi
from .ABuSymbol import Symbol
from .ABuSymbol import code_to_symbol
from ..CoreBu import ABuEnv
Expand All @@ -36,6 +36,7 @@ class HDF5ExtError(RuntimeError):
EMarketSourceType.E_MARKET_SOURCE_nt.value: NTApi,
EMarketSourceType.E_MARKET_SOURCE_sn_us.value: SNUSApi,
EMarketSourceType.E_MARKET_SOURCE_sn_futures.value: SNFuturesApi,
EMarketSourceType.E_MARKET_SOURCE_sn_futures_gb.value: SNFuturesGBApi,
EMarketSourceType.E_MARKET_SOURCE_hb_tc.value: HBApi}


Expand Down
14 changes: 12 additions & 2 deletions abupy/MarketBu/ABuMarket.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
from ..CoreBu.ABuFixes import KFold, six
from ..UtilBu.ABuLazyUtil import LazyFunc
from ..MarketBu.ABuSymbol import Symbol, code_to_symbol
from ..MarketBu.ABuSymbolFutures import AbuFuturesCn
from ..MarketBu.ABuSymbolFutures import AbuFuturesCn, AbuFuturesGB
from ..MarketBu.ABuSymbolStock import AbuSymbolCN, AbuSymbolUS, AbuSymbolHK

__author__ = '阿布'
Expand Down Expand Up @@ -173,12 +173,20 @@ def _all_hk_symbol(index=False):

def _all_futures_cn():
"""
AbuFuturesCn().symbol获取期货symbol代码,注意这里只取连续合约代码
AbuFuturesCn().symbol获取国内期货symbol代码,注意这里只取连续合约代码
:return:
"""
return AbuFuturesCn().symbol


def _all_futures_gb():
"""
AbuFuturesGB().symbol获取国际期货symbol代码,LME,CBOT,COMEX
:return:
"""
return AbuFuturesGB().symbol


def _all_tc_symbol():
"""
获取币类symbol,注意这里只取比特币与莱特币,可自行扩展其它币种
Expand Down Expand Up @@ -208,6 +216,8 @@ def all_symbol(market=None, ss=False, index=False, value=True):
symbols = _all_hk_symbol(index)
elif market == EMarketTargetType.E_MARKET_TARGET_FUTURES_CN:
symbols = _all_futures_cn()
elif market == EMarketTargetType.E_MARKET_TARGET_FUTURES_GLOBAL:
symbols = _all_futures_gb()
elif market == EMarketTargetType.E_MARKET_TARGET_TC:
symbols = _all_tc_symbol()
else:
Expand Down
15 changes: 10 additions & 5 deletions abupy/MarketBu/ABuSymbol.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,14 @@ def code_to_symbol(code):
:param code: str对象,代码 如:300104,sz300104,usTSLA
:return: Symbol对象
"""
from ..MarketBu.ABuSymbolFutures import AbuFuturesCn
from ..MarketBu.ABuSymbolFutures import AbuFuturesCn, AbuFuturesGB
from ..MarketBu.ABuSymbolStock import AbuSymbolCN, AbuSymbolUS
from ..MarketBu.ABuMarket import all_symbol

if not isinstance(code, six.string_types):
# code必须是string_types
raise TypeError('code must be string_types!!!,{} : type is {}'.format(code, type(code)))

if len(code) < 2:
# code的长度必须 > 2
raise ValueError('arg code :{} len < 2is error'.format(code))

sub_market = None
market = None
# 尝试获取市场信息
Expand Down Expand Up @@ -79,6 +75,13 @@ def code_to_symbol(code):
market = EMarketTargetType.E_MARKET_TARGET_TC
sub_market = EMarketSubType.COIN
return Symbol(market, sub_market, code)
elif code.isalpha() and code.upper() in all_symbol(EMarketTargetType.E_MARKET_TARGET_FUTURES_GLOBAL):
# 全字母且匹配国际期货市场
futures_gb_code = code.upper()
q_df = AbuFuturesGB().query_symbol(futures_gb_code)
sub_market = EMarketSubType(q_df.exchange.values[0])
market = EMarketTargetType.E_MARKET_TARGET_FUTURES_GLOBAL
return Symbol(market, sub_market, futures_gb_code)
elif code.isalpha() or (code.startswith('.') and code[1:].isalpha()):
# 全字母进行美股大盘匹配或者美股股票匹配
stock_code = code.upper()
Expand Down Expand Up @@ -234,6 +237,8 @@ class IndexSymbol(object):

# 国内期货只是使用黄金做为时间标尺,不具备对比大盘作用
BM_FUTURES_CN = Symbol(EMarketTargetType.E_MARKET_TARGET_FUTURES_CN, EMarketSubType.SHFE, 'AU0')
# 国际期货只是使用纽约黄金做为时间标尺,不具备对比大盘作用
BM_FUTURES_GB = Symbol(EMarketTargetType.E_MARKET_TARGET_FUTURES_GLOBAL, EMarketSubType.NYMEX, 'GC')

# 币类只是使用btc做为时间标尺,不具备对比大盘作用
TC_INX = Symbol(EMarketTargetType.E_MARKET_TARGET_TC, EMarketSubType.COIN, 'btc')
106 changes: 103 additions & 3 deletions abupy/MarketBu/ABuSymbolFutures.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,20 @@
__weixin__ = 'abu_quant'

_rom_dir = ABuEnv.g_project_rom_data_dir
"""文件定期重新爬取,更新"""
"""国内期货symbol文件,文件定期重新爬取,更新"""
_stock_code_futures_cn = os.path.join(_rom_dir, 'futures_cn.csv')

"""国际期货symbol文件,文件定期重新爬取,更新"""
_stock_code_futures_gb = os.path.join(_rom_dir, 'futures_gb.csv')


@singleton
class AbuFuturesCn(FreezeAttrMixin):
"""AbuFuturesCn单例,混入FreezeAttrMixin在__init__中冻结了接口,外部只可以读取"""
"""国内期货symbol数据,AbuFuturesCn单例,混入FreezeAttrMixin在__init__中冻结了接口,外部只可以读取"""

def __init__(self):
"""
self.hk_unit_df表结构如下所示:列分别为
self.futures_cn_df表结构如下所示:列分别为
symbol product min_deposit min_unit commission exchange
0 V0 PVC 0.07 5 2.0 DCE
Expand Down Expand Up @@ -142,6 +145,103 @@ def exchange(self):
"""代理获取futures_cn_df.exchange,LazyFunc"""
return self.futures_cn_df.exchange


# TODO 提取AbuFutures基类,删除重复代码
@singleton
class AbuFuturesGB(FreezeAttrMixin):
"""国际期货数据,AbuFuturesGB单例,混入FreezeAttrMixin在__init__中冻结了接口,外部只可以读取"""

def __init__(self):
"""
self.futures_gb_df表结构如下所示:列分别为
symbol product min_deposit min_unit exchange
0 NID 伦敦镍 0.07 6 LME
1 PBD 伦敦铅 0.10 25 LME
2 SND 伦敦锡 0.05 5 LME
3 ZSD 伦敦锌 0.10 25 LME
4 AHD 伦敦铝 0.08 25 LME
5 CAD 伦敦铜 0.08 25 LME
"""
# 读取本地csv到内存
self.futures_gb_df = pd.read_csv(_stock_code_futures_gb, index_col=0)
# __init__中使用FreezeAttrMixin._freeze冻结了接口
self._freeze()

def __str__(self):
"""打印对象显示:futures_cn_df.info, futures_cn_df.describe"""
return 'info:\n{}\ndescribe:\n{}'.format(self.futures_gb_df.info(),
self.futures_gb_df.describe())

__repr__ = __str__

def __len__(self):
"""对象长度:futures_cn_df.shape[0],即行数"""
return self.futures_gb_df.shape[0]

def __contains__(self, item):
"""成员测试:item in self.futures_cn_df.columns,即item在不在futures_cn_df的列中"""
return item in self.futures_gb_df.columns

def __getitem__(self, key):
"""索引获取:套接self.futures_cn_df[key]"""
if key in self:
return self.futures_gb_df[key]
# 不在的话,返回整个表格futures_cn_df
return self.futures_gb_df

def __setitem__(self, key, value):
"""索引设置:对外抛出错误, 即不准许外部设置"""
raise AttributeError("AbuFuturesGB set value!!!")

def query_symbol(self, symbol):
"""
对外查询接口
:param symbol: 可以是Symbol对象,也可以是symbol字符串对象
"""
if isinstance(symbol, Symbol):
symbol = symbol.value
if symbol in self.symbol.values:
return self.futures_gb_df[self.futures_gb_df.symbol.values == symbol]
return None

def query_min_unit(self, symbol):
"""
对query_symbol的查询一手单位的近一部函数封装
:param symbol: 可以是Symbol对象,也可以是symbol字符串对象
"""
min_cnt = 10
# 查询最少一手单位
q_df = self.query_symbol(symbol)
if q_df is not None:
min_cnt = q_df.min_unit.values[0]
return min_cnt

@LazyFunc
def symbol(self):
"""代理获取futures_gb_df.symbol,LazyFunc"""
return self.futures_gb_df.symbol

@LazyFunc
def product(self):
"""代理获取futures_gb_df.product,LazyFunc"""
return self.futures_gb_df.product

@LazyFunc
def min_deposit(self):
"""代理获取futures_gb_df.min_deposit,LazyFunc"""
return self.futures_gb_df.min_deposit

@LazyFunc
def min_unit(self):
"""代理获取futures_gb_df.min_unit,LazyFunc"""
return self.futures_gb_df.min_unit

@LazyFunc
def exchange(self):
"""代理获取futures_gb_df.exchange,LazyFunc"""
return self.futures_gb_df.exchange

"""由于封装对外所以不使用模块单例"""
# """模块单例"""
# futures_cn = AbuFuturesCn()
3 changes: 2 additions & 1 deletion abupy/MarketBu/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from .ABuSymbol import IndexSymbol, Symbol, code_to_symbol
from . import ABuSymbol
from ..MarketBu.ABuSymbolStock import AbuSymbolCN, AbuSymbolUS, AbuSymbolHK
from .ABuSymbolFutures import AbuFuturesCn
from .ABuSymbolFutures import AbuFuturesCn, AbuFuturesGB
from .ABuHkUnit import AbuHkUnit
from . import ABuMarket
from .ABuMarket import MarketMixin
Expand All @@ -27,6 +27,7 @@
'get_price',
'ABuSymbol',
'AbuSymbolCN',
'AbuFuturesGB',
'AbuSymbolUS',
'AbuSymbolHK',
'AbuFuturesCn',
Expand Down
Binary file modified abupy/RomDataBu/df_kl.h5.zip
Binary file not shown.
5 changes: 4 additions & 1 deletion abupy/SimilarBu/ABuCorrcoef.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,11 +162,14 @@ def rolling_corr(df, ss=None, window=g_rolling_corr_window):
"""
corr = 0
if ss is None:
# 如果不使用pd_rolling_corr,需要copy,保证df == np.inf的会修改
df = df.copy()
df[df == np.inf] = 0
# 迭代rolling_window下的时间窗口,使用np.corrcoef,比使用pd_rolling_corr效果高很多
for (s, e) in rolling_window:
# eg. rolling_window第一个即为np.corrcoef(df.iloc[0:60].T)
window_corr = np.corrcoef(df.iloc[s:e].T)
window_corr[window_corr == np.inf] = 0
window_corr[(window_corr == np.inf) | (window_corr == np.nan)] = 0
# 当前窗口下的相关系数乘以权重, window_corr * weights[s]为df.shape[1]大小的相关系数二维方阵
corr += window_corr * weights[s]
else:
Expand Down
4 changes: 2 additions & 2 deletions abupy/SimilarBu/ABuSimilar.py
Original file line number Diff line number Diff line change
Expand Up @@ -410,8 +410,8 @@ def multi_corr_df(corr_jobs, cmp_cnt=252, n_folds=None, start=None, end=None):
# 美股期权暂时也以IXIC做为标尺
benchmark = IndexSymbol.IXIC
elif ABuEnv.g_market_target == EMarketTargetType.E_MARKET_TARGET_FUTURES_GLOBAL:
# 国际期货暂时也以BM_FUTURES_CN做为标尺
benchmark = IndexSymbol.BM_FUTURES_CN
# 国际期货暂时也以BM_FUTURES_GB做为标尺
benchmark = IndexSymbol.BM_FUTURES_GB
else:
# 没匹配上也不抛错误,随便给一个,因为这里要的benchmark主要目的只是做为时间标尺
benchmark = IndexSymbol.IXIC
Expand Down
4 changes: 2 additions & 2 deletions abupy/TradeBu/ABuBenchmark.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ def __init__(self, benchmark=None, start=None, end=None, n_folds=2, rs=True):
# 美股期权暂时也以IXIC做为标尺,最好是外部参数中的benchmark设置
benchmark = IndexSymbol.IXIC
elif ABuEnv.g_market_target == EMarketTargetType.E_MARKET_TARGET_FUTURES_GLOBAL:
# 国际期货暂时也以BM_FUTURES_CN做为标尺,最好是外部参数中的benchmark设置
benchmark = IndexSymbol.BM_FUTURES_CN
# 国际期货暂时也以BM_FUTURES_GB做为标尺
benchmark = IndexSymbol.BM_FUTURES_GB
else:
raise TypeError('benchmark is None AND g_market_target ERROR!')

Expand Down
Loading

0 comments on commit f8e0cb2

Please sign in to comment.