vn.py量化社区
By Traders, For Traders.
Member
avatar
加入于:
帖子: 173
声望: 18

接下来是比较核心的部分

CtpTdApi(TdApi)

缓存变量

  • 状态变量:包括控制连接、登录、授权、连接失败,四个控制变量,比如connect_status
  • 用户信息:比如userid
  • frontid;sessionid[用于形成唯一order序号,由Thost回调提供]
  • reqid;order_ref[vnpy内部维护,用于发单等编号]
  • order_data;trade_data[这两个list用于保存第一次私有流委托等回报的data]
  • sysid_orderid_map用于
  • symbol_\exchange_map;symbol_name_map;symbol_size_map[这三个是全局dict,用于在合约代码、交易所、合约名称、合约大小之间形成映射]

逻辑流程

先明确作为一个交易接口,TdApi需要实现什么功能:

  • 首先tdapi需要能够正常连接到ctp服务器,即执行连接、登录操作
  • 其次tdapi需要在第一次连接后查询各个交易所可交易合约并保存到vnpy本地;查询账户资金情况;查询持仓情况;查询当前报单情况;查询当前成交情况;
  • 最后就是通过交易接口进行一些基础的下单操作,并且得收到服务器多次响应。
     
    其次要明确CTP交易接口如何实现这些功能
    由于客户端和期货公司CTP服务器在通讯过程中设计多种模式,先初步介绍一下CTP通讯模式
    CTP-API涉及的通讯模式有三种:对话通讯模式;私有通讯模式;广播通讯模式。而不同的通讯模式又支持不同的数据流,具体体现在函数命名规则上
  • 对话通讯模式:客户端主动发起请求,服务器端给予相应回应,该模式支持对话数据流和查询数据流。前者指的是客户端向服务器发送交易请求,包括登录、报撤单等,Api命名规则为Reqxxx;后者指的是客户端向服务器发送查询请求,比如报单查询、合约查询等,命名规则为ReqQryxxx。
  • 私有通讯模式:CTP后台主动向某个特定客户端发出信息,该模式支持私有数据流,并且仅有响应接口OnRtnxxx,没有请求接口,包含成交回报报单回报各种错误回报。成交回报指的是报单状态信息变化后CTP主动向客户端发送回报信息。
  • 广播通讯模式:CTP后台主动向所有客户端发出信息,比如合约交易状态通知
    私有流和交易接口又相关关联,比如通过对话流进行报单录入,不仅会收到报单相应OnRspOrderInsert,当报单交易状态发生变化时,又会自动调用OnRtnOrder
     

CTP实现一个交易接口的功能可以分成几部分:初始化、初次查询、报单录入、撤单、委托成交回报

  • 初始化
    connect(初始化连接)--> onFrontConnected(连接响应,嵌套authenticate) --> onRspAuthenticate(授权成功,嵌套login) --> login(实际触发reqUserLogin) --> onRspUserLogin(登录回报,嵌套投资者结算结果确认reqSettlementInfoConfirm,交易接口和行情接口区别之一在于交易接口在客户端成功登录ctp后会主动进行私有流\公有流回报OnRtnxxx,并且比投资者结算结果响应还要早)
    完成上述操作后交易接口初始化完成,但仍然不适合直接进行交易,还需要进行初次查询,而vnpy直接将这两种操作互相嵌套了。
    :初始化最后会自动调用onRtnOrder和onRtnTrade作为私有流回报。原生OnRtnOrder只用于返回报单信息,通知客户端报单的最新状态.vnpy重载形成onRtnOrder,想要实现的功能包括第一次连入Thost后将挂单缓存到本地,vnpy发出的报单得到的委托成交回报也缓存到本地。
    具体逻辑为 :和order相关的vnpy内部数据结构有OrderRequest,OrderData.OrderData向vnpy上层事件引擎推送信息,来源于Thost回调的data数据,通过预定义的dict映射成OrderData.OrderRequest是策略层下底层发单用到的对象,和OrderData区别在于不包含接口信息。由于Thost的委托回报自身没有交易所信息(空字段),并且vnpy三个映射字典是通过reqQryInstrument完成的(比第一次私有流回报晚),因此OnRtnOrder函数需要同时考虑几种情况
      - 第一次连入Thost:将onRtnOrder返回的CThostOrderField数据缓存在self.order\_data中
      - 在onRspQryInstrument内部:在最后一次查询合约完成后,vnpy内部三个映射dict已经全部缓存完成,这时将order\_data中的各个CThostOrderField手工推送到onRtnOrder中
      **onRtnOrder完成的功能**:将Thost推送的委托回报数据包装成OrderData推送到gateway中;将委托回报的orderid和OrderSysID记录成映射
    
     
  • 初次查询
    除了嵌套在初始化中的查询合约,vnpy还对账户信息和仓位进行轮询。查询结果全部封成vnpy内部数据结构推送给gateway。
     
  • 报单
    在vnpy系统里,上层传到底层的报单对象为OrderRequest,然后在gateway层将其转化为ctp所需要的dict对象(pybind会把dict变成C++里的struct)。
    报单指令是ReqOrderInsert,CTP所需要的报单对象有如下成员:
      - InstrumentID,ExchangeID,LimitPrice,VolumeTotalOriginal(数量)
      - OrderPriceType(订单价格类型,比如限价等,vnpy支持限价、市价、stoop、FAKFOK)
      - Direction(买卖方向)
      - CombOffsetFlag(组合开平标志,一般用不到)
      - OrderRef(报单引用,作为报单的标识之一,vnpy内部会维护)
      - InvestorID(投资者代码),BrokerID(经纪商代码)
      - ComHedgeFlag(组合投机套保标志,一般用不到)
      - ContingentCondition(触发条件,比如立即、止损等,vnpy默认使用“立即”)
      - IsAutoSuspend(自动挂起标志,bool类型,默认是False,不知道干啥的,不重要)
      - TimeCondition(有效期类型,包含FOK、当日有效、本节有效、指定日期前有效、撤销前有效、集合竞价有效,vnpy发单默认使用“当日有效”)
      - VolumeCondition(成交量类型,vnpy默认使用任何数量)
      - MinVolume(vnpy默认最小成交数量是1)
    
    以上是报单基础类型,可以根据OrderRequest.type进行diy,比如变成FAK或者FOK,只需要更改TimeCondition和VolumeCondition
      - FAK = 立即完成所有数量否则撤销
      - FOK = 立即完成任何数量否则撤销
    
    报单涉及到一组唯一序号,由FrontID、SessionID、OrderRef组成,前两个是在登录后ctp默认分发的,vnpy会自动缓存,第三个vnpy在每次报单操作后会自动++1递增。这三个成员组成了某一个接口中独一无二的order编号orderid。而在往上层推送的是利用OrderRequest.create_order_data生成的OrderData对象,多出了vt_symbol,vt_orderid等信息。
    至此,一次报单请求操作已经完成。
Member
avatar
加入于:
帖子: 2
声望: 1

学习了 学习了

Member
加入于:
帖子: 22
声望: 1

学习

Member
avatar
加入于:
帖子: 3
声望: 0

学习了!

© 2015-2019 上海韦纳软件科技有限公司
备案服务号:沪ICP备18006526号-3