http://blog.sina.com.cn/s/blog_56e7157f01016ri2.html

自从综合交易平台(CTP)的API开放以来,很多人开始编写自己的程序化交易系统,今天我想说说自己的一些看法。
    首先解读一下CTP的接口说明,CTP的API使用建立在TCP协议之上FTD协议(《期货交易数据交换协议》)与交易托管系统进行通讯,而交易托管系统负责投资者的交易业务处理。FTD 协议中规定了所有的通讯都基于某一种通讯模式。

交易涉及的通讯模式共有三种:

1.对话通讯模式,是指由会员端主动发起的通讯请求。该请求被交易所端接收和处理,并给予响应。例如报单、查询等。这种通讯模式与普通的客户/服务器模式相同。

2.私有通讯模式,是指交易所端主动,向某个特定的会员发出的信息。例如成交

回报等。

3.广播通讯模式,是指交易所端主动,向市场中的所有会员都发出相同的信息。

例如公告、市场公共信息等。

CTP的交易API提供了两个接口,分别为CThostFtdcTraderApi 和CThostFtdcTraderSpi

我们自己开发的交易系统通过CThostFtdcTraderApi向CTP发送操作请求,通过CThostFtdcTraderSpi接收CTP的任何响应。

现在把主要的业务举例在下表中

业务举例

通讯模式

CThostFtdcTraderApi

CThostFtdcTraderSpi

登录

对话模式

ReqUserLogin

OnRspUserLogin

报单录入

ReqOrderInsert

OnRspOrderInsert

报单查询

ReqQryOrder

OnRspQryOrder

成交查询

ReqQryTrade

OnRspQryTrade

报单回报

私有模式

OnRtnOrder

成交回报

OnRtnTrade

行情涉及的通讯模式共有两种:

1.对话通讯模式,同交易一样,是指由会员端主动发起的通讯请求。该请求被交易所端接收和处理,并给予响应。例如登录,退订等。

2.广播通讯模式,主要是行情订阅,当订阅行情后交易所端主动向会员连续主动发出行情信息。

业务举例

通讯模式

CThostFtdcMdApi

CThostFtdcMdSpi

登录

对话
模式

ReqUserLogin

OnRspUserLogin

行情订阅

广播

模式

SubscribeMarketData

OnRspQryDepthMarketData

行情退订

对话模式

UnSubMarketData

OnRspUnSubMarketData

可见,通过CTP提供的接口,我们可以向CTP发送业务申请,也不断的按照三种通讯模式中的其中一种接收CTP的响应。因此我们写的交易系统中至少就应该有两个线程,一个称其为主业务线程,负责对CTP发出业务申请;另一个线程为API工作线程,负责接收CTP通过广播通讯模式,对话通讯模式,私有通讯模式其中一种模式对交易系统的响应。

综上所述,我们的程序化交易系统需要完成的业务可以划分为:

1.基本操作,比如登录,订阅等;

2.行情操作,比如对行情数据的接收,存储等

3.订单操作,比如报单;对报单,成交状况的查询;报单,成交状况的私有回报等。

4.数据监听和处理操作,比如接收到新数据之后的统计处理,满足统计条件后的报单处理(其实这里就是我们的策略所在)

那么,我建议将我们的程序化交易系统分为四个线程,分别处理上述业务。程序的主线程就可以完成基本操作,完成登入,订阅等初始化工作。

其它三个线程工作关系如下图所示:

程序化交易系统是一个复杂的多线程网络程序,在开发过程中要特别注意处理很多的线程互斥、数据处理造成的网络丢包等一系列棘手问题。另外,对于CTP开发的资料,大家可以留言给我,我尽量提供,也欢迎大家多多讨论。

