配对交易(pair trading)现在还有人做吗?具体是怎么操作的?

如题。pair trading在90年代美国比较流行,不知道现在还有没有人用类似方法套利。还有在国内做的话怎么解决做空(short position)要收手续费的问题。
关注者
1370
被浏览
62700

25 个回答

目前在配对交易方面的研宄归纳起来大体有三种方法:

Ø 最小化偏差平方和法则(最小距离法)(Gatev,Goetzmann ,Rouwenhorst(1999))

他的论文中提到了一种非参数方法最小距离法。首先选择合适的形成期,也就是样本期,将股票价格进行标准化。然后计算标准化的股票价格序列的平方距离,用此距离来度量价差,即股票价格序列之间的错误定价程度。再设置合适的交易规则,选择平方距离最小的股票对进入交易期进行实证检验,当发现两支股票的标准化价格序列的差值超过了预先设定的临界值则进行交易,结果发现最小距离法能够盈利。

Ø 协整理论方法(Vidyamurthy(2004))

协整策略是在协整理论的基础上建立起来的,是目前使用最广泛的方法。很多金融变量的时间序列都是非平稳的,建立回归模型,可能出现伪回归的现象。但是协整描述的是非平稳时间序列之间存在的长期稳定均衡关系。所谓均衡是指这些序列的线性组合所得序列是平稳的,即序列的均值和方差为常数,协方差只与时间间隔有关。之所以会出现这种情况,是因为某些金融时间序列受到了共同经济因素影响,表现出趋同性。就是取两个标的,然后相关性检验->序列单整检验->同阶单整的进行协整检验->取相关性系数、均值和标准差计算两只标的目前的价差值->价差值符合开仓平仓条件的,做相应操作。

Ø 随机价差模型方法(Elliott,Van Der Hoek,Malcolm(2005))

均值回复特性,资产A、B价差C=A-B建模。文章提出通过卡尔曼滤波的方法估计模型参数,并且提供了两种计算参数的具体算法。

假设可观测的价差由白噪声和一个均值回复过程组成,这个均值回复过程是由一个潜在的状态变量x驱动,x遵循维纳过程:

y_t=x_t+\omega _t (1)

dx_t=k(\theta -x_t)dt+\sigma dB_t (2)

(1)称为观测方程,(2)称为状态方程,两个方程一同构成了一个状态空间模型。式中dB_t为标准布朗运动。\theta 是均值,K表示状态变量x回归其均值的速度。

7.8更新 - 我们发布了更加详细的接近paper质量的研究、思想以及Ricequant API的代码:

配对交易(Paper Version)

欢迎大家来做更详细的深入探讨。

Happy Coding & Happy Trading :)

------------------------

自己最近在看配对交易方面的资料,主要是看Pairs Trading (豆瓣)这本书。

看这本书的体会是配对交易利用的就是两支相关的股票价格的时间序列(股价时间序列为非平稳时间序列)可以通过线性组合得到一个新的平稳的时间序列(Engle和Granger将这一性质称为协整,他们也因此获得了03年的Nobel prize),利用平稳时间序列具有mean-reverting的性质来构造多空组合进行交易。

简单来说,进行配对交易的步骤如下:

1.发现可能具有协整性质的股票对。利用的方法为计算两只股票回报的相关系数,选出相关系数高的股票对。

2.一旦确定了可能具有协整性质的股票对,我们就可以利用统计学的方法来检验这些股票对是否真的具有协整的性质。在这一过程中我们就可以确定协整系数以及价差是否具有mean-reverting的行为。

3.最后我们需要确定策略的一些参数,比如利用多长的历史数据来确定股票对是否具有协整性质,当价差偏离均值多远时进场或退场等。

看完了书就尝试了在A股市场试一试(准确说是part 1和part 2, part 3讲的是risk abitrage pair还没看)。

首先选择适合交易的股票对,我是从tushare下载了机械板块的10支股票2012年全年的日线数据,然后利用python来计算两两之间的相关系数,选择相关系数最高的五对股票对再做augumented dickey-fuller test, 选取最有可能具有协整性质的股票对。在计算价差时我把价差用zScore进行了处理:

zScore =  \frac{spread - spread_{mean}}{spread_{variance}}

当zScore超过阈值后入场,因为价差是一个平稳的时间序列,所以当zScore回复到均值附近时平仓出场。

在计算每次对冲的头寸的时候,我们需要HedgeRatio,它的计算方法为对两只股票的时间序列做一个OLS,斜率即为HedgeRatio。

