import pandas as pd
import numpy as np
from pandas_datareader import data as web
import fix_yahoo_finance as yf
import tushare as ts

#提取中国银行和浦发银行的调整后收盘数据

PAf = web.get_data_yahoo('601988.SS', start = '2014-01-01', end = '2015-01-01')
PBf = web.get_data_yahoo('600000.SS', start ='2014-01-01', end = '2015-01-01')

#PAF= ts.get_k_data(code=‘601988’,start=‘2014-01-01’,end=‘2015-01-01’)

PAf = PAf['Adj Close']
PBf = PBf['Adj Close']
#将两只股票数据合在一起形成Dataframe
pairf = pd.concat([PAf,PBf],axis=1)

#求形成期长度

len(pairf)

#最小距离法
#构造标准化价格之差平方累积SSD函数

def SSD(priceX,priceY):if priceX is None or priceY is None:print('缺少价格序列')returnX= (priceX - priceX.shift(1))/priceX.shift(1)[1:]returnY= (priceY - priceY.shift(1))/priceY.shift(1)[1:]standardX = (returnX +1).cumprod()standardY = (returnY +1).cumprod()SSD= np.sum((standardX-standardY)**2)return(SSD)

#协整模型

from arch.unitroot import ADF

#检验中国银行对数价格的一阶单整性

PAflog = np.log(PAf)
PBflog =  np.log(PBf)

#对中国银行对数价格进行单位根检验

adfA = ADF(PAflog)
print(adfA.summary().as_text())adfB = ADF(PBflog)
print(adfB.summary().as_text())

#将中国银行对数价格差分

retA = PAflog.diff()[1:]
retB = PBflog.diff()[1:]adfretA = ADF(retA)
print(adfretA.summary().as_text())adfretB = ADF(retB)
print(adfretB.summary().as_text())

#画出中国银行和浦发银行股票对数价格时序图

import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei']PAflog.plot(label='601988ZGYH',style='--')
PBflog.plot(label='600000ZGLT',style='-')
plt.legend(loc='upper left')
plt.title('中国银行与浦发银行的对数价格时序图')
plot.show()

#绘制股票对数价格差分的时序图

retA.plot(label='601988ZGYH')
retB.plot(label='600000ZGLT')
plt.legend(loc='lower left')
plt.title('中国银行与浦发银行的对数价格差分(收益率)')
plt.show()

#回归分析
#因变量是中国银行(A)股票的对数价格
#自变量是浦发银行(B)股票的对数价格

import statsmodels.api as smmodel=sm.OLS(PBflog, sm.add_constant(PAflog))
results = model.fit()
print(results.summary())

#将浦发银行股票的对数价格与中国银行股票的对数价格做线型回归后,对回归残差进行平稳性检验。

#提取回归截距项和系数

alpha = results.params[0]
beta = results.params[1]
#求残差
spread = PBflog-beta*PAflog-alpha
spread.plot()
plt.title('价差序列')
plt.show()

#价差序列单位根检验

adfspread = ADF(spread,trend='nc')
print(adfspread.summary().as_text())

‘最小距离法交易策略’
#中国银行和浦发银行标准化价格

standardA = (1+retA).cumprod()
standardB = (1+retB).cumprod()

#求中国银行和浦发银行标准化价格序列的价差

SSD_pair = standardB-standardA
SSD_pair.head()meanSSD_pair = np.mean(SSD_pair)
sdSSD_pair = np.std(SSD_pair)
thresholdUp = meanSSD_pair+1.2*sdSSD_pair
thresholdDown = meanSSD_pair-1.2*sdSSD_pairSSD_pair.plot()
plt.title('中国银行与浦发银行标准化价差序列(形成期)')
plt.axhline(y=meanSSD_pair,color='black')
plt.axhline(y=thresholdUp,color='green')
plt.axhline(y=thresholdDown,color='green')
plt.show()

#构建pairtrading 类

