1. 原理

什么是套利?

套利是指在买入或卖出一种金融资产的同时卖出或买入另一种相关的金融资产从中利用价差获得套利的过程。

什么是跨品种套利?

当两个合约有很强的相关性时,可能存在相似的变动关系,两种合约之间的价差会维持在一定的水平上。当市场出现变化时,两种合约之间的价差会偏离均衡水平。此时,可以买入其中一份合约同时卖出其中一份合约,当价差恢复到正常水平时平仓,获取收益。

以大商所玉米和淀粉为例,合约分别为c1801和cs1801。二者之间相关性为0.7333,价差处于相对稳定合理区间。如图所示。

二者价差整体处于250-350之间。当价差偏离此区间时,可以进行跨品种套利。

跨品种套利有以下几个特点:

1.套利的两种资产必须有一定的相关性。2.两种合约标的不同,到期时间相同。3.两种资产之间的价差呈现一定规律。

怎样确定合约之间有相关性?

最常用的方法是利用EG两步法对两个序列做协整检验,判断两个序列是否平稳。只有单整阶数相同,二者才有可能存在一定的关系。

以大豆和豆粕为例,选取其在2017年1月1日至2018年1月1日的主力合约价格时间序列,利用statsmodels包进行协整检验。

检验结果为:焦炭的t = -1.7886,1%置信区间的临界值为-3.4576,说明该序列在99%的置信水平下平稳。焦煤的t = -2.0500,1%置信区间的临界值为-3.4576,说明该序列在99%的置信水平下平稳。

因此,二者都为平稳序列。

利用OLS回归检残差序列是否平稳,残差的t=-2.3214,临界值为-3.4577,说明残差平稳。因此,可以认为二者之间存在一定的关系。

回归后的残差图如下:

对残差进行ks检验,检验结果p=0,说明残差分布为正态分布。

策略设计

传统利用价差进行跨品种套利的方法是计算出均值和方差,设定开仓、平仓和止损阈值。当新的价格达到阈值时,进行相应的开仓和平仓操作。

应该怎样确定均值?

均值的选取主要有两种方法,第一种方法是固定均值。先按历史价格计算相应的阈值(比如利用2017年2月-2017年6月的数据计算阈值,在2019年7月进行套利),再用最新价差进行比较,会发现前后均值差异很大。如图所示。

因此,常用变动的均值设定阈值。即用过去N天两个标的之间差值的均值和方差。

  1. 策略思路

第一步:选择相关性较高的两个合约,本例选择大商所的焦炭和焦煤。第二步:以过去30个的1d频率bar的均值正负0.75个标准差作为开仓阈值,以正负2个标准差作为止损阈值。第三步:最新价差上穿上界时做空价差,回归到均值附近平仓;下穿下界时做多价差,回归到均值附近平仓。设定止损点,触发止损点则全部平仓。

  1. 策略代码

