CTP-API开发系列之八:报撤单代码实现

CTP-API开发系列之八:报撤单代码实现

  • CTP-API开发系列之八:报撤单代码实现
    • 前情回顾
    • 函数实现
      • 缓存FrontID 和 SessionID
      • 报单函数实现
      • 撤单函数实现
    • 调用示例
      • 报单(形成挂单)
      • 对挂单进行撤单
      • 报单(立即成交)
      • 注意事项
      • 委托、成交映射关系
      • 分笔成交情况
    • 日志截图
    • 下节预告

CTP-API开发系列之八:报撤单代码实现

前情回顾

在前面的章节,分享了交易API认证登录以及基础数据查询的代码流程(CTP-API开发系列之六:交易登录及查询流程),并介绍了报撤单及回报顺序(CTP-API开发系列之七:报撤单及回报顺序),这节继续分享报单、撤单相关的代码实现。

函数实现

在之前代码基础上,新增以下类成员变量:

# 登录成功,从响应结构体中获取,用于报单跟踪
FrontID = 0
SessionID = 0
# 报单引用编号:递增,使用时需转成字符串
MyOrderRefInt = 1000# key: str(FrontID) + "_" + str(SessionID) + "_" + OrderRef
# value: CThostFtdcInputOrderField
MyOrders = {}

缓存FrontID 和 SessionID

def OnRspUserLogin(self, pRspUserLogin: 'CThostFtdcRspUserLoginField', pRspInfo: 'CThostFtdcRspInfoField', nRequestID: 'int', bIsLast: 'bool') -> "void":log.info("OnRspUserLogin: " + api_struct_serialize(pRspUserLogin))if not pRspInfo.ErrorID:# 登录成功,从响应结构体中获取,用于报单跟踪self.FrontID = pRspUserLogin.FrontIDself.SessionID = pRspUserLogin.SessionID

报单函数实现

### 具体枚举值见CTP-API头文件ThostFtdcUserApiDataType.h
def ReqorderfieldInsert(self, InstrumentID, EXCHANGEID, DIRECTION, OFFSET, PRICE, VOLUME):"""报单操作"""orderfield = api.CThostFtdcInputOrderField()orderfield.BrokerID = BROKERIDorderfield.UserID = USERIDorderfield.InvestorID = USERIDorderfield.OrderRef = self.getOrderRef()  # 报单编号:从1000递增,使用时需转成字符串orderfield.ExchangeID = EXCHANGEIDorderfield.InstrumentID = InstrumentIDorderfield.Direction = DIRECTIONorderfield.CombOffsetFlag = OFFSETorderfield.LimitPrice = PRICEorderfield.OrderPriceType = api.THOST_FTDC_OPT_LimitPrice # 限价orderfield.VolumeTotalOriginal = VOLUMEorderfield.ContingentCondition = api.THOST_FTDC_CC_Immediatelyorderfield.TimeCondition = api.THOST_FTDC_TC_GFDorderfield.VolumeCondition = api.THOST_FTDC_VC_AVorderfield.CombHedgeFlag = api.THOST_FTDC_HF_Speculationorderfield.ForceCloseReason = api.THOST_FTDC_FCC_NotForceCloseorderfield.IsAutoSuspend = 0# 本地报单记录key = f"{self.FrontID}_{self.SessionID}_{orderfield.OrderRef}"self.MyOrders[key] = orderfieldself.tapi.ReqOrderInsert(orderfield, 0)log.info("send ReqOrderInsert key: " + key)log.info("send ReqOrderInsert: " + api_struct_serialize(orderfield))

撤单函数实现

撤单有两种方式,官方文档推荐使用第一种

  1. 第一种方法,使用OrderSysID撤单
  2. 第二种方法,使用FrontID+SessionID+OrderRef撤单
def ReqorderfieldAction(self,OrderSysID,ExchangeID,InstrumentID):"""撤单操作(第一种方式OrderSysID)"""orderfield = api.CThostFtdcInputOrderActionField()orderfield.BrokerID = BROKERIDorderfield.UserID = USERIDorderfield.InvestorID = USERIDorderfield.OrderSysID = OrderSysIDorderfield.ExchangeID = ExchangeIDorderfield.InstrumentID = InstrumentIDorderfield.ActionFlag = api.THOST_FTDC_AF_Deleteself.tapi.ReqOrderAction(orderfield, 0)log.info('send ReqOrderAction: ' +  api_struct_serialize(orderfield))

调用示例

报单(形成挂单)

在 OnRspQryInstrument 合约查询回调函数中,合约查询完成后调用(bIsLast==True)

# rb2405 合约:买入开仓 3手 委托价格3600(低于最新价形成挂单,用于撤单)
self.ReqorderfieldInsert("rb2405", "SHFE", api.THOST_FTDC_DEN_Buy, api.THOST_FTDC_OF_Open, 3600, 3)

