在实际操作中,其执行过程可以简单地描述为:投资者首先选择相互匹配的两个资产,当配对资产价格差异增加的时候,做多价格偏低的资产,同时做空价格偏高的资产,而当价格差异减小的时候,则结束头寸,完成交易;同时,为了控制风险,当价差进一步扩大时,需要在适当的止损点结束头寸。
所以,想开发一个配对交易的策略,核心有两个步骤:
1.找到待交易的标的。
比如说两个走势非常类似的股票或者其他证券。
2.对两者的价差建模。
假设是两者的价差会在一个稳定的区间波动(均值回归)。
————————————————
在以往的研究中,配对交易的标的的筛选方法有很多种,归纳起来大致有这两种:
- 最小化偏差平方和法则(最小距离法)
- 协整理论方法
今天,我们以ETF为例。
首先获取深交所的所有交易标的,剔除掉在今年才上市和已经退市的,筛选出深交所的所有ETF基金,然后通过相关性检验取出相关系数最强的一对cp进行配对交易。
具体执行如下:
1.先获取深交所的所有交易标的 。
import numpy as np
import pandas as pd
from gm.api import *
import matplotlib.pyplot as plt
set_token('xxxxxxxxxxxx')
#获取深圳交易所全部标的
data1=get_instruments(exchanges='SZSE',df=True)
#剔除掉在今年才上市的标的
data1=data1[data1['listed_date']<'2020-12-30']
#剔除掉今天之前退市的标的
data1=data1[data1['delisted_date']>'2021-08-30']
data1.index=range(len(data1))
data1
2.取出ETF基金。
b=pd.DataFrame()
symbol=[]
for i in range(len(data1)):
if 'ETF' in data1['sec_name'][i]:
print(data1['sec_name'][i])
symbol.append(data1['symbol'][i])
if len(b)==0:
b=data1[data1['sec_name']==str(""+data1['sec_name'][i]+"")]
else:
b=b.append(data1[data1['sec_name']==str(""+data1['sec_name'][i]+"")])
b
获取的部分ETF如下,一共114支。
3.获取这114支ETF的最近半年的历史数据代码。
这里理论上应该获取回测时间点前半年的数据出来研究,但这里暂且用今年前半年多的数据来研究,读者可以自行修改数据的时间参数。
data2=pd.DataFrame()
for i in b['symbol']:
history_data = history(symbol=i, frequency='1d', start_time='2021-01-28',end_time='2021-07-30', fields='close', adjust=ADJUST_PREV, df= True)
data2["'"+i+"'"]=history_data['close']
最终获取的数据如下,一共122个交易日,114支ETF。
4.由于数据量太大,这里取出前六支ETF,计算相关系数并画出热力图,如下所示:
5.根据相关系数进行排序,取出相关系数最强的十组进行“强行cp”,结果如下所示:
最终,根据数值选出的最佳配对为:SZSE.159801(广发国证半导体芯片ETF) 和SZSE.159995(华夏国证半导体芯片ETF) ,其收盘价数据变化对比如下:
经计算,两者在过去半年中的相关系数为**** 99.99% ,已是相当高了。我们接着再用配对交易的一般策略验证这对标的进行配对交易的成效。
————————————————
策略思想 :
获取两支ETF基金交易情况,如果停牌,则跳过。
计算前五分钟,两者收盘价差值,并计算差值的方差及平均值。
依据以上数据,构造差值的布林通道。
当价差上破布林上轨 ,做空价差(半仓)。
当价差下破布林下轨 ,做多价差(半仓)。
回测参数均设置为:
时间: 2021-01-01至2021-08-10
调仓频率: 1天
基准指数: 沪深300指数(SHSE.000300)
**标的:SZSE.159801(广发国证半导体芯片ETF)、SZSE.159995(华夏国证半导体芯片ETF)
滑点: 0.0001
手续费: 0.0001