"""
关注: Ctp接口量化"""
from _ctp import *
from Config import Config
import numpy as np
class Arbitrage_Strategy(Strategy):def __init__(self):super().__init__()# 选择的两个合约self.symbol_lsit = ['j1901', 'jm1901']# 订阅历史数据self.bar_time = BarType.Min  #订阅K线周期  秒级 BarType.Time3  Time5  Time15  Time30       分钟级  BarType.Min ,  Min3 、 Min5 、 Min15 、 Min30 、 Min60self.StrategyType = StrategyType.Bar  #策略类型  StrategyType.Renko   StrategyType.Bar   StrategyType.Tickdef on_trade(self, trade):print(trade)def on_tick(self, tick=None):print(tick.InstrumentID,tick.LastPrice)  def on_bar(self, tick=None, Bar=None):# 数据提取symbol = tick.InstrumentID   #合约代码print(self.GetData(symbol))   # 获取k历史数据j_close = self.GetData(self.symbol_lsit[0])jm_close = self.GetData(self.symbol_lsit[1])# 提取最新价差new_price = j_close[-1] - jm_close[-1]# 计算历史价差,上下限,止损点spread_history = j_close[:-2] -  jm_close[:-2]self.spread_history_mean = np.mean(spread_history)self.spread_history_std = np.std(spread_history)self.up = self.spread_history_mean + 0.75 * self.spread_history_stdself.down = self.spread_history_mean - 0.75 * self.spread_history_stdself.up_stoppoint = self.spread_history_mean + 2 * self.spread_history_stdself.down_stoppoint = self.spread_history_mean - 2 * self.spread_history_std# 查持仓print(self.Get_Position(self.symbol_lsit[0]))      # 返回多条持仓print(self.Get_Position(self.symbol_lsit[1]))      # 返回多条持仓position_j_long = self.GetPosition(self.symbol_lsit[0],"Long") # 返回一条持仓position_j_short = self.GetPosition(self.symbol_lsit[0],"Short") # 返回一条持仓position_jm_long = self.GetPosition(self.symbol_lsit[1],"Long") # 返回一条持仓position_jm_short = self.GetPosition(self.symbol_lsit[1],"Short") # 返回一条持仓# 设计买卖信号# 设计开仓信号if not position_jm_short and not position_jm_long:if new_price > self.up:print('做空价差组合')self.send(self.symbol_lsit[0], DirectionType.Sell, OffsetType.Open, j_close[-1], 1, OrderType.Limit)   # # OffsetType.Open 开仓,   OffsetType.Close 平仓,   OffsetType.CloseToday 平今 , OffsetType.CloseYesterday 平昨self.send(self.symbol_lsit[1], DirectionType.Buy, OffsetType.Open, jm_close[-1], 1, OrderType.Limit)  # # OrderType.FOK """全部完成,否则撤销"""  OrderType.FAK """部分成交,剩余撤销"""  OrderType.Market 市价   OrderType.Limit 限价if new_price < self.down:print('做多价差组合')self.send(self.symbol_lsit[0], DirectionType.Buy, OffsetType.Open, j_close[-1], 1, OrderType.Limit)   # # OffsetType.Open 开仓,   OffsetType.Close 平仓,   OffsetType.CloseToday 平今 , OffsetType.CloseYesterday 平昨self.send(self.symbol_lsit[1], DirectionType.Sell, OffsetType.Open, jm_close[-1], 1, OrderType.Limit)  # # OrderType.FOK """全部完成,否则撤销"""  OrderType.FAK """部分成交,剩余撤销"""  OrderType.Market 市价   OrderType.Limit 限价# 设计平仓信号# 持jm多仓时if position_jm_long:if new_price >= self.spread_history_mean:# 价差回归到均值水平时,平仓print('价差回归到均衡水平,平仓')self.send(self.symbol_lsit[0], DirectionType.Sell, OffsetType.Close, j_close[-1], position_j_long["总持仓"], OrderType.Limit)   #    OffsetType.Close 已优化 适应 上期所 平今 平昨  的区别 self.send(self.symbol_lsit[1], DirectionType.Buy, OffsetType.Close, jm_close, position_jm_long["总持仓"], OrderType.Limit)if new_price < self.down_stoppoint:# 价差达到止损位,平仓止损print('价差超过止损点,平仓止损')self.send(self.symbol_lsit[0], DirectionType.Sell, OffsetType.Close, j_close[-1], position_j_long["总持仓"], OrderType.Limit)   #    OffsetType.Close 已优化 适应 上期所 平今 平昨  的区别 self.send(self.symbol_lsit[1], DirectionType.Buy, OffsetType.Close, jm_close[-1], position_jm_long["总持仓"], OrderType.Limit)# 持jm空仓时if position_jm_short:if new_price <= self.spread_history_mean:# 价差回归到均值水平时,平仓print('价差回归到均衡水平,平仓')self.send(self.symbol_lsit[0], DirectionType.Buy, OffsetType.Close, j_close[-1], position_j_short["总持仓"], OrderType.Limit)   #    OffsetType.Close 已优化 适应 上期所 平今 平昨  的区别 self.send(self.symbol_lsit[1], DirectionType.Sell, OffsetType.Close, jm_close[-1], position_jm_short["总持仓"], OrderType.Limit)if new_price > self.up_stoppoint:# 价差达到止损位,平仓止损print('价差超过止损点,平仓止损')self.send(self.symbol_lsit[0], DirectionType.Buy, OffsetType.Close, j_close[-1], position_j_short["总持仓"], OrderType.Limit)   #    OffsetType.Close 已优化 适应 上期所 平今 平昨  的区别 self.send(self.symbol_lsit[1], DirectionType.Sell, OffsetType.Close, jm_close[-1], position_jm_short["总持仓"], OrderType.Limit)
if __name__ == '__main__':t = CTP(Arbitrage_Strategy())t.Login(Config)

注:此策略只用于学习、交流、演示,不构成任何投资建议。