对挂单进行撤单

在 OnRtnOrder 报单回报函数中,对上述产生的挂单-“未成交”状态的单子进行撤单操作

def OnRtnOrder(self, pOrder: 'CThostFtdcOrderField') -> "void":log.info("OnRtnOrder: " + api_struct_serialize(pOrder))key = f"{pOrder.FrontID}_{pOrder.SessionID}_{pOrder.OrderRef}".replace(' ', '')# 本地报单回推流if key in self.MyOrders.keys():log.info(f'local order: {key}')log.info(f' InstrumentID:{pOrder.InstrumentID},Direction:{pOrder.Direction},CombOffsetFlag:{pOrder.CombOffsetFlag},OrderSubmitStatus:{pOrder.OrderSubmitStatus},VolumeTraded:{pOrder.VolumeTraded},VolumeTotal:{pOrder.VolumeTotal},LimitPrice:{pOrder.LimitPrice},OrderStatus:{pOrder.OrderStatus},StatusMsg:{pOrder.StatusMsg}')## 如果未成交,5秒后主动撤单if pOrder.OrderStatus is api.THOST_FTDC_OST_NoTradeQueueing:thread = threading.Thread(target=self.ReqorderfieldAction, args=(pOrder.OrderSysID,pOrder.ExchangeID,pOrder.InstrumentID))thread.start()thread.join()## 如果已撤单,修改价格重新报单if pOrder.OrderStatus is api.THOST_FTDC_OST_Canceled:# rb2405 买入开仓 3手 委托价格3630(高于最新价立即成交,从OnRtnTrade可以看到最终成交价格为3628self.ReqorderfieldInsert("rb2405", "SHFE", api.THOST_FTDC_DEN_Buy, api.THOST_FTDC_OF_Open, 3630, 3)# 外部报单回推流else:log.info('outside order: ' + key)log.info(f' InstrumentID:{pOrder.InstrumentID},Direction:{pOrder.Direction},CombOffsetFlag:{pOrder.CombOffsetFlag},OrderSubmitStatus:{pOrder.OrderSubmitStatus},VolumeTraded:{pOrder.VolumeTraded},VolumeTotal:{pOrder.VolumeTotal},LimitPrice:{pOrder.LimitPrice},OrderStatus:{pOrder.OrderStatus},StatusMsg:{pOrder.StatusMsg}')

报单(立即成交)

同样还是在 OnRtnOrder 报单回报函数中,对上述“已撤单”成功后,进行新的报单操作。

以下是simnow快期3软件上,这两笔委托单的截图,方便对照验证:

注意事项

第二笔报单价格3630,最终撮合成交的价格是3628。最终成交价格在OnRtnOrder 是没有的,需要在 OnRtnTrade 成交回报推送函数中获得

def OnRtnTrade(self, pTrade: 'CThostFtdcTradeField') -> "void":log.info("OnRtnTrade: " + api_struct_serialize(pTrade))

委托、成交映射关系

1.报单前唯一标识维护:FrontID+SessionID+OrderRef,并进行缓存
# 本地报单记录
key = f"{self.FrontID}_{self.SessionID}_{orderfield.OrderRef}"
self.MyOrders[key] = orderfield
如下日志截图中两笔单子的唯一标识分别是:“1_-172308391_1000”和“1_-172308391_1001”2.在OnRtnOrder函数中可以找到这三个字段:FrontID+SessionID+OrderRef
同时会有 ExchangeID、OrderSysID 等字段(当报单被交易所拒绝后,交易所不会分配OrderSysID,此时仍要使用第1组序号跟踪报单)3.在OnRtnOrder函数中没有第1组序号,需要使用2中的 ExchangeID、OrderSysID,跟踪报单最终的成交价(Price)

分笔成交情况

在simnow环境中不会产生分笔成交的情况,在这里我从实盘环境中,做了一个分笔成交的情况,重点需要关注OnRtnOrder函数中的OrderStatus、VolumeTraded、VolumeTotal字段的变化情况,以及OnRtnTrade函数中Volume字段的变化情况。

以下截图报了一笔10手的单子,OnRtnOrder函数回调了7次;OnRtnTrade 函数回调了4次:
在这里插入图片描述