本文开始先说说CTP给开发者提供了什么。CTP提供给开发者的文件一共有4个头文件 ThostFtdcTraderApi.h,ThostFtdcMdApi.h,ThostFtdcUserApiStruct.h,ThostFtdcUserApiDataType.h 和2个dll:thosttraderapi.dll,thostmduserapi.dll(动态链接库,如果是静态库则是thosttraderapi.lib,thostmduserapi.lib)。
    其中ThostFtdcTraderApi.h定义了交易请求接口CThostFtdcUserApi和交易事件处理接口CThostFtdcUserSpi;
    ThostFtdcMdApi.h定义了行情请求接口CThostFtdcMdApi,行情事件处理接口CThostFtdcMdSpi;
    ThostFtdcUserApiStruct.h定义了接口方法中用到的数据结构。
    ThostFtdcUserApiDataType.h定义了数据结构中用到数据类型,枚举描述。
    开发者通过CThostFtdcUserApi就可以完成交易接口的初始化,登入,确认结算结果,查询合约,查询资金,查询持仓,报单,撤单等业务操作;通过CThostFtdcUserSpi获取相应回报
    开发者也可以通过CThostFtdcMdApi完成行情接口的初始化,登入,订阅,收行情等业务;通过CThostFtdcMdSpi获取相应的行情业务操作的回报。
   上文提到了基于CTP的程序化交易系统开发最好要有四个线程:
1.完成初始化及退出操作的主线程;
2.行情接受和处理线程;
3.新行情数据监听和处理线程;
4.订单管理线程
现在先讨论一下主线程的初始化工作。初始化工作包括交易接口和行情接口两部分,对于交易接口的初始化,程序必须完成如下步骤:
1, 产生一个CThostFtdcTraderApi实例
2, 产生一个事件处理的实例
3, 注册一个事件处理的实例
4, 订阅私有流
5, 订阅公共流
6, 设置交易托管服务的地址。
初始化过程的时序图如下:

对于行情接口的初始化工作要简单一些,因为接口默认就订阅了公有流和私有流,初始化过程的时序图如下:

接下来就是行情接收和处理线程,行情的接收是通过CThostFtdcMdApi::SubscribeMarketData()完成对行情的订阅,通过CThostFtdcMdSpi::OnRtnDepthMarketData()完成对于行情数据的接收。此线程的工作主要要完成如下三个方面:
1.行情数据的存储:由于SubscribeMarketData()可以对多个合约行情进行订阅,所以在接收到数据后的处理首先要考虑对不同合约的数据分别以合适的方式(这里合适的方式是指存取,遍历,查询,增删等操作最为稳定快速的算法)存储。
2.行情数据的补齐:这是一个相当重要的问题。当tick数据为空的时候,必须以合适的方式补齐(因为缺失的数据对后来的统计指标计算有较大的影响,所以数据补齐是相当考究的)。
3.最新行情数据到来时向数据监听线程发出信号。
   在下一文中我将讨论一下剩余的数据监听和处理线程和订单管理线程。

最近比较忙,好容易今天事情少点,赶紧继续写博客,谢谢大家的关注。
   接到上篇说哈,本文讨论一下数据监听线程和订单管理线程做些什么。
   一,数据监听线程
   数据监听线程,当行情处理线程接收到新的行情数据时,也就是每当一个tick到来时,就向数据监听线程发出信号,触发此线程启动,然后依次进行:
1.各种指标计算,
2.然后进行策略计算,
3.最后在满足策略时进行交易。
   指标计算,就是指根据新到来的数据以及历史数据进行某些统计值的计算,比如常见的MA,MACD,RSI等,当然也可以自己构造出某个统计值。这里需要提到的是数据周期的问题(我在之前的博文中曾解释过)。如果指标计算是基于数据周期,那么对于行情数据就要进行数据的拼装,也就是说将每一tick数据(500毫秒)拼装成你所需要的数据周期(也就是拼装成K线),然后将每个周期(每根k线)中的open,high,low,close计算出来,以便进行统计值的计算。
   策略计算就是将你的计算出来的指标,按照你自己的交易思想,交易策略进行逻辑的组合,然后在满足策略逻辑的时候进行交易。
   这里我建议一下架构,就是不要将指标计算和策略计算以及交易写到一个函数里面,而是将每一个指标计算写成一个函数,然后分别用函数指针指向它;然后策略计算以及交易写成一个函数,然后用函数指针指向它,并将其压入一个堆栈,此后每添加一个指标,就将指标对应的函数指针压入堆栈;