import re
import pandas as pd
import numpy as np
from arch.unitroot import ADF
import statsmodels.api as sm
class PairTrading:def SSD(self,priceX,priceY):if priceX is None or priceY is None:print('缺少价格序列')returnX = (priceX - priceX.shift(1)) / priceX.shift(1)[1:]returnY = (priceY - priceY.shift(1)) / priceY.shift(1)[1:]standardX = (returnX + 1).cumprod()standardY = (returnY + 1).cumprod()SSD = np.sum((standardX - standardY) ** 2)return (SSD)def SSDSpread(self,priceX,priceY):if priceX is None or priceY is None:print('缺少价格序列')retx = (priceX - priceX.shift(1)) / priceX.shift(1)[1:]rety = (priceY - priceY.shift(1)) / priceY.shift(1)[1:]standardX = (1+retx).cumprod()standardY = (1+rety).cumprod()spread = standardY - standardXreturn(spread)def cointegration(self,priceX,priceY):if priceX is None or priceY is None:print('缺少价格序列')priceX = np.log(priceX)priceY = np.log(priceY)results = sm.OLS(priceY,sm.add_constant(priceX)).fit()resid = results.residadfSpread = ADF(resid)if adfSpread.pvalue >= 0.05:print('''交易价格不具有协整关系,P-value of ADF test: %fCoefficients of regression: Intercept: %fBeta: %f'''% (adfSpread.pvalue, results.params[0],results.params[1]))return(None)else:print('''交易价格具有协整关系,P-value of ADF test: %fCoefficients of regression: Intercept: %fBeta: %f''' % (adfSpread.pvalue, results.params[0], results.params[1]))return(results.params[0], results.params[1])def CointegrationSpread(self,priceX,priceY,formPeriod, tradePeriod):if priceX is None or priceY is None:print('缺少价格序列')if not (re.fullmatch('\d{4}-\d{2}-\d{2}:\d{4}-\d{2}-\d{2}',formPeriod)or re.fullmatch('\d{4}-\d{2}-\d{2}:\d{4}-\d{2}-\d{2}',tradePeriod)):print('形成期交易期格式错误.')formX = priceX[formPeriod.split(':')[0]:formPeriod.split(':')[1]]formY = priceY[formPeriod.split(':')[0]:formPeriod.split(':')[1]]coefficients = self.cointegration(formX,formY)if coefficients is None:print('未形成协整关系,无法配对.')else:spread=(np.log(priceY[tradePeriod.split(':')[0]:tradePeriod.split(':')[1]])-coefficients[0]-coefficients[1]*np.log(priceX[tradePeriod.split(':')[0]:tradePeriod.split(':')[1]]))return(spread)def calBound(self,priceX,priceY,method,formPeriod,width=1.5):if not (re.fullmatch('\d{4}-\d{2}-\d{2}:\d{4}-\d{2}-\d{2}',formPeriod)or re.fullmatch('\d{4}-\d{2}-\d{2}:\d{4}-\d{2}-\d{2}',tradePeriod)):print('形成期格式错误.')if method=='SSD':spread=self.SSDSpread(priceX[formPeriod.split(':')[0]:formPeriod.split(':')[1]],priceY[formPeriod.split(':')[0]:formPeriod.split(':')[1]])mu = np.mean(spread)sd = np.std(spread)UpperBound = mu+width*sdLowerBound = mu-width*sdreturn(UpperBound,LowerBound)elif method=='Cointegration':spread=self.CointegrationSpread(priceX,priceY,formPeriod,formPeriod)mu = np.mean(spread)sd = np.std(spread)UpperBound = mu + width * sdLowerBound = mu - width * sdreturn (UpperBound, LowerBound)else:print('不存在该方法,请选择“SSD"或是”Cointegration".')

testing

import pandas as pd
import numpy as np
from pandas_datareader import data as web
import fix_yahoo_finance as yf
import tushare as tsformPeriod = '2014-01-01:2015-01-01'
tradePeriod = '2015-01-01:2015-06-30'
priceA = web.get_data_yahoo('601988.SS', start = '2014-01-01', end = '2015-06-30')
priceB = web.get_data_yahoo('600000.SS', start ='2014-01-01', end = '2015-06-30')
priceA = priceA['Adj Close']
priceB = priceB['Adj Close']
priceAf = priceA[formPeriod.split(':')[0]:formPeriod.split(":")[1]]
priceBf = priceB[formPeriod.split(':')[0]:formPeriod.split(":")[1]]
priceAt =priceA[tradePeriod.split(':')[0]:tradePeriod.split(":")[1]]
priceBt = priceB[tradePeriod.split(':')[0]:tradePeriod.split(":")[1]]
pt=PairTrading()SSD=pt.SSD(priceAf,priceBf)SSDspread = pt.SSDSpread(priceAf,priceBf)
SSDspread.describe()
SSDspread.head()coefficients=pt.cointegration(priceAf,priceBf)CoSpreadF=pt.CointegrationSpread(priceA,priceB,formPeriod,formPeriod)
CoSpreadTr=pt.CointegrationSpread(priceA,priceB,formPeriod,tradePeriod)bound = pt.calBound(priceA,priceB,'Cointegration',formPeriod,width=1.2)CoSpreadTr.plot()
plt.axhline(bound[0],color='black')
plt.axhline(bound[1],color='black')
plt.show()logPBf=np.log(priceBf)
logPAf=np.log(priceAf)spreadf=logPBf-beta*logPAf-alpha
adfSpread=ADF(spreadf)
print(adfSpread.summary().as_text())CoSpreadT=logPBf-beta*logPAf-alpha
mu=np.mean(spreadf)
sd=np.std(spreadf)

