期权 Pair trading 策略

本文介绍了期权的Pair trading策略,包括数据准备、策略开发思路及交易信号的产生。策略核心是寻找两只ETF之间的相对价格关系,当该关系偏离历史平均后进行买卖操作。然而,策略面临如Spread不回归、中国市场做空限制、Rebalancing需求以及交易成本等问题。
摘要由CSDN通过智能技术生成

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
stocks_pair = ['cu', 'zn']
1. 数据准备
# 加载数据
data1 = pd.read_csv('cu.csv')[['date','close']]
data2 = pd.read_csv('zn.csv')['close']
# 按行拼接收盘价
data = pd.concat([data1, data2], axis=1)
data.set_index('date',inplace = True)
# 重命名列('cu'、'zn')
data.columns = stocks_pair
data.head()
cuzn
date
2016/10/183730018080
2016/10/193726018200
2016/10/203727018255
2016/10/213715018245
2016/10/243732018175
data.plot(figsize= (8,6));

4

2. 策略开发思路
data.corr()  # 协方差矩阵
cuzn
cu1.0000000.941114
zn0.9411141.000000
# 数据可视化,看相关关系
plt.figure(figsize =(8,6))
plt.title('Stock Correlation')
plt.plot(data['cu'], data['zn'], '.');
plt.xlabel('cu')
plt.ylabel('zn')
data.dropna(inplace = True)

7

# 对两股票价格做线性回归(白噪声项符合正态分布)
[slope, intercept] = np.polyfit(data.iloc[:,0], data.iloc[:,1], 1).round(2)      
slope,intercept
(0.48, 266.73)

(y-266.73-0.48x) 符合Stationary

# 算出 (y-266.73-0.48x) 一列
data['spread'] = data.iloc[:,1] - (data.iloc[:,0]*slope + intercept)
data.head()
cuznspread
date
2016/10/183730018080-90.73
2016/10/19372601820048.47
2016/10/20372701825598.67
2016/10/213715018245146.27
2016/10/243732018175-5.33
data['spread'].plot(figsize = (8,6),title = 'Price Spread');

11

# 对 spread 进行标准化
data['zscore'] = (data['spread'] - data['spread'].mean())/data['spread'].std()
data.head()
cuznspreadzscore
date
2016/10/183730018080-90.73-0.018872
2016/10/19372601820048.470.192004
2016/10/20372701825598.670.268053
2016/10/213715018245146.270.340163
2016/10/243732018175-5.330.110502
# 可视化标准化后的值
data['zscore'].plot(figsize = (10,8),title = 'Z-score')
plt.axhline(1.5)
plt.axhline(0)
plt.axhline(-1.5)

13

产生交易信号
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')
data['position_1'].plot(ylim=[-1.1, 1.1], figsize=(10, 6),title = 'Trading Signal_Uptrade');

16

data['position_2'] = -np.sign(data['position_1'])
data['position_2'].plot(ylim=[-1.1, 1.1], figsize=(10, 6),title = 'Trading Signal_Downtrade');

17

3. 计算策略年化收益并可视化
# 算离散收益率
data['returns_1'] = np.log(data['cu'] / data['cu'].shift(1))
data['returns_2'] = np.log(data['zn'] / data['zn'].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).tail(1)
returns_1returns_2strategy
date
2018/6/61.4107241.3780421.35536
# 画出累积收益率
data[['returns_1','returns_2','strategy']].dropna().cumsum().apply(np.exp).plot(figsize=(10, 8),title = 'Strategy_Backtesting');

21

# 计算年化收益率
data[['returns_1','returns_2','strategy']].dropna().mean() * 252
returns_1    0.216785
returns_2    0.202018
strategy     0.191562
dtype: float64
# 计算年化风险
data[['returns_1','returns_2','strategy']].dropna().std() * 252 ** 0.5
returns_1    0.158409
returns_2    0.210702
strategy     0.054305
dtype: float64
# 策略累积收益率
data['cumret'] = data['strategy'].dropna().cumsum().apply(np.exp)
# 策略累积最大值
data['cummax'] = data['cumret'].cummax()
# 算回撤序列
drawdown = (data['cummax'] - data['cumret'])
# 算最大回撤
drawdown.max()
0.026175344283502433
小结

策略的思考

  1. 对多只ETF进行配对交易,是很多实盘量化基金的交易策略;

策略的风险和问题:

  1. Spread不回归的风险,当市场结构发生重大改变时,用过去历史回归出来的Spread会发生不回归的重大风险;

  2. 中国市场做空受到限制,策略中有部分做空的收益是无法获得的;

  3. 回归系数需要Rebalancing;

  4. 策略没有考虑交易成本和其他成本;

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值