配对交易策略 Pair Trading
0. 引库
import pandas as pd
import numpy as np
import tushare as ts
import seaborn
from matplotlib import pyplot as plt
plt. style. use( 'seaborn' )
% matplotlib inline
data = pd. read_csv( 'pair-trade-data.csv' )
data. set_index( 'date' , inplace = True )
data. head( )
000568
000858
date
2010/1/4
27.488118
26.117536
2010/1/5
27.335123
26.391583
2010/1/6
26.941707
25.694008
2010/1/7
26.388011
24.913389
2010/1/8
26.825140
24.863562
data. plot( figsize= ( 8 , 6 ) ) ;
2. 策略开发思路
data[ 'priceDelta' ] = data[ '000568' ] - data[ '000858' ]
data. head( )
000568
000858
priceDelta
date
2010/1/4
27.488118
26.117536
1.370582
2010/1/5
27.335123
26.391583
0.943540
2010/1/6
26.941707
25.694008
1.247699
2010/1/7
26.388011
24.913389
1.474622
2010/1/8
26.825140
24.863562
1.961578
data[ 'priceDelta' ] . plot( figsize= ( 8 , 6 ) ) ;
plt. ylabel( 'Spread' )
plt. axhline( data[ 'priceDelta' ] . mean( ) ) ;
data[ 'zscore' ] = ( data[ 'priceDelta' ] - np. mean( data[ 'priceDelta' ] ) ) / np. std( data[ 'priceDelta' ] )
data. head( )
000568
000858
priceDelta
zscore
date
2010/1/4
27.488118
26.117536
1.370582
0.569895
2010/1/5
27.335123
26.391583
0.943540
0.500520
2010/1/6
26.941707
25.694008
1.247699
0.549932
2010/1/7
26.388011
24.913389
1.474622
0.586796
2010/1/8
26.825140
24.863562
1.961578
0.665903
len ( data[ data[ 'zscore' ] > 1.5 ] )
17
data[ 'position_1' ] = np. where( data[ 'zscore' ] > 1.5 , - 1 , np. nan)
data[ 'position_1' ] = np. where( data[ 'zscore' ] < - 1.5 , 1 , data[ 'position_1' ] )
data[ 'position_1' ] = np. where( abs ( data[ 'zscore' ] ) < 0.5 , 0 , data[ 'position_1' ] )
data. head( )
000568
000858
priceDelta
zscore
position_1
date
2010/1/4
27.488118
26.117536
1.370582
0.569895
NaN
2010/1/5
27.335123
26.391583
0.943540
0.500520
NaN
2010/1/6
26.941707
25.694008
1.247699
0.549932
NaN
2010/1/7
26.388011
24.913389
1.474622
0.586796
NaN
2010/1/8
26.825140
24.863562
1.961578
0.665903
NaN
产生交易信号
data[ 'position_1' ] = data[ 'position_1' ] . ffill( ) . fillna( 0 )
data[ 'position_1' ] . plot( ylim= [ - 1.1 , 1.1 ] , figsize= ( 10 , 6 ) ) ;
data[ 'position_2' ] = - np. sign( data[ 'position_1' ] )
data[ 'position_2' ] . plot( ylim= [ - 1.1 , 1.1 ] , figsize= ( 10 , 6 ) ) ;
3. 计算策略年化收益并可视化
data[ 'returns_1' ] = ( np. log( data[ '000568' ] / data[ '000568' ] . shift( 1 ) ) ) . fillna( 0 )
data