#设定交易期

tradeStart = '2015-01-01'
tradeEnd='2015-06-30'

#绘制价差区间图

CoSpreadTr.plot()
plt.title('交易期价差序列(协整配对)')
plt.axhline(y=mu,color='black')
plt.axhline(y=mu+0.2*sd,color='blue',ls='-',lw=2)
plt.axhline(y=mu-0.2*sd,color='blue',ls='-',lw=2)
plt.axhline(y=mu+1.5*sd,color='green',ls='--',lw=2.5)
plt.axhline(y=mu-1.5*sd,color='green',ls='--',lw=2.5)
plt.axhline(y=mu+2.5*sd,color='red',ls='-.',lw=3)
plt.show()

#根据开仓平仓点制定交易策略,并模拟交易账户。

level =(float('-inf'),mu-2.5*sd,mu-1.5*sd,mu-0.2*sd,mu+0.2*sd,mu+1.5*sd,mu+2.5*sd,float('inf'))
prcLevel = pd.cut(CoSpreadTr,level,labels=False)-3
prcLevel.head()

#构造交易新号函数

def TradeSig(prcLevel):n= len(prcLevel)signal = np.zeros(n)for i in range(1,n):if prcLevel[i-1]==1 and prcLevel[i]==2:signal[i]=-2elif prcLevel[i-1]==1 and prcLevel[i]==0:signal[i]=2elif prcLevel[i-1]==2 and prcLevel[i]==3:signal[i]=3elif prcLevel[i-1]==-1 and prcLevel[i]==-2:signal[i]=1elif prcLevel[i-1]==-1 and prcLevel[i]==0:signal[i]=-1elif prcLevel[i-1]==-2 and prcLevel[i]==-3:signal[i]=-3return(signal)signal = TradeSig(prcLevel)
position=[signal[0]]
ns=len(signal)for i in range (1,ns):position.append(position[-1])if signal[i]==1:position[i]=1elif signal[i]==-2:position[i]==-1elif signal[i]==1 and postion[i-1]==1:position[i]=0elif signal[i]==2 and position[i-1]==-1:position[i]=0elif signal[i]==3:position[i]=0elif signal[i]==-3:position[i]=0position = pd.Series(position,index=CoSpreadTr.index)
position.tail()def TraddeSim(priceX, priceY, position):n=len(position)size=1000shareY = size*positionshareX = [(-beta)*shareY[0]*priceY[0]/priceX[0]]cash=[2000]for i in range (1,n):shareX.append(shareX[i-1])cash.append(cash[i-1])if position[i-1]==0 and position[i]==1:shareX[i]=[(-beta)*shareY[i]*priceY[i]/priceX[i]]cash[i]=cash[i-1]-(shareY[i]*priceY[i]+ np.array(shareX[i])*priceX[i])elif position[i-1]==0 and position[i]==-1:shareX[i] = [(-beta) * shareY[i] * priceY[i] / priceX[i]]cash[i]=cash[i-1]-(shareY[i]*priceY[i]+np.array(shareX[i])*priceX[i])elif position[i-1]==1 and  position[i]==0:shareX[i]=0cash[i]=cash[i-1]+(shareY[i-1]*priceY[i]+np.array(shareX[i-1])*priceX[i])elif position[i-1]==-1 and position[i]==0:shareX[i]=0cash[i]=cash[i-1]+(shareY[i-1]*priceY[i]+np.array(shareX[i-1])*priceX[i])cash = pd.Series(cash,index=position.index)shareY = pd.Series(shareY,index=position.index)shareX = pd.Series(shareX,index=position.index)asset = cash + shareY*priceY +pd.Series(shareX)*priceXaccount =pd.DataFrame({'Position':position,'ShareY':shareY,'ShareX':shareX,'Cash':cash,'Asset':asset})account.index=position.indexreturn(account)account = TradeSim(priceAt,priceBt,position)
account.iloc[:,0].plot()
account.iloc[:,1].plot()
account.iloc[:,2].plot()
plt.show()