当每次数据监听线程启动时就依次弹出每个指标并计算,最后完成策略函数。
  二,订单管理线程
    订单管理线程,主要是用于处理订单管理中的两个问题:
    1.订单队列的管理,一般按照报单的时间先后顺序用数组等数据结构进行管理,原则是每一个业务请求要准确对应其回报,每一组请求和回报要准确的对应其归属的订单。其关键就在于业务请求编号和交易序列号。
    业务请求号是指发送请求时设定的RequestID,TraderApi返回响应时返回相关请求的RequestID。因为TraderApi是异步实现的,终端程序可能连续发出多个请求和查询指令。RequestID可以把请求/查询指令和相关的回报关联起来。
    而交易序列号是组合而成的。从报单到成交的交易过程中,会产生如下几组交易序列号:
FrontID + SessionID + OrderRef
    用户使用这组交易序列号可以按照自己的方式来唯一标示发出的任何一笔委托。用户登入成功后,会收到前置机编号FrontID, 会话编号SessionID 和最大报单引用MaxOrderRef。用户在报单时设定报单引用OrderRef。 OrderRef可以从MaxOrderRef开始递增。如果用户没有设定OrderRef,在报单响应中,Thost会为用户设置一个的OrderRef。使得每个报单的这组序列号保持唯一。
    通过这个交易序列号,就可以确定委托回报和成交回报的归属,也可以使用这组交易序列号进行撤单操作。
2.订单的各种状态的管理:在回报中,订单的状态有很多种,请参考ThostFtdcUserApiDataType.h,我建议根据其含义归纳为这五种状态:报单中,已成交,撤单中,已撤单,出错,因为这五种状态对于策略逻辑的完成是至关重要的。
    下面说一下订单交易的机制与时序。先给出一个时序图:

其中,报单响应和回报的机制是当Thost收到报单指令,如果没有通过参数校验,拒绝接受报单指令。用户就会收到OnRspOrderInsert消息,其中包含了错误编码和错误消息。如果Thost接受了报单指令,用户不会收到OnRspOrderInser,而会收到OnRtnOrder,用来更新委托状态。交易所收到报单后,通过校验。用户会收到OnRtnOrder、OnRtnTrade。如果交易所认为报单错误,用户就会收到OnErrRtnOrder。
    撤单响应和回报和报单响应和回报相似。当Thost收到撤单指令,如果没有通过参数校验,拒绝接受撤单指令。用户就会收到OnRspOrderAction消息,其中包含了错误编码和错误消息。如果Thost接受了撤单指令,用户不会收到OnRspOrderAction,而会收到OnRtnOrder,用来更新委托状态。交易所收到撤单后,通过校验,执行了撤单操作。用户会收到OnRtnOrder。如果交易所认为报单错误,用户就会收到OnErrRtnOrderAction。