/// 具体枚举值见CTP-API头文件ThostFtdcUserApiDataType.h
/
///TFtdcOrderStatusType是一个报单状态类型
/
///全部成交
#define THOST_FTDC_OST_AllTraded '0'
///部分成交还在队列中
#define THOST_FTDC_OST_PartTradedQueueing '1'
///部分成交不在队列中
#define THOST_FTDC_OST_PartTradedNotQueueing '2'
///未成交还在队列中
#define THOST_FTDC_OST_NoTradeQueueing '3'
///未成交不在队列中
#define THOST_FTDC_OST_NoTradeNotQueueing '4'
///撤单
#define THOST_FTDC_OST_Canceled '5'
///未知
#define THOST_FTDC_OST_Unknown 'a'
///尚未触发
#define THOST_FTDC_OST_NotTouched 'b'
///已触发
#define THOST_FTDC_OST_Touched 'c'
typedef char TThostFtdcOrderStatusType;/
///TFtdcOrderSubmitStatusType是一个报单提交状态类型
/
///已经提交
#define THOST_FTDC_OSS_InsertSubmitted '0'
///撤单已经提交
#define THOST_FTDC_OSS_CancelSubmitted '1'
///修改已经提交
#define THOST_FTDC_OSS_ModifySubmitted '2'
///已经接受
#define THOST_FTDC_OSS_Accepted '3'
///报单已经被拒绝
#define THOST_FTDC_OSS_InsertRejected '4'
///撤单已经被拒绝
#define THOST_FTDC_OSS_CancelRejected '5'
///改单已经被拒绝
#define THOST_FTDC_OSS_ModifyRejected '6'
typedef char TThostFtdcOrderSubmitStatusType;

日志截图

在这里插入图片描述

下节预告

交易相关常用的功能基本已经实现完成,上述报撤单对期权也是支持的,只需要传递不同的期权合约参数。后面会分享行权和自对冲相关业务的代码。

相比交易API的功能,行情API的功能就要简单的多了,后面在分享行情API代码的基础上,会与交易API的demo进行结合,实现一个简易的自动化交易程序(当行情满足一定条件自动进行报单,并按照设定的条件自动进行止盈止损)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/274348.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

XSS靶场-DOM型初级关卡

一、环境 XSS靶场 二、闯关 1、第一关 先看源码 使用DOM型&#xff0c;获取h2标签&#xff0c;使用innerHTML将内容插入到h2中 我们直接插入<script>标签试一下 明显插入到h2标签中了&#xff0c;为什么不显示呢&#xff1f;看一下官方文档 尽管插入进去了&#xff0…

系统运维网络知识汇总

一、系统运维中网络方面的规划与思考 系统运维建立在网络的基础之上&#xff0c;如果没有一个相对合理的网络架构&#xff0c;恐怕系统运维做起来也不是那么的顺手。一个公司基本上都会把网络和服务器独立开来&#xff0c;划分不同的区域摆放设备&#xff0c;很多时候都是物理…

基于Android的高校移动成绩查询系统的设计与实现

摘 要 在我国现今状态&#xff0c;互联网呈现出的高速发展状态以及高等教育的教学不断改革下&#xff0c;各高校的教务管理系统都已经从传统的纸质方式转向了基于Internet的绿色管理方式。而对于目前各高校所使用的都是浏览器/服务器&#xff08;B/S&#xff09;模式&#xff…

短视频解析接口分发系统,附带系统搭建教程

搭建教程 宝塔面板&#xff1a;Nginx系统 php7.2 Mysql 5.6-5.7 伪静态Thinkphp 上传文件直接访问域名安装即可 解析接口推荐&#xff1a;ce.qsy.mobi 源码免费下载地址抄笔记

JavaSE面试——类集框架List/Set/Queue

Collection 集成体系 Map 集成体系 List 和 Map、Set 的区别 1. 结构特点 1.存储数据类型&#xff1a; List 和 Set 是存储单列数据的集合&#xff0c;Map 是存储键和值这样双列数据的集合 2. 存储特点&#xff1a; List&#xff1a;存储数据有顺序&#xff0c;允许重复 …

kibana配置 dashbord,做可视化展示

一、环境介绍 这里我使用的kibana版本为7.17版本。 语言选择为中文。 需要已经有es&#xff0c;已经有kibana&#xff0c;并且都能正常访问。 二、背景介绍 kibana的可视化界面&#xff0c;可以配置很多监控统计界面。非常方便&#xff0c;做数据的可视化展示。 这篇文章&…

鸿蒙App基础

基础说明 .1、应用模型 .1.1、构成要素 应用组件 应用组件是应用的基本组成单位&#xff0c;是应用的运行入口。用户启动、使用和退出应用过程中&#xff0c;应用组件会在不同的状态间切换&#xff0c;这些状态称为应用组件的生命周期。应用组件提供生命周期的回调函数&…

Android 生成SO - 基础工程创建

最近需要给小伙伴扫盲一下如何使用Android Studio 生成一个SO文件&#xff0c;网上找了很多都没有合适的样例&#xff0c;那只能自己来写一个了。 原先生成SO是一个很麻烦的事情&#xff0c;现在Android Studio帮忙做了很多的事情&#xff0c;基本只要管好自己的C代码即可。 …

