CTP开发爬坑指北(一)

01

行情和交易API中的TradingDay交易日规则是怎样的?

CTP行情API推送的行情快照中,有TradingDay和ActionDay两个表示日期的字段,分别表示交易日和实际日期。因为夜盘的交易时段是属于下一天白天的日盘的交易日的,因此如果是2024年4月12日(星期五)晚上的夜盘,则它属于4月15日(下个星期一)的交易日。而实际上夜盘中不同交易所的设置规则不尽相同,具体值如下表所示。

夜盘TradingDay和ActionDay
TradingDayActionDay
上期所/能源中心(SHFE/INE)20240415下周一20240412周五
大商所/广期所(DCE/GFEX)20240415下周一20240415下周一
郑商所(CZCE)20240412周五20240412周五

可以看出,只有上期所/能源中心的两种日期,是与真实值相一致的。开发时可取用它们的合约的行情快照中的日期作为交易日和实际日期。另外,SimNow环境里所有交易所都是使用和上期所相同的规则

另一个取巧一些的办法是,取用程序所在本地机器的系统日期作为实际日期,而由于夜盘是晚上9点开盘,因此交易日取用"当前时间 + 4小时"的日期(需特殊处理周五-周一的情况),这个交易日的取值对于日盘也是有效的。

如果使用交易API,则可以从交易API的登录响应数据中获取交易日,虽然行情API中的登录响应中也有交易日,但它是空值。交易API在有账户登录成功以后,也可以使用静态函数 GetTradingDay() 获取交易日。

交易API中的一些接口中,例如OnRtnTrade成交通知,OnRtnOrder报单通知等,也有TradingDay字段,它们都是准确的。

交易API的OnRtnTrade成交通知中,有成交日期TradeDate字段,它本意是表示成交的实际日期,但和上面的ActionDay一样,TradeDate各个交易所的设置规则不一样,可使用上述相同的办法来处理成交实际日期。

02

如何确定订单的唯一性?

换而言之,如何撤单?

订单有三种key,都可以用来撤单,这里直接就说是哪三种key。

