就像2020年总结提到,最近想在中高频策略搞搞。对于高频交易,如果有深度行情当然是必须的,看到说上期所五档行情免费提供,而且我用其他行情软件可以查到,就想在VNPY保存到数据库先研究下。有点发现,写下来记录下。
首先看了下代码,VNPY的ctp_gateway已经支持五档行情接收,也不需要什么配置,但是没有发现五档行情数据,无论是界面端还是数据库。
然后研究下,因为ctp_gateway行情接收是采用继承接口被调用的模式,是由CTP API工作线程驱动;没法被直接debug,倒是可以直接插入print方法输出。发现是有返回值,但是是1.79769313486232e+308这样的溢出值,被一个VNPY专门写静态方法adjust_price给过滤掉了。顺便说下,1.9.2版本也实现ctp五档行情读取,不过要改改ctp_gateway代码,把上期所加入。
我想是不是VNPY封装的CTP接口太老呢,不支持呢,因为看Github历史记录是2年前更新的。就研究了下CTP-API,发现原来是由下面几个点要注意,稍微说下。
首先按照CTP-API接口文档说的支持的通讯模式有三种:对话通讯模式,私有通讯模式,广播通讯模式,
对话通讯模式
对话通讯模式是指由会员端主动发起的通讯请求。该请求被交易所端接收和处理,并给予响应。例如报单、查询等。这种通讯模式与普通的客户/服务器模式相同。CTP-API中的命名Req------或者ReqQry------这样都是发起API
私有通讯模式
私有通讯模式是指交易所端主动,向某个特定的会员发出的信息。例如成交回报等,一般是On-----这样名字,也是上面提到继承接口被CTP调用。
广播通讯模式(公有流)
广播通讯模式又称公有流,是指交易所端主动,向市场中的所有会员都发出相同的信息。例如公告、市场公共信息等。另外,广播模式是不能在公网搞得,ctp所说的广播就是针对在对应所有会员也就是期货公司的内网广播。
但是,在CTP-API文档里面很明确的说明,五档行情是使用组播模式,针对同一组的机器进行广播。
二代组播行情(下文简称二代行情):交易所以组播方式提供的实时五档行情。因为是组播,所以接收端必须在内部网络并且要加入组播组。
目前交易所不允许投资者直接连接交易所报盘网去接收组播行情,如果期货公司将行情转发出来给投资者使用,投资者便能享受到快速的组播行情。我和我期货公司沟通,必须要把机器放在期货公司委托机房才可以接收转发组播的五档行情。这边补充下,查了些文档,组播也可以在公网搞,但是因为UDP没有确认,容易掉包,CTP-API提供增量方法来保证针对这个情况加以弥补,但是很少期货公司提供公网组播,比较吃了不讨好,如果那个提供我就去开户了,哈。
就算机器放在托管机房了,还有一个地方要设置,就是设置订阅组播行情前置,CTP-API方法如下
static CThostFtdcMdApi CreateFtdcMdApi(const char pszFlowPath = "", const bool bIsUsingUdp=false, const bool bIsMulticast=false);
各类型行情字段组合如下:
bIsUsingUdp bIsMulticast
TCP行情前置 false false
UDP行情前置 true false
组播行情前置 true true
那么说,五档行情时候必须参数bIsUsingUdp和bIsMulticast都为True才可以。
我看了下VNPY 2.1.8的ctp-api,vnctpmd.h头文件的接口是createFtdcMdApi(string pszFlowPath = ""),没有提供bIsUsingUdp和bIsMulticast参数录入。可能是vnpy封装的CTP-API的版本太老,因为6.3.15api中的好像最早版本的行情部分并不支持二代,必须自己拼接。
总结下,就是要拿到免费五档行情,需要机器放在托管机房,另外ctp行情订阅必须把bIsUsingUdp和bIsMulticast都为True,对于VNPY需要重新封装以下CTP-API,更新下ctp_gateway。