轮动是一种统计套利的变形。本文试图从最简单的统计套利推演到我们常用的轮动模型,以期对轮动有更深入的理解。
一、从最简化的统计套利说起
我们假定有两个时间序列a和b,这两个序列高度相关,且价差序列a-b具有均值回归的特性,为简化起见假设均值为0,那么,我们可以观察a-b的变化,在a-b小于0时多a空b, 在a-b大于0时多b空a, 这就是最简化的统计套利模型。
为了更直观的理解,我们撸一遍代码。先构建一个随机游走的时间序列a, 起始价格为1,日波动标准差为0.01。
接下来,再构建一个以0为中心的均值回归序列:
最后,把前面两个序列加起来,得到序列b。把这两个序列放一起,如下所示,我们就得到了两条高度相关的、可进行套利操作的序列。
接下来,我们构建一个经典的统计套利策略,我们观察a-b价差序列,发现大部分时间在[-0.02,0.02]之间波动,我们就马后炮地选择在-0.02的时候多a空b, 在0.02的时候多b空a,在穿越零值的时候平仓。
我们发现,我们的马后炮套利非常成功,净值呈45度角一路上升,感觉造个印钞机跟玩儿似的。别做梦了,这只是极度简化的理论模型,让我们往现实靠近一步,考虑更为普遍的情况,万一没有做空手段或做空成本太高呢?
二、向现实妥协的搬砖模型
现实中,收益往往需要用风险来交换,如果存在可观的价差空间,几乎可以肯定是由于无风险套利渠道不畅造成的,最常见的情况就是至少有一条腿是无法做空的。这时,我们还有个替代的模型叫搬砖。简单来说就是只做一条腿,哪个价格低就做多哪个,由于无法通过做空来对冲,需要承受标的价格下跌的风险。
我们来看看搬砖模型的表现:
可以看到,搬砖模型虽然也有超额收益,但由于叠加了多头走势,在标的趋势向下的情况下,搬砖模型也会遭遇很大的回撤。那么,有没有办法减小回撤呢?我们马上想到了资产组合理论,同时交易很多低相关的资产可以降低回撤。
三、组合搬砖模型
接下来,我们假设可以找到100组这样的序列对,对每组序列上面进行搬砖交易, 然后把收益曲线组合在一起。
我们惊奇地发现,组合起来的收益呈非常完美的指数向上走势。其实大可不必惊讶,因为我们随机生成的这100个组合之间是完全无关的,即相关性为0,按投资组合理论确实可以得到这样完美的结果。
接下来我们想一想还有没有优化空间?我们在生成a、b两组序列时,a序列是随机游走的,而b序列则是在a的基础上叠加了一个均值回归的走势。从逻辑上分析,对于随机游走的序列是不存在可获利策略的,那么所有的收益来源只可能在b序列上。为证实我们的猜想,我们把上一步计算中得到的pnl_a和pnl_b分开来看一下。
下图是pnl_a的累计曲线。
下图是pnl_b的累计曲线。
我们的猜想是正确的,在搬砖模型组合中,a序列组不贡献收益,而b序列组则持续贡献超额收益,也就是说,我们只需要对b序列组进行操作,而a序列组由于是随机游走的,其综合收益最终会因足够分散而接近于0。
我们再来向现实靠近一步。在现实中,我我们一般只能从逻辑上推测价差一定回归,但很难提前预知价差的波动范围,从而难以实现如上所示的搬砖套利。但如果我们能合理假定很多个价差组合一定程度上具有同质性,我们就可以用价差的相对大小来衡量价差回归的胜率和赔率,从而可以不需要确定的价差阈值,而只是根据价差来选择相对最优的标的。终于,我们来到了本文的主角,轮动模型。
四、轮动模型
我们对上面的搬砖组合做个变形,只做b序列的部分。在b序列的信号生成时,不再是设置b-a在某个阈值区间做多,而是比较各个b-a价差在横截面上的相对大小,选择价差最小的几组b序列单向做多,即可获取统计套利的收益。当组合数量足够多时,a序列的波动风险将可以被分散到最小。
这部分的回测大家比较熟悉了,我们直接给出回测结果。
进一步向现实靠拢,a序列之间的相关性不可能是0,反而是高度相关的,在这种情况下,a序列的波动风险将不能被完全分散,最终我们不得不承受市场的平均风险。
五、总结
最后再回顾一下,我们构建的轮动模型有两个前提:
1、a序列组可视做随机游走;
2、b序列组与a序列组高度相关,且b序列组有向a序列组收敛的趋势。
最后得到了如下结果:
1、通过轮动b序列,可以在不对价差进行精确预测的前提下获取统计套利收益。
2、通过资产组合,可在单向做多的限制条件下,有效分散单个序列自身的波动风险。
3、由于市场风险不可分散,这将是我们不得不承受的风险。
由此,我们可以进一步推论,轮动模型获利的条件:
1、价差回归的逻辑成立。
2、价差有可观的波动空间。
一、从最简化的统计套利说起
我们假定有两个时间序列a和b,这两个序列高度相关,且价差序列a-b具有均值回归的特性,为简化起见假设均值为0,那么,我们可以观察a-b的变化,在a-b小于0时多a空b, 在a-b大于0时多b空a, 这就是最简化的统计套利模型。
为了更直观的理解,我们撸一遍代码。先构建一个随机游走的时间序列a, 起始价格为1,日波动标准差为0.01。
import numpy as np
import pandas as pd
s_random_chg=pd.Series(np.random.normal(0,0.01,1000))
s_random=(s_random_chg+1).cumprod()
s_random.plot(figsize=(10,5),grid=True);
接下来,再构建一个以0为中心的均值回归序列:
def generate_reverse_serise(N):
s=0
k=0.1
s_reverse=[]
for i in range(0,N):
s=s-s*k+np.random.normal(0,0.01)
s_reverse.append(s)
return pd.Series(s_reverse)
s_reverse=generate_reverse_serise(1000)
s_reverse.plot(figsize=(10,5),grid=True);
最后,把前面两个序列加起来,得到序列b。把这两个序列放一起,如下所示,我们就得到了两条高度相关的、可进行套利操作的序列。
pricedf=pd.DataFrame()
pricedf['a']=s_random
pricedf['b']=s_random+s_reverse
pricedf.plot(figsize=(10,5),grid=True);
接下来,我们构建一个经典的统计套利策略,我们观察a-b价差序列,发现大部分时间在[-0.02,0.02]之间波动,我们就马后炮地选择在-0.02的时候多a空b, 在0.02的时候多b空a,在穿越零值的时候平仓。
def signal_func(c):
s=[]
flag=0
for i in range(0,len(c)):
if c[i]<-0.02:
flag=1
elif c[i]>0.02:
flag=-1
else:
if flag==1 and c[i]>0:
flag=0
elif flag==-1 and c[i]<0:
flag=0
s.append(flag)
return pd.Series(s)
signal=pd.DataFrame()
signal['a']=signal_func(pricedf['a']-pricedf['b'])
signal['b']=-signal['a']
forward_return=pricedf.pct_change().shift(-1)
pnl=(forward_return*signal).sum(axis=1)/2
(1+pnl).cumprod().plot(figsize=(10,5),grid=True);
我们发现,我们的马后炮套利非常成功,净值呈45度角一路上升,感觉造个印钞机跟玩儿似的。别做梦了,这只是极度简化的理论模型,让我们往现实靠近一步,考虑更为普遍的情况,万一没有做空手段或做空成本太高呢?
二、向现实妥协的搬砖模型
现实中,收益往往需要用风险来交换,如果存在可观的价差空间,几乎可以肯定是由于无风险套利渠道不畅造成的,最常见的情况就是至少有一条腿是无法做空的。这时,我们还有个替代的模型叫搬砖。简单来说就是只做一条腿,哪个价格低就做多哪个,由于无法通过做空来对冲,需要承受标的价格下跌的风险。
我们来看看搬砖模型的表现:
signal2=signal[signal>0]
forward_return=pricedf.pct_change().shift(-1)
pnl=(forward_return*signal2).sum(axis=1)
(1+pnl).cumprod().plot(figsize=(10,5),grid=True);
可以看到,搬砖模型虽然也有超额收益,但由于叠加了多头走势,在标的趋势向下的情况下,搬砖模型也会遭遇很大的回撤。那么,有没有办法减小回撤呢?我们马上想到了资产组合理论,同时交易很多低相关的资产可以降低回撤。
三、组合搬砖模型
接下来,我们假设可以找到100组这样的序列对,对每组序列上面进行搬砖交易, 然后把收益曲线组合在一起。
pricedf_a=(pd.DataFrame(np.random.normal(0,0.01,(1000,100)))+1).cumprod()
pricedf_b=pricedf_a.apply(lambda x:x+generate_reverse_serise(1000))
forward_return_a=pricedf_a.pct_change().shift(-1)
forward_return_b=pricedf_b.pct_change().shift(-1)
signal=(pricedf_a-pricedf_b).apply(signal_func)
signal_a=signal[signal>0].fillna(0)
signal_b=-signal[signal<0].fillna(0)
pnl_a=(signal_a*forward_return_a).sum(axis=1)/signal_a.sum(axis=1)
pnl_b=(signal_b*forward_return_b).sum(axis=1)/signal_b.sum(axis=1)
pnl=(pnl_a+pnl_b)/2
(pnl+1).cumprod().plot(figsize=(10,5),grid=True);
我们惊奇地发现,组合起来的收益呈非常完美的指数向上走势。其实大可不必惊讶,因为我们随机生成的这100个组合之间是完全无关的,即相关性为0,按投资组合理论确实可以得到这样完美的结果。
接下来我们想一想还有没有优化空间?我们在生成a、b两组序列时,a序列是随机游走的,而b序列则是在a的基础上叠加了一个均值回归的走势。从逻辑上分析,对于随机游走的序列是不存在可获利策略的,那么所有的收益来源只可能在b序列上。为证实我们的猜想,我们把上一步计算中得到的pnl_a和pnl_b分开来看一下。
下图是pnl_a的累计曲线。
下图是pnl_b的累计曲线。
我们的猜想是正确的,在搬砖模型组合中,a序列组不贡献收益,而b序列组则持续贡献超额收益,也就是说,我们只需要对b序列组进行操作,而a序列组由于是随机游走的,其综合收益最终会因足够分散而接近于0。
我们再来向现实靠近一步。在现实中,我我们一般只能从逻辑上推测价差一定回归,但很难提前预知价差的波动范围,从而难以实现如上所示的搬砖套利。但如果我们能合理假定很多个价差组合一定程度上具有同质性,我们就可以用价差的相对大小来衡量价差回归的胜率和赔率,从而可以不需要确定的价差阈值,而只是根据价差来选择相对最优的标的。终于,我们来到了本文的主角,轮动模型。
四、轮动模型
我们对上面的搬砖组合做个变形,只做b序列的部分。在b序列的信号生成时,不再是设置b-a在某个阈值区间做多,而是比较各个b-a价差在横截面上的相对大小,选择价差最小的几组b序列单向做多,即可获取统计套利的收益。当组合数量足够多时,a序列的波动风险将可以被分散到最小。
这部分的回测大家比较熟悉了,我们直接给出回测结果。
pnl=calc_pnl(filtTopN(pricedf_b-pricedf_a,20),forward_return_b)
(pnl+1).cumprod().plot(figsize=(10,5),grid=True);
进一步向现实靠拢,a序列之间的相关性不可能是0,反而是高度相关的,在这种情况下,a序列的波动风险将不能被完全分散,最终我们不得不承受市场的平均风险。
五、总结
最后再回顾一下,我们构建的轮动模型有两个前提:
1、a序列组可视做随机游走;
2、b序列组与a序列组高度相关,且b序列组有向a序列组收敛的趋势。
最后得到了如下结果:
1、通过轮动b序列,可以在不对价差进行精确预测的前提下获取统计套利收益。
2、通过资产组合,可在单向做多的限制条件下,有效分散单个序列自身的波动风险。
3、由于市场风险不可分散,这将是我们不得不承受的风险。
由此,我们可以进一步推论,轮动模型获利的条件:
1、价差回归的逻辑成立。
2、价差有可观的波动空间。