第一种方法,使用 ExchangeID + OrderSysID 撤单(推荐使用哦

CTP未来版本的API(7.0版本,还未发布),在报单和撤单时,强制需要填写ExchangeID交易所代码,因此这种撤单方法暗合未来的CTP需求,实际只需要程序保存维护OrderSysID这一个字段。

OrderSysID报单编号是一个字符串,内容是数字,例如"    012865",即可能是右对齐的形式。生产环境里,不同的交易所的规则稍有不同,例如有的交易所是没有右对齐的,而且也不一定都是只有6位数字。不建议对它的空格部分进行截断处理,完整的保存使用才是最好的。同时,CTP报单的第一个OnRtnOrder回报里面,报单编号是空值,这个是无法拿来撤单的。

第二种方法,使用 FrontID SessionID OrderRef 撤单

用这种方法撤单时,实际还需要填写InstrumentID合约代码。

部分交易所在订单被交易所接收之前(即报单还在被CTP柜台处理中还没送到交易所时),不支持这种撤单方式。

FrontID 和 SessionID是报出这个订单的会话的编号信息,在OnRtnOrder报单通知中可以获取到。当以后新版本的CTP发布时,这种撤单方法还需要添加填入ExchangeID字段。

OrderRef报单引用和上面说的OrderSysID报单编号类似,都是"读作字符串,写作整数"。如果需要自行维护OrderRef,则需要保持递增,否则报单会失败,提示"重复的报单"。另外需要指出的是,OrderRef本质是一个有符号32位整数(有测试发现部分期货公司CTP柜台使用的是64位整数,但建议仍按32位整数来处理),是允许有负数的,超出它的范围( -2147483468 到 2147483467 )的数字,可能会被CTP服务器端判定为0从而不符合规则导致报单失败。

第三种方法,使用 ExchangeID + TraderID OrderLocalID 撤单

TraderID是交易所交易员代码,并不是TradeID成交编号,注意它多出一个"r"字母。

除了上述的三种可用于撤单的key之外,如果是为了将收到的OnRtnOrder报单通知和发出的订单请求对应起来,其实还可以用RequestID字段一键对应。这个整数字段在OnRtnOrder的报单数据中也有返回,返回的值与报单时填写的RequestID值相同。需注意的是,RequestID不是nRequestID(报单请求函数的参数,很多CTP请求函数都有nRequestID参数),别把二者混淆!报单失败时的响应函数OnRspOrderInsert的参数中,nRequestID会出现,值与报单时填写的nRequestID值相同。

RequestID != nRequestID

但是,用RequestID来对应,虽然简单好用,却有一个缺点(同时也是优点?)——CTP允许有重复的RequestID。因此如果程序没有维护好,在下单时使用了重复的RequestID,就会产生重复的key无法将报单通知和请求一一对应了。同时,只用RequestID也无法区分同一个账户的不同会话之间的下单。

03

如何将成交和订单关联起来?


 

由上面的第2点引申出一个问题:成交通知OnRtnTrade中,如何将这笔成交和此前的订单关联起来?

OnRtnTrade中,和订单唯一性有关的数据有OrderSysIDOrderRefTraderID 和 OrderLocalID,但缺失了FrontID SessionID,因此用第一种和第三种方法都可以直接将成交和订单关联起来,用它们来保存订单以及撤单是更好的选择。

再插一句,OnRtnTrade成交通知中的Volume成交数量,是这笔成交通知的成交的数量,并不是这个订单的总的成交数量,总成交数量可以去查看报单通知OnRtnOrder中的VolumeTraded字段。举个例子,一个订单的委托数量是4手,分成两次(1手和3手)成交,则第一次OnRtnTrade的Volume是1,第一次OnRtnTrade的Volume是3。

如果是组合合约的订单的成交通知,那么会分成两个单腿合约分别推送OnRtnTrade,即推送至少2次OnRtnTrade。具体可查看此前的介绍组合合约交易的文章:CTP组合合约浅析(下)

04

查询合约手续费率为什么返回品种代码?

如果查询合约手续费率时,返回的响应中的合约代码是品种代码,说明这个合约的手续费率是按品种通用的费率设置的。例如,查询"IF2409"合约的手续费率,而返回的是"IF",说明你的沪深300股指2409合约的手续费率是和沪深300股指品种通用的费率。

与此类似的,如果返回的InvestorID是"000000",则说明这个费率是所有投资者通用的费率,经纪商并没有对你这个账号单独设置费率。

另外需指出,查询得到的手续费率,以及保证金率,都是账户最终的费率,而不是交易所标准的费率。交易所标准的保证金率可通过查询合约进行查询,在其响应OnRspQryInstrument中查看多头和空头的保证金率。

查询上述两种费率时,如果填写的合约代码为空值,则返回的是持仓中的各个合约的对应费率。换而言之,如果要知道市场所有合约的费率,则需要逐个合约查询费率。

05

各个交易所的持仓的平仓顺序是什么?

大商所和郑商所和广期所:先开先平,优先平昨。但如果平今手续费有减免,则优先平今。

中金所:同上,先开先平,优先平昨。但是,计算平仓的手续费时,按优先平今仓的规则来计算手续费。

上期所和能源中心:自己下单时指定平今仓还是平昨仓。今仓和昨仓各自的内部也是先开先平。

拿一个中金所的股指期货举例:

简单的假设IF2409合约,开仓和平昨仓是20元每手,而平今仓是300元每手。

账户有IF2409多头昨仓2手。今天先继续开仓IF2409买入1手。

这样就总共有3手持仓,其中2手是昨仓,1手是今仓。

此时卖出平仓1手。根据上面的规则,这平掉的1手是昨仓。

因此还剩下1手昨仓和1手今仓。

但是,收取的手续费是按平今来计算的。

然后继续卖出平仓1手。根据上面的规则,这平掉的1手仍是昨仓。

因此还剩下0手昨仓和1手今仓。

由于在此前的1手平仓计算手续费时,已经按平今来计算了,今仓已经平仓完了,所以此次平仓就按平昨来计算手续费。

因此手续费是 20 (开仓) + 300 (平今) + 20 (平昨) = 340 元。

可以用这种方式来理解:在计算手续费的系统中,也有一套虚拟持仓,不过它的维护规则是优先平今仓,今仓平完以后再平昨仓。真正的持仓系统和这套虚拟持仓系统并行运行,后者只是为了算手续费来使用的。

真实持仓数量虚拟持仓数量总手续费
昨仓数今仓数昨仓数今仓数

初始持仓

20200
买入开仓1手 之后212120
卖出平仓1手 之后112020+300
再卖出平仓1手 之后011020+300+20

因此,如果是为了把股指期货的手续费算准,可以用这套"计算手续费专用"的虚拟持仓系统和它的维护规则。

欢迎加入QQ群736174420一起沟通交流CTP API的使用!~

  • 42
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
CTP(中国金融期货交易所)是国内比较重要的期货交易平台,目前已经成为了全球最大的期货市场之一。对于高频交易者来说,CTP是一个非常重要的平台,因为它提供了高效、稳定的交易接口。 以下是一些CTP高频开发教程: 1. CTP官方文档:在开始进行CTP高频开发之前,建议您先熟悉CTP的官方文档。这些文档包括CTP API接口文档、CTP交易规则、CTP交易指南等。这些文档可以帮助您了解CTP的基本知识和API的使用方法。 2. CTP开发环境配置:在开始开发之前,需要安装CTP开发环境。CTP提供了多种语言的API接口,包括C++、Python、Java等。根据您的编程语言选择相应的API接口,并按照官方文档进行环境配置。 3. CTP高频交易策略开发:在掌握CTP的基本知识和API接口之后,可以开始进行高频交易策略的开发。高频交易策略的开发需要考虑到市场行情、交易规则、风险控制等多方面因素。可以参考一些已有的交易策略,并进行优化和改进。 4. CTP高频交易系统搭建:在开发完高频交易策略之后,需要将其部署到一个稳定的交易系统中。可以使用一些流行的开源框架,如vnpy、pyctp等,进行高频交易系统的搭建。 5. CTP高频交易系统测试与优化:在完成交易系统的搭建之后,需要进行一些测试和优化工作。测试可以包括回测、实盘测试等。通过优化,可以提高交易系统的效率和稳定性。 以上是CTP高频开发的一些基本教程,希望能对您有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值