CTP: 各种错误的测试(补充和修改中)

    一直想总结一下,CTP对各种错误的反馈和机制,由各种原因,总没完成。现开个头,希望慢慢总结,不断测试,不断整理。

一、CTP的报单流程

         根据CTP的介绍,CTP的报单流程如下:

      CTP终端报单指令(ReqOrderInsert)报入CTP后台,首先要经过数据同步状态、会话、报单字段、合约、经纪公司、投资者、是否确认结算单、交易权限、持仓资金检查和冻结、只能平仓权限检查及交易所会话检查等,CTP报单检查失败则通过OnRspOrderInsert返回报单错误(CTP打回的错单),根据CTP介绍,OnRspOrderInsert属于对话通讯模式,即普通的客户/服务器模式,也就是说服务器只会将此类返回信息发送给对应的客户会话,通讯故障发生时,此类数据流也存在丢失的可能。
     通过报单检查的报单指令(ReqOrderInsert),CTP后台会向客户端返回OnRtnOrder消息,其中OrderSubmitStatus为“已经提交”,OrderStatus为“未知”。同时CTP后台将该报单指令转发至对应的交易所系统。交易所系统同样会对报单进行相应的检查,如价格是否超出涨跌停板、报单指令是否试用等等,未通过交易所系统检查的报单,CTP收到交易所系统响应后也会向客户端返回OnRtnOrder消息,其中OrderSubmitStatus为“报单已经被拒绝”,OrderStatus为“撤单”。
     通过交易所系统检查的报单,交易所系统会将对应的报单插入报单薄,并通知CTP后台,CTP收到交易所系统响应后也会向客户端返回OnRtnOrder消息,其OrderSubmitStatus为“已经接受”,OrderStatus为“未成交还在队列中”。
      当成交发生后(全部成交或部分成交),CTP后台将向客户端返回OnRtnTrade消息,同时也会返回OnRtnOrder消息,其中OrderSubmitStatus为“已经接受”,OrderStatus为“全部成交”或“部分成交还在队列中”。

二、CTP对错误的反馈机制的特点

     我个人看,客户端报单要经过三个层次流程,来对报单进行判断。(1)CTP表层判断->(2)CTP深层判断->(3)交易所层次判断.

    按正常理解,Rsp 只作表层判断,Err进行深层判断。但CTP有些并非如此。有些感觉应从Rsp或Err类型的返回的错误,它却从Order层次的状态的变化来表达,而这种“告诉”往往让你感觉有点奇怪,或摸不着头脑。也许CTP有其不得言的苦衷吧。

三、CTP和错误反馈机制相关的主要回调函数:

1、OnRspOrderInsert:报单录入回调,CTP表层判断即报单参数基本的校验,如校验不通过,会收到回调信息。

      (1)典型错误:报单引用是否自增

      (2)典型错误:报单引用是否重复

      (3)典型错误:报单数量错误,如报卖量不足。有“平仓量超过持仓量”等。

      具体信息会在 pRspInfo.ErrorMsg中给出详细的描述。

2、OnErrOrderInsert:报单录入错误回调。


