目录
上节说到,做2只股票配对交易,先判断2只股票的平稳性,不平稳就做一阶差分和协整关系
这篇博客就要来说协整关系
协整关系简单的说就是2只股票的线性组合,并且这个组合是平稳的。
先感性的认识:
A股票的价格序列为X,B股票的价格序列为Y. 用X、Y做线性回归,就可以得出线性方程:
xy线性组合:
由上面的公式可以知道:xy的线性方程,由CFA一级的知识可以知道:(没考过cfa应该不知道,记住即可,具体啰嗦,不谈。)
ε均值是0,方差是稳定的一个常数。既满足正态分布。
GitHub源代码:https://github.com/455125158/CSDN-AQF
import pandas as pd
import numpy as np
import tushare as ts
import seaborn
%matplotlib inline
from matplotlib import pyplot as plt
stocks_pair = ['600199', '600702']
1. 数据准备 & 回测准备
data1 = ts.get_k_data('600199', '2013-06-01', '2014-12-31')[['date','close']]
data2 = ts.get_k_data('600702', '2013-06-01', '2014-12-31')['close']
# 拼接
data = pd.concat([data1, data2], axis=1)
data.set_index('date',inplace = True)
data.columns = stocks_pair
data.plot(figsize= (8,6))
2. 策略开发思路
先判断2只股票的相关性:
data.corr() # 相关性矩阵
plt.figure(figsize =(10,8))
plt.title('Stock Correlation')
plt.plot(data['600199'], data['600702'], '.')
plt.xlabel('600199')
plt.ylabel('600702')
data.dropna(inplace = True)
可以看出2只股票有一定线性关系,并且前段时间的价差稳定,后段时间平稳性较差。可以使用线性回归找到2者的线性关系。
[slope, intercept] = np.polyfit(data.iloc[:,0], data.iloc[:,1], 1).round(2)
# 1次回归
slope,intercept
slope:斜率 intercept:截距
可以得出: (0.97, 4.28)
既:误差spread=y-4.29-0.97x 其中y:199股票 x:702股票
data['spread'] = data.iloc[:,1] - data.iloc[:,0]*slope - intercept
data['spread'].plot(figsize = (10,8),title = 'Price Spread')
均值在0左右。再次标准化。
data['zscore'] = (data['spread'] - data['spread'].mean())/data['spread'].std() #标准化, .std()方差
data['zscore'].plot(figsize = (10,8),title = 'Z-score')
plt.axhline(1.5, color = 'r')
plt.axhline(0)
plt.axhline(-1.5, color = 'r')
3.产生交易信号
position_1:
图解:
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['position_1'] = data['position_1'].fillna(method = 'ffill')
#填充nan
data['position_1'].plot(ylim=[-1.1, 1.1], figsize=(10, 6),title = 'Trading Signal_Uptrade')
position_2:
data['position_2'] = -np.sign(data['position_1'])
data['position_2'].plot(ylim=[-1.1, 1.1], figsize=(10, 6),title = 'Trading Signal_Downtrade')
3. 计算策略年化收益并可视化
data['returns_1'] = np.log(data['600199'] / data['600199'].shift(1))
data['returns_1'] = np.log(data['600199'] / data['600199'].shift(1))
data['strategy'] = 0.5*(data['position_1'].shift(1) * data['returns_1'])+0.5*(data['position_2'].shift(1) * data['returns_2'])
# 等权
data[['returns_1','returns_2','strategy']].dropna().cumsum().apply(np.exp).plot(figsize=(10, 8),title = 'Strategy_Backtesting')
4.总结
策略的思考
- 对多只ETF进行配对交易,是很多实盘量化基金的交易策略;
策略的风险和问题:
-
Spread不回归的风险,当市场结构发生重大改变时,用过去历史回归出来的Spread会发生不回归的重大风险;
-
中国市场做空受到限制,策略中有部分做空的收益是无法获得的;
-
回归系数需要Rebalancing(系数要改变);
-
策略没有考虑交易成本和其他成本;