基于CTP的程序化交易系统开发相关推荐

  1. 基于CTP的程序化交易系统开发(二)

     本文开始先说说CTP给开发者提供了什么. CTP提供给开发者的文件一共有4个头文件 ThostFtdcTraderApi.h,ThostFtdcMdApi.h,ThostFtdcUserApiS ...

  2. 基于CTP的程序化交易系统开发(一)

     自从综合交易平台( CTP)的 API开放以来,很多人开始编写自己的程序化交易系统,今天我想说说自己的一些看法.     首先解读一下 CTP的接口说明, CTP的 API使用建立在 TCP协议 ...

  3. 基于CTP的程序化交易系统开发(三)

     本文讨论一下数据监听线程和订单管理线程做些什么.     一,数据监听线程     数据监听线程,当行情处理线程接收到新的行情数据时,也就是每当一个tick到来时,就向数据监听线程发出信号,触发 ...

  4. 基于CTP的程序化交易系统开…

    原文地址:基于CTP的程序化交易系统开发(一)作者:ronalgao 自从综合交易平台(CTP)的API开放以来,很多人开始编写自己的程序化交易系统,今天我想说说自己的一些看法.     首先解读一下 ...

  5. 基于Android校园跳蚤市场交易系统的设计与实现

    小跳蚤 大用途 前言: 算一算时间又快到了一年一度的毕业设计了吧,我也差不多完成我自己的毕业设计一年了,在此推出我的毕业设计成果以供后来的学弟学妹参考.都说站在巨人肩膀上,更上一层楼,在枯燥的编程期间 ...

  6. java ctp行情_javaCtp: java版本期货程序化交易系统,包括行情服务,交易服务会逐步完善...

    java_vnpy 介绍 java版本期货程序化交易系统,包括行情服务,交易服务会逐步完善,CTP版本上期技术官网下载6.3.15 穿透式, 目前项目无架构设计,只针对ctp进行封装调用,实现基本交易 ...

  7. 基于MT4的 国内期货交易系统 150ms

    基于MT4的 国内期货交易系统 成交速度150ms!!!!! 开发试用中,联系方式Q群:459504288 需提交模拟CTP账户 密码 全品种开放

  8. 交易系统开发之行情数据总结

    一.行情数据简介 1.行情数据简介 行情数据是交易过程中最基本.最重要的部分.一次完整的交易通常分为三个步骤:接收行情.分析行情(策略部分).发出买卖指令并成交(算法交易部分).对于高频交易和低延迟交 ...

  9. 基于Java毕业设计在线交易系统源码+系统+mysql+lw文档+部署软件

    基于Java毕业设计在线交易系统源码+系统+mysql+lw文档+部署软件 基于Java毕业设计在线交易系统源码+系统+mysql+lw文档+部署软件 本源码技术栈: 项目架构:B/S架构 开发语言: ...

最新文章

  1. MySQL 规范及优化
  2. 基于RSSI利用KNN位置指纹法的室内定位(卡尔曼滤波)及代码
  3. 巨头间未来战争-丰收节交易会·万祥军:农业AI发展概况
  4. 点融产品 VP 赵征宇:增长是一个探索人性的过程
  5. iOS 相册权限绕过漏洞
  6. [开源] FreeSql.Tools Razor 生成器
  7. gitlab 安装gitlabrunner 无法连接tiller_谈一谈GitLab Runner是个什么东东?
  8. 【华为云实战开发】9.如何进行PHP项目的快速搭建并实现CICD?
  9. springboot获取当前服务ip_springboot(6)——整合日志
  10. java获取数据库当前时间_java中获取系统的当前时间
  11. 如何解决struts2没有提示问题
  12. Oracle几种清除数据的方式,在平台用别的医院数据库做初始化时有用
  13. 数据结构与算法书籍汇总(从小白到大神)
  14. matlab检验数据异方差,怀特异方差检验方法在matlab中的实现,以及广义最.....
  15. 太可怕了!上海交大毕业的网易前员工曝身患重病后,被残酷裁员!
  16. CentOS 8 安装tc流量控制工具
  17. ROS编译依赖配置问题记录
  18. hive中时间类date函数
  19. ELK安装过程记录,监听netflow和sflow的配置文件编写
  20. css中overflow属性失效,页面始终不能滚动显示溢出的内容

热门文章

  1. 第十四届全国大学生电工数学建模竞赛A题-高比例风电电力系统储能运行及配置分析
  2. C语言 求众数 程序
  3. 配置tomcat下载sis,sisx文件
  4. JDK8新特性-Map遍历比较
  5. MySql Sharding:分表、分库、分片和分区
  6. Revit Lookup 2018版本 安装教程
  7. html年会抽奖代码实例,基于JavaScript实现简单抽奖功能代码实例
  8. 腾讯云认证,腾讯云架构高级工程师,腾讯云高级运维工程师 考试通过
  9. 软件开发的步骤和流程
  10. 【Python】 Python编程基础练习100题学习记录第二期(11~20)