3、OnRtnOrder:报单回调。进行CTP深层判断和交易所层次判断. 

       需要说明的是,在这个回调函数中,事实上,只有报单状态的变化信息,没有错误信息。

     (1)典型错误:非交易时段报单录入。

        Insert阶段告知成功,但CTP会对这种报单进行自动撤单,我个人认为,这个单根本就没有进入交易所层次。还是在CTP层次被拦截了。

     (2)典型错误:报单的价格超过涨停价或跌停价。

      本来应在OnRspOrderInsert反应,但CTP并非如此。CTP认为,它不进行涨跌停价的判断,这个由交易所层次来进行识别。但与此同时,CTP,在OnRtnOrder中,把交易所的传回来的错误反馈在OnRtnOrder中以报单的状态(有二个状态,见下说明)进行调整来表达,但并不传出相应的错误。此时,TFtdcOrderSubmitStatusType的状态为InsertRejected,EnumOrderStatusType的状态为Canceled。

       关于Order中的状态,主要有二个枚举类型,需要我们关注其中可能隐含的错误信息。

      (1)关于报单状态: TFtdcOrderStatusType

    public enum EnumOrderStatusType
    {
        AllTraded = 48,                                          // 全部成交。                                                                                  --->最终状态
        PartTradedQueueing = 49,                      // 部分成交,且还在队列中。说明,部分成交,部分在等待成交。
        PartTradedNotQueueing = 50,                // 部分成交,不在队列中,说明:部成部撤。                                    --->最终状态。
        NoTradeQueueing = 51,                           //未成交,在交易队列中。说明:报单在市场中,但没有成交
        NoTradeNotQueueing = 52,                     // 没有交易 且不在队列中,说明:报单被CTP拒绝。                       --->最终状态
        Canceled = 53,                                           // 报单被取消                                                                                 --->最终状态
        Unknown = 97,                                            // 未知。说明:报单已经被CTP接收,但还没发往交易所。
        NotTouched = 98,                                       // 预埋单未触发
        Touched = 99,                                             // 预埋单已触发
    }

    需要注意的是,上面有四种报单状态是最终状态(即这种状态不会发生变化),其中,NoTradeNotQueueing 是比较特别,我们不常见。

   (2)关于提交状态 : TFtdcOrderSubmitStatusType
    public enum EnumOrderSubmitStatusType
    {
        InsertSubmitted = 48,                             // 报单已提交
        CancelSubmitted = 49,                          //撤单已提交
        ModifySubmitted = 50,                          // 报价修改单已提交
        Accepted = 51,                                      // 已收
        InsertRejected = 52,                              // 报单录入拒绝
        CancelRejected = 53,                           // 撤单拒绝
        ModifyRejected = 54,                            // 报价修改单已拒绝
    }

   这个是针对不同类型的报单(一般报单,撤单,改价单)的几种状态,要么是被提交,要么被接收,要不就是被拒绝三种情况。

       资料引用:见综合交易平台 API 开发FAQ文档。

      39.  如果发送一个报单委托价格在停板之外。按道理如果 CTP 校验失败,那么应该从OnRspOrderInsert 返回错误;如果是交易所校验失败,那么应该从 OnErrRtnOrder 来返
     回错误。现在情况是这两个地方都不返回错误,而是从 OnRtnOrder 返回。然而OnRtnOrder 却没有错误代码,仅是状态改变,没法捕捉异常。其实用户报单后,如果正确根本不会“马上收到报单响应OnRspOrderInsert” ,只有报单被 CTP拒绝才会收到。  
       答:超出涨跌停板的判断是在交易所处理,所以,CTP收到报单就新增一条记录,然后收到交易所的OnErrRtnOrder后, 修改委托表里的记录, 触发 OnRtnOrder。       OnErrRtnOrder的作用是:CTP在检查委托发现错误时,会给发出委托的投资者发出 OnRspInsertOrder,同时发出OnErrRtnOrder给相关的交易员,所以,作为投资者可以不关心 OnErrRtnOrder。  

4、OnRspOrderAction:撤单回调

     (1)

5、OnErrRtnOrderAction:报单错误回调,听说用到很少。

    从实际操作上看,onRspInsert 和OnRtnOrder最需关注的二个回调函数。绝大多数错误在这里面来进行表达。

    以上是个人看法,还需待证实。

  • 3
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
CTPapi_交易开发实例 class CTraderSpi : public CThostFtdcTraderSpi { public: ///当客户端与交易后台建立起通信连接时(还未登录前),该方法被调用。 virtual void OnFrontConnected(); ///登录请求响应 virtual void OnRspUserLogin(CThostFtdcRspUserLoginField *pRspUserLogin, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); ///投资者结算结果确认响应 virtual void OnRspSettlementInfoConfirm(CThostFtdcSettlementInfoConfirmField *pSettlementInfoConfirm, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); ///请求查询合约响应 virtual void OnRspQryInstrument(CThostFtdcInstrumentField *pInstrument, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); ///请求查询资金账户响应 virtual void OnRspQryTradingAccount(CThostFtdcTradingAccountField *pTradingAccount, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); ///请求查询投资者持仓响应 virtual void OnRspQryInvestorPosition(CThostFtdcInvestorPositionField *pInvestorPosition, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); ///报单录入请求响应 virtual void OnRspOrderInsert(CThostFtdcInputOrderField *pInputOrder, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); ///报单操作请求响应 virtual void OnRspOrderAction(CThostFtdcInputOrderActionField *pInputOrderAction, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); ///错误应答 virtual void OnRspError(CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); ///当客户端与交易后台通信连接断开时,该方法被调用。当发生这个情况后,API会自动重新连接,客户端可不做处理。 virtual void OnFrontDisconnected(int nReason); ///心跳超时警告。当长时间未收到报文时,该方法被调用。 virtual void OnHeartBeatWarning(int nTimeLapse); ///报单通知 virtual void OnRtnOrder(CThostFtdcOrderField *pOrder); ///成交通知 virtual void OnRtnTrade(CThostFtdcTradeField *pTrade); private: ///用户登录请求 void ReqUserLogin(); ///投资者结算结果确认 void ReqSettlementInfoConfirm(); ///请求查询合约 void ReqQryInstrument(); ///请求查询资金账户 void ReqQryTradingAccount(); ///请求查询投资者持仓 void ReqQryInvestorPosition(); ///报单录入请求 void ReqOrderInsert(); ///报单操作请求 void ReqOrderAction(CThostFtdcOrderField *pOrder); // 是否收到成功的响应 bool IsErrorRspInfo(CThostFtdcRspInfoField *pRspInfo); // 是否我的报单回报 bool IsMyOrder(CThostFtdcOrderField *pOrder); // 是否正在交易的报单 bool IsTradingOrder(CThostFtdcOrderField *pOrder); };

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值