#记录 配对交易学习相关推荐

  1. 高频交易配对交易学习——Copulas函数理解

    Copulas函数理解 https://github.com/MalteKurz/VineCopulaCPP

  2. 配对交易方法_COVID下的自适应配对交易,一种强化学习方法

    配对交易方法 Abstract 抽象 This is one of the articles of A.I. Capital Management's Research Article Series, ...

  3. Python实现股票量化交易学习进阶(二)之简单交易策略的定义实现

    Python实现股票量化交易学习进阶第二篇之简单交易策略的定义实现 1.backtrader回测框架知识 2.需求一自定义MACD指标 3.需求二自定义实现KDJ指标 4.需求三自定义CCI指标 1. ...

  4. python统计套利_统计套利(二),利用协整关系进行配对交易【原文】

    之前我们谈到了利用两只股票之间的相关系数进行配对交易,但我们能通过两只相关性较高的股票对之间的差价图看出,相关性高他们之间的价差并不一定会是一个平稳序列,简单来说我们无法利用这个不收敛的价差来进行套利 ...

  5. 利用协整关系进行配对交易

    在前一篇当中利用相关系数来进行套利,看到价差并不为平稳序列,回测结果也就不是很好,所以想到利用协整关系来构建股票的线性组合,使得股价差为平稳序列,从而在真正意义上构建一个套利策略.看到有其他小伙伴也做 ...

  6. Python实现股票量化交易学习进阶(一)之基础库(知识准备)搭建

    股票量化交易学习第一篇之基础搭建 1.写在前面 1.1.Numpy库的安装 1.2.Pandas库的安装 1.3.金融数据获取 1.4.talib金融库的安装及文档链接 1.5.Matplotlib ...

  7. 记录自己的学习和经验

    从今天开始,正式开通博客,记录自己的学习知识和经验. 下面是一些个人心得. http://www.imooc.com/article/4637 转载于:https://www.cnblogs.com/ ...

  8. matlab配对交易回测,精品案例 | 经典投资策略之配对交易策略

    原标题:精品案例 | 经典投资策略之配对交易策略 人不恋爱枉少年,在"全城热恋"的氛围下,股市也来凑热闹,配对交易策略油然而生.所谓"男女搭配,干活不累",成双 ...

  9. android培训内容明细,记录Android开发学习

    记录Android开发学习 Menu菜单学习 1.掌握Android中菜单的创建. 2.掌握Intent信使组件. 创建菜单Menu 我们模仿微信菜单栏学习,创建一个于微信菜单栏相似的菜单 那么我们应 ...

最新文章

  1. 微软,您的.net为中国程序员带来了什么?
  2. 【青少年编程】【三级】青蛙捕虫
  3. Android图片轮播
  4. Java开发环境配置——Tomcat
  5. php7 加的新特性积累
  6. pandas插入新列
  7. java生产环境增量发版陷阱【原】
  8. H3C 命令行历史记录功能
  9. html5新标签笔记,HTML5新标签学习笔记
  10. Maxscale读写分离,多实例
  11. xlwings 冻结窗口格 / 冻结首行/ FreezePanes
  12. 装了伽卡他卡打不开任务管理器的解决办法
  13. 数据清洗与处理第二章
  14. 2021-09-15小记西数3T蓝盘翻车
  15. MySQL慢SQL探究
  16. 智能语音机器人智能在哪里?
  17. mysql(.msi)下载、安装及配置教程
  18. JDK11安装教程(手把手配置,也适用于其他jdk版本)
  19. 神经网络最本质的理论基础是什么?
  20. Contacts(简介)

热门文章

  1. HSY 点餐(数论)
  2. 深入解析go依赖注入库go.uber.org/fx
  3. html投影电脑,投影仪怎么连接笔记本电脑
  4. Kerberos协议内容详解
  5. (二)回顾硅谷:硅谷历史
  6. 从零基础到导入运行Java版坦克大战游戏项目 第一节(Java JDK的下载安装配置)
  7. 【模电仿真】RC桥式正弦波发生电路
  8. dp——洛谷P1240 诸侯安置
  9. 孝经白话:诸侯章第三
  10. MySQL中LOCATE()函数的详解