CTP接口python实现跨品种套利策略源码相关推荐

  1. CTP接口开发案例(内附源码)

    CTP接口开发(内附源码) 提示:在看本博客之前建议先阅读上期所官方的开发文档(SimNow官网中去下载CTP接口文件),然后在SimNow官网注册模拟账号. 提示:股票CTP接口和期货CTP接口类似 ...

  2. 获取铁矿石和螺纹钢期货数据。对收益率序列进行描述性统计、jb检验,反正是否符合分形市场假说。计算Hurst指数,制定跨品种套利策略,并进行回测,对跨品种套利效果进行评估。寻求改进空间。

    源码已上传至github 项目简介 获取铁矿石和螺纹钢期货数据.对收益率序列进行描述性统计.jb检验,反正是否符合分形市场假说.计算Hurst指数,制定跨品种套利策略,并进行回测,对跨品种套利效果进行 ...

  3. CTP综合交易平台接口-程序化交易编程模板(VC源码)

    期货程序化VC++ vs2008代码,自己只要编写交易策略部分即可,简单方便 动态行情.任意分钟K线.Tick数据自维护,自动收盘, 从文件brokers.xml找期货公司代码 直连期货公司交易服务器 ...

  4. spring MVC cors跨域实现源码解析

    spring MVC cors跨域实现源码解析 名词解释:跨域资源共享(Cross-Origin Resource Sharing) 简单说就是只要协议.IP.http方法任意一个不同就是跨域. sp ...

  5. python设计模式pdf_精通Python设计模式 高清晰PDF+源码

    精通Python设计模式讲述了16种基本设计模式,轻松解决软件设计常见问题:借力高效的Python语言,用现实例子展示各模式关键特性. 本书用实际生活中的例子带你了解常用的设计模式,介绍了诸多有关编写 ...

  6. cvtcolor python opencv_13行代码实现:Python实时视频采集(附源码)

    程序逻辑 Python实时视频采集程序主要流程共分为10个步骤,具体如下图所示: 流程描述: 库文件导入:导入程序依赖的python安装包: 摄像头管理对象创建和初始化:是对opencv VideoC ...

  7. 【Python 笔记】Linux 下源码编译安装 python

    本文记录在 Linux 上源码编译安装 python 的过程. 文章目录 1. 源码编译安装说明 2. 安装 python2.7 3. 安装 python3.6 1. 源码编译安装说明 安装过程比我想 ...

  8. 分享Python采集99个VB源码,总有一款适合您

    分享Python采集99个VB源码,总有一款适合您 Python采集的99个VB源码下载链接:https://pan.baidu.com/s/1Ljs41rWn_WxvGqFWCkmGsA?pwd=1 ...

  9. 【附源码】计算机毕业设计Python安卓“我爱厨房”APP5loq7(源码+程序+LW+调试部署)

    [附源码]计算机毕业设计Python安卓"我爱厨房"APP5loq7(源码+程序+LW+调试部署) 该项目含有源码.文档.程序.数据库.配套开发软件.软件安装教程 项目运行环境配置 ...

  10. 100个Python实战项目(附源码),练完即可就业,从入门到进阶

    前言: "读"代码是不能给你带来任何收益的,正如"读书"一样,如果在读的时候你不琢磨,保管你读完仨月准忘了一大半.真正需要的是去"试"代码, ...

最新文章

  1. 数据库安全性之使用命令来实现用户管理以及角色.十五
  2. 【C 语言】数组 ( 指针数组用法 | 菜单选择 )
  3. Can't connect to MySQL server on 'localhost' (1...
  4. 服务器所有文件,检索服务器端文件夹中的所有文件
  5. 前端学习(769):new关键字执行过程
  6. 密钥协商(密钥交换)机制的讲解
  7. JS-数组-声明方式-读写添加删除-遍历
  8. amoeba实现mysql主从读写分离_利用Amoeba实现MySQL主从复制和读写分离
  9. 即插即用!开源项目【云框架】发布“基于Spring cloud的微服务架构”
  10. 修复数码相片祛除红眼
  11. 问题 I: Sequence Problem : Array Practice
  12. PMOS做固态继电器,PMOS做高侧双向开关电路,PMOS防电流倒灌电路,PMOS电源防反接电路
  13. 垃圾邮件是什么样的邮件
  14. 在原生js中的,table表格,display:block之后,样式混乱
  15. raid卡组不同raid_Linux 软件阵列与低端硬件阵列卡性能对比
  16. 脚踏实地才能仰望星空
  17. 讲座录播及课件|Tamer Özsu教授:图处理-全景式视角和开放性问题
  18. 中国卫生和无菌阀市场趋势报告、技术动态创新及市场预测
  19. 用touchstart、touchmove、touchend简陋实现左右滑动【触摸事件】
  20. 矩阵分块与矩阵乘法的理解

热门文章

  1. Session 钝化机制
  2. 最简洁用EXCEL公式实现身份证验证
  3. Python进阶读书笔记之(四) set集合
  4. Excel快捷键大全 Excel2013/2010/2007/2003常用快捷键大全【转】
  5. 操作系统--内存管理超详细整理!
  6. C++覆盖(override)
  7. 几何公差基础知识之平面度
  8. 重装win10专业版系统
  9. 分享下nirsoft提供的注册表工具
  10. 用c语言求20以内的勾股数,C语言求勾股数代码及解析