数据“隐领”未来!【隐私计算实训营】限时免费招募!

数智经济时代&#xff0c;为强化个人隐私信息保护&#xff0c;国家颁布了《国家安全法》、《网络安全法》、《数据安全法》等数据安全法律法规&#xff0c;并严厉处罚数据违规出海、侵权、滥用等问题。数据安全和隐私保护成为大家的共识。隐私计算技术在此背景下应运而生&#…

物联网云原生云边协同

文章目录 一、物联网平台设计1.物联网平台设计2.物联网平台实现 二、部署环境1.节点配置2.版本信息 三、物联网平台部署1.部署 Kubernetes 集群2.部署 KubeEdge3.部署 ThingsBoard 集群4.部署 ThingsBoard Edge4.1.创建 Edge 实例4.2.部署 PostgreSQL4.3.创建数据库4.4.部署 Th…

【C++】类与对象

文章目录 1. 面向过程与面向对象2. 类&#xff08;class&#xff09;类的作用域 3. 访问限定符封装 4. 类的实例化5. this指针6. 默认成员函数6.1 构造函数6.2 析构函数6.3 拷贝构造函数 1. 面向过程与面向对象 C语言是面向过程&#xff08;procedure-oriented&#xff09;的语…

“成像光谱遥感技术中的AI革命:ChatGPT应用指

遥感技术主要通过卫星和飞机从远处观察和测量我们的环境&#xff0c;是理解和监测地球物理、化学和生物系统的基石。ChatGPT是由OpenAI开发的最先进的语言模型&#xff0c;在理解和生成人类语言方面表现出了非凡的能力。本文重点介绍ChatGPT在遥感中的应用&#xff0c;人工智能…

数字脉搏:互联网的演进与社会脉络

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢&#xff0c;在这里我会分享我的知识和经验。&am…

React-路由小知识

1.默认路由 说明&#xff1a;当访问的是一级路由时&#xff0c;默认的二级路由组件可以得到渲染&#xff0c;只需要在二级路由的位置去掉path,设置index.属性为true。 2.404路由 说明&#xff1a;当浏览器输入ul的路径在整个路由配置中都找不到对应的pth,为了用户体验&#x…

【蓝桥杯】路径之谜(DFS)

一.题目描述 小明冒充 X 星球的骑士&#xff0c;进入了一个奇怪的城堡。 城堡里边什么都没有&#xff0c;只有方形石头铺成的地面。 假设城堡地面是 nn 个方格。如下图所示。 按习俗&#xff0c;骑士要从西北角走到东南角。可以横向或纵向移动&#xff0c;但不能斜着走&#x…

如何在Linux使用Docker部署Firefox并实现无公网IP访问本地浏览器

文章目录 1. 部署Firefox2. 本地访问Firefox3. Linux安装Cpolar4. 配置Firefox公网地址5. 远程访问Firefox6. 固定Firefox公网地址7. 固定地址访问Firefox Firefox是一款免费开源的网页浏览器&#xff0c;由Mozilla基金会开发和维护。它是第一个成功挑战微软Internet Explorer浏…

基于React低代码平台开发:直击最新高效应用构建

&#x1f3e1;浩泽学编程&#xff1a;个人主页 &#x1f525; 推荐专栏&#xff1a;《深入浅出SpringBoot》《java对AI的调用开发》 《RabbitMQ》《Spring》《SpringMVC》《项目实战》 &#x1f6f8;学无止境&#xff0c;不骄不躁&#xff0c;知行合一 文章目录…

浅析开源内存数据库Fastdb

介绍&#xff1a; Fastdb是免费开源内存数据库&#xff0c;其优秀的性能&#xff0c;和简洁的C代码&#xff0c;让我学习使用过程中收益颇多&#xff0c;但是国内中文相关研究的文章相当稀少&#xff0c;外文我查询相当不便。有兴趣的朋友可以通过以下网站访问&#xff1a;Mai…

Redis 内存的优化

目录 前言 Redis 的内存碎片问题 判断Redis 内存碎片 如何清理内存碎片&#xff1f; 前言 我想讲一下怎么提高Redis 内存的利用率&#xff0c;redis 的数据是保存在内存中。对内存的利用率低&#xff0c;意味着存的数据很少&#xff0c;并不意味着就没有内存了&#xff0c…

【办公类-21-09】三级育婴师 视频转文字docx(等线小五单倍行距),批量改成“宋体小四、1.5倍行距、蓝色字体”

作品展示&#xff1a; 背景需求&#xff1a; 一、视频处理 1、育婴师培训的现场视频 2、下载视频&#xff0c;将视频换成考题名称 二、音频 视频用格式工厂转成MP3音频 3、转文字doc 把音频放入“网易云见外工作台”转换为“文字" 等待5分钟&#xff0c;音频文字会被写…