作者: 阿布
阿布量化版权所有 未经允许 禁止转载
abu量化系统github地址 (欢迎+star)
交易目标之间的相关性分析是量化交易中一个非常重要的工具,本节将示例abupy中相关分析模块的使用示例:
首先导入abupy中本节使用的模块:
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
# 使用沙盒数据,目的是和书中一样的数据环境
abupy.env.enable_example_env_ipython()
In [2]:
from abupy import abu, ml, nd, tl, ECoreCorrType, ABuSymbolPd, ABuScalerUtil, AbuFuturesCn, ABuCorrcoef
from abupy import find_similar_with_cnt, find_similar_with_se, find_similar_with_folds
from abupy import EMarketTargetType, ABuStatsUtil, ABuSimilar, ABuIndustries
受限于沙盒中数据限制,本节示例的相关性分析只限制在abupy内置沙盒数据中,首先将内置沙盒中美股,A股,港股, 比特币,莱特币,期货市场中的symbol都列出来:
In [3]:
us_choice_symbols = ['usTSLA', 'usNOAH', 'usSFUN', 'usBIDU', 'usAAPL', 'usGOOG', 'usWUBA', 'usVIPS', 'us.IXIC']
cn_choice_symbols = ['002230', '300104', '300059', '601766', '600085', '600036', '600809', '000002', '002594', '002739', 'sh000001']
hk_choice_symbols = ['hk03333', 'hk00700', 'hk02333', 'hk01359', 'hk00656', 'hk03888', 'hk02318', 'hkHSI']
tc_choice_symbols = ['btc', 'ltc']
# 期货市场的直接从AbuFuturesCn().symbo中读取
ft_choice_symbols = AbuFuturesCn().symbol.tolist()
all_choice_symbols = us_choice_symbols + cn_choice_symbols + hk_choice_symbols + tc_choice_symbols +ft_choice_symbols
len(all_choice_symbols)
Out[3]:
如上所示abupy内置沙盒中的symbol共75个,下面组装这75个symbol形成一个三维panel数据,摘取所有数据的p_change(涨跌幅)列形成二维dataframe对象,如下所示:
In [4]:
panel = ABuSymbolPd.make_kl_df(all_choice_symbols, start='2015-07-27', end='2016-07-26',
show_progress=True)
# 转换panel轴方向,即可方便获取所有金融时间数据的某一个列
panel = panel.swapaxes('items', 'minor')
net_cg_df = panel['p_change'].fillna(value=0)
net_cg_df.head()
Out[4]:
In [5]:
ABuCorrcoef.corr_xy(net_cg_df.btc, net_cg_df['601766'], similar_type=ECoreCorrType.E_CORE_TYPE_PEARS)
Out[5]:
上面通过默认参数获取601766与比特币的相关度,数值为-0.04,可以通过关键子参数similar_type来切换相关的计算方法,如下使用E_CORE_TYPE_SPERM:
In [6]:
ABuCorrcoef.corr_xy(net_cg_df.btc, net_cg_df['601766'], similar_type=ECoreCorrType.E_CORE_TYPE_SPERM)
Out[6]:
下面使用E_CORE_TYPE_SIGN,sign的相关度度量,只关注符号,不关心具体数据,即比如今天比特币涨,那只要601766今天也涨就正相关,不会理会具体涨多少,实际上这种度量方式更适合交易类型产品:
In [7]:
ABuCorrcoef.corr_xy(net_cg_df.btc, net_cg_df['601766'], similar_type=ECoreCorrType.E_CORE_TYPE_SIGN)
Out[7]:
下面使用时间加权相关E_CORE_TYPE_ROLLING,进行计算,即时间上越早的相关值所占权重越小,时间上越晚的相关值权重越大:
In [8]:
ABuCorrcoef.corr_xy(net_cg_df.btc, net_cg_df['601766'], similar_type=ECoreCorrType.E_CORE_TYPE_ROLLING)
Out[8]:
上面的corr_xy的接口参数只能是两个品种的相关度度量,如果想要从上面net_cg_df的75种品种中找到与比特币最相关的品种很麻烦,使用corr_matrix接口可以一次输出计算:
In [9]:
corr_df = ABuCorrcoef.corr_matrix(net_cg_df, )
corr_df.btc.sort_values()[::-1][:10]
Out[9]:
corr_matrix接口同样支持关键字参数similar_type,如下使用E_CORE_TYPE_SIGN:
In [10]:
corr_df = ABuCorrcoef.corr_matrix(net_cg_df, similar_type=ECoreCorrType.E_CORE_TYPE_SIGN)
corr_df.btc.sort_values()[::-1][:10]
Out[10]:
上面输出的都是正相关的top10,发现除了ltc(莱特币)外,其它的相关度也都在0附近,都没有超过0.1,即都基本无关,实际上不管是正相关还是负相关都成为可以有用的素材,下面看一下时间加权相关的top10负相关的品种:
In [11]:
corr_df = ABuCorrcoef.corr_matrix(net_cg_df, ECoreCorrType.E_CORE_TYPE_ROLLING)
corr_df.btc.sort_values()[:10]
Out[11]:
如上所示负相关的数值有几个已经上到0.1以上了,但是由于沙盒数据中的交易品种所限,并没有找到适合构成特征(强正相关,或者强负相关)的品种。
备注:之后的章节在使用非沙盒数据的前提下,会编写在完整的各个全市场中寻找与比特币最强正相关,最强负相关的示例,以及通过它们构成特征,实现策略的优化
In [12]:
ABuStatsUtil.euclidean_distance_xy(net_cg_df.btc, net_cg_df.ltc)
Out[12]:
上面的接口度量了比特币和莱特币之间的欧式距离(L2范数),下面度量曼哈顿距离(L1范数):
In [13]:
ABuStatsUtil.manhattan_distances_xy(net_cg_df.btc, net_cg_df.ltc)
Out[13]:
下面度量余弦距离:
In [14]:
ABuStatsUtil.cosine_distances_xy(net_cg_df.btc, net_cg_df.ltc)
Out[14]:
上面接口cosine_distances_xy度量了比特币和莱特币之间的余弦距离,0.23为距离的度量值,距离和相似度之间可以通过关键字参数to_similar=True将余弦距离直接转换为余弦相似度,如下所示:
In [15]:
ABuStatsUtil.cosine_distances_xy(net_cg_df.btc, net_cg_df.ltc, to_similar=True)
Out[15]:
和相似度接口类似,xy接口只能两个直接度量,通过matrix接口可实现矩阵的度量,如下所示:
In [16]:
euclidean_df = ABuStatsUtil.euclidean_distance_matrix(net_cg_df)
euclidean_df.btc.sort_values()[:10]
Out[16]:
可以看到与比特币距离最短的是莱特币,同时可以通to_similar=True将距离度量值转换为相似度,如下所示:
In [17]:
manhattan_df = ABuStatsUtil.euclidean_distance_matrix(net_cg_df, to_similar=True)
manhattan_df.btc.sort_values()[::-1][:10]
Out[17]:
上面度量了欧式距离(L2范数),下面度量曼哈顿距离(L1范数)的matrix接口:
In [18]:
manhattan_df = ABuStatsUtil.manhattan_distance_matrix(net_cg_df, to_similar=True)
manhattan_df.btc.median()
Out[18]:
上面度量结果的中位数,值为0.37,很高,因为L1范数和L2范数针对相似度的度量只是相对的,只在数据范围内,数据之间进行数据比较统计的意义不大,如上ltc的值和WHO差不多大,余弦距离与它们不同,如下示例,可以看到ltc与usTSLA数值差别很大:
In [19]:
cosine_df = ABuStatsUtil.cosine_distance_matrix(net_cg_df, to_similar=True)
cosine_df.btc.sort_values()[::-1][:10]
Out[19]:
备注:与上述接口的使用类似,通过ABuScalerUtil.scaler_xy针对两组矢量进行标准化,通过ABuScalerUtil.scaler_matrix针对矩阵进行标准化。
In [20]:
abupy.env.g_market_target = EMarketTargetType.E_MARKET_TARGET_CN
similar_dict = find_similar_with_cnt('600036', 252)
上面的接口使用的是find_similar_with_cnt,参数252为天数,即度量最近一年的相关性,下面切换市场为港股市场,接口使用find_similar_with_se参数通过start,end进行设置时间,关键字参数corr_type代表度量相关算法,使用查看hk02333与港股市场的相关性:
In [21]:
abupy.env.g_market_target = EMarketTargetType.E_MARKET_TARGET_HK
_ = find_similar_with_se('hk02333', start='2016-07-26', end='2017-07-26', corr_type=ECoreCorrType.E_CORE_TYPE_PEARS)
下面的市场继续在港股市场,但参数symbol使用比特币,即度量的结果为比特币与港股市场的相关性:
In [22]:
_ = find_similar_with_cnt('btc', 252, corr_type=ECoreCorrType.E_CORE_TYPE_PEARS)
下面的市场继续在港股市场,但接口使用find_similar_with_folds,参数参数n_folds代表年数,symbol使用比特币,corr_type使用时间加权相关度量,如下所示:
In [23]:
_ = find_similar_with_folds('btc', n_folds=1, corr_type=ECoreCorrType.E_CORE_TYPE_ROLLING)
上面的接口通过corr_type来切好相关度度量算法,如果想使用多种度量算法,同时度量,可以使用calc_similar接口,使用如下所示:
In [25]:
abupy.env.g_market_target = EMarketTargetType.E_MARKET_TARGET_CN
rank_score, _ = tl.similar.calc_similar('600036', '601766', corr_jobs=(ECoreCorrType.E_CORE_TYPE_PEARS,
ECoreCorrType.E_CORE_TYPE_SPERM), show=False)
rank_score
Out[25]:
上面使用E_CORE_TYPE_PEARS和E_CORE_TYPE_SPERM共同做为度量算法,下面使用+-号相关和时间加权相关,如下所示:
In [29]:
abupy.env.g_market_target = EMarketTargetType.E_MARKET_TARGET_CN
rank_score, _ = tl.similar.calc_similar('600036', '601766', corr_jobs=(ECoreCorrType.E_CORE_TYPE_ROLLING, ECoreCorrType.E_CORE_TYPE_ROLLING), show=False)
rank_score
Out[29]:
观察上面的输出值都很高,通过corr_xy度量两支股票的相关度只有0.458,如下所示:
In [30]:
ABuCorrcoef.corr_xy(net_cg_df['600036'], net_cg_df['601766'])
Out[30]:
实际上ABuTLSimilar.calc_similar()度量的是两支股票相对整个市场的相关性评级,它不关心某一个股票具体相关性的数值的大小,calc_similar(a, b) 的工作流程如下:
即ABuTLSimilar.calc_similar返回值由0至1,这样的好处是通过计算600036与601766在所有股票中的相似度水平,会更全局客观的体现相关性。
下面calc_similar的show=True进行可视化,它可视化了两支股票的价格距离,如下所示:
In [31]:
rank_score, _ = tl.similar.calc_similar('600036', '601766', show=True)
In [52]:
pd.options.display.max_rows = 100
pd.options.display.max_columns = 100
# 找到与600036处在一个行业中的所有股票, 返回dataframe对象
industries, _ = ABuIndustries.industries_df('600036')
# 输出显示后5个股票信息
industries.tail()
Out[52]:
自然相关性来自人为的对行业进行分类,可以通过industries_factorize获取某个市场中所有行业分类信息,如下获取港股市场中所有行业:
In [44]:
ABuIndustries.industries_factorize(market=EMarketTargetType.E_MARKET_TARGET_HK)
Out[44]:
如果你对上面行业分类中的序号6:赌场与赌博,序号9:中国房地产,比较感兴趣,可以使用如下方式查询这两个行业中的所有股票信息:
In [56]:
# 6:赌场与赌博,序号9:中国房地产 只显示后5支股票信息
ABuIndustries.query_factorize_industry_df([6, 9], market=EMarketTargetType.E_MARKET_TARGET_HK).tail()
Out[56]:
如果你在回测中想使用比如上面两个分类中的所有股票进行回测,可以使用如下接口获取行业中所有股票symbol序列:
In [57]:
ABuIndustries.query_factorize_industry_symbol([6, 9], market=EMarketTargetType.E_MARKET_TARGET_HK)[:5]
Out[57]:
如果已经有了想要查询的具体行业目标,比如想要从A股市场中模糊查询医学相关的股票,可以使用如下接口:
In [61]:
# 从A股市场中查询医学相关的股票显示前5个
ABuIndustries.query_match_industries_df('医学', market=EMarketTargetType.E_MARKET_TARGET_CN).head()
Out[61]:
如果从A股市场中模糊查询医学相关所有股票进行回测,可以使用如下接口获取行业中所有股票symbol序列:
In [50]:
ABuIndustries.query_match_industries_symbol('医学', market=EMarketTargetType.E_MARKET_TARGET_CN)[:5]
Out[50]:
小节:
abu量化系统文档教程持续更新中,请关注公众号中的更新提醒。
更多关于量化交易相关请阅读《量化交易之路》
更多关于量化交易与机器学习相关请阅读《机器学习之路》
更多关于abu量化系统请关注微信公众号: abu_quant