Python里面计算相关系数和做ADFT检验真的是蛮快的,有现成的库可以直接调用。

经过以上筛选 我选出的是厦工股份和晋亿实业。对这对股票对进行的Augumented Dickey-Fuller test检验的结果如下:
(-3.34830942527566, 0.0128523914172048, 0, 115, {'5%': -2.8870195216569412, '1%': -3.4885349695076844, '10%': -2.5803597920604915}, -11.392077815567461)

现在来解释一下几个比较重要的结果。第一个值-3.34830942527566为T-统计量,第二个值0.0128523914172048为p- value。Dictionary里面包含的内容为置信度为5%,1%和10%时的T-统计量的值。比如对于我所选择的股票对厦工股份和晋亿实业, T-统计量为-3.34830942527566,小于5%所对应的-2.8870195216569412,而且很接近1%所对应的-3.4885349695076844,那么很大可能我们发现了一个平稳的时间序列。

然后在RiceQuant - Beta上面进行了回测,回测时间为2013年全年,核心代码如下:

            //获取两只股票的日线数据
            double[] closePxInStockId1 = stats.get(stockId1).history(period + 1, HPeriod.Day).getClosingPrice();
            double[] closePxInStockId2 = stats.get(stockId2).history(period + 1, HPeriod.Day).getClosingPrice();
            //每次对冲的多头头寸控制为当前持有现金的0.6
            betShare = info.portfolio().getAvailableCash()*0.6/closePxInStockId2[199];  
            buyShare = beta*betShare;
           
            shareStock1 = info.position(stockId1).getNonClosedTradeQuantity();
            shareStock2 = info.position(stockId2).getNonClosedTradeQuantity();
            //计算两只股票之间的价差
            spread = closePxInStockId2[199] - beta*closePxInStockId1[199];
            //计算zScore
            zScore = (spread - mean)/std;
            informer.plot("zScore", zScore);

//当入场信号来的时候,进入市场 
            if ((zScore > 1.1  ) && (shareStock1 == 0) && (shareStock2 == 0)){              
                trans.sell(stockId2).shares(betShare).commit();
                trans.buy(stockId1).shares(buyShare).commit();
            }
            if ((zScore < -1.5) && (shareStock2 == 0) && (shareStock1 == 0)){
                trans.sell(stockId1).shares(buyShare).commit();
                trans.buy(stockId2).shares(betShare).commit();
            }
//当出场信号来的时候,离开市场
            if ((zScore < 0.8) && (zScore > -1.0) && (shareStock1 != 0) && (shareStock2 != 0) ){
                if (shareStock1 > 0){
                    trans.sell(stockId1).shares(shareStock1).commit();
                }
                if (shareStock1 < 0){
                    trans.buy(stockId1).shares(-shareStock1).commit();
                }   
                if (shareStock2 > 0){
                    trans.sell(stockId2).shares(shareStock2).commit();
                }
                if (shareStock2 < 0){
                    trans.buy(stockId2).shares(-shareStock2).commit();
                   
                }
            }           
        });
    }
}>


进行了一系列的运算...

结果看上去不错,Sharp Ratio 2.12,Max Drawdown 7.80%, 回测收益36.05%.
接着加入一个优化策略,即设计一个止损策略。加入的止损策略很简单:如果连续亏损达到四天以上,则平仓退场。加入的代码如下:
            if (dailyReturn < 0){
                count = count + 1;
            }
            if (count > 4){
               if (shareStock1 > 0){
                    trans.sell(stockId1).shares(shareStock1).commit();
                    }
               if (shareStock1 < 0){
                   trans.buy(stockId1).shares(-shareStock1).commit();
                }   
                if (shareStock2 > 0){
                    trans.sell(stockId2).shares(shareStock2).commit();
                }
                if (shareStock2 < 0){
                    trans.buy(stockId2).shares(-shareStock2).commit();
                }
                count = 0;
            }


这时候再次进行回测,结果如下:
Max Drawdown降低为6.650%。Max Drawdown降低的并不多,但是Sharp Ratio提高到了2.34,回测收益也提高到了41.80%。

最后把回测时间延长一年到14年底,我们知道14年底本轮牛市开始启动。
从回测收益曲线上可以看出,直到14年11月初策略表现还是不错的,14年11月之后到年底,收益直接从正的50%左右降到-28%左右。而大盘也正是从14年11月开始出现明显的向上趋势。这表明单边行情可能不适合配对交易。

欢迎访问注册登录 RiceQuant - Beta 之后就可以开始量化回测研究之旅,策略完整代码在这里:配对交易(Revised Version)