CTP报单中, 包含条件单和预埋单两种不同的特殊报单种类, 这里给大家解析一下.
条件单
CTP条件单的本质是, 触发条件后, 以你报入的报单的其他参数(报单价格, 报单数量等), 立即自动下一个普通的单子. 条件单报入后, 是储存在期货公司机房服务器中, 不同期货公司对CTP条件单的支持情况不同, 比如可以报入的条件单的数量等, 建议先咨询你的期货公司.
CTP条件单的报单接口和普通报单一样, 都是ReqOrderInsert.
一个单子是否是条件单, 取决于ContingentCondition和StopPrice两个参数.
其中, ContingentCondition是触发条件, 条件单应当根据你的触发条件需求填入THOST_FTDC_CC_LastPriceGreaterThanStopPrice(最新价大于条件价)等宏, 注意不能填THOST_FTDC_CC_Touch(止损)或THOST_FTDC_CC_TouchProfit(止盈). 具体支持哪些触发条件, 需要咨询你的期货公司. 不过一般常见的THOST_FTDC_CC_LastPriceGreaterThanStopPrice(最新价大于条件价)等触发条件都是支持的. StopPrice在注释中是止损价, 实际是触发价格, 即当触发你所设置的触发条件的价格.
这里需要说明的是:
-
条件单不止可以用于止损, 还可以用于止盈或开仓等.
-
条件单的其他字段含义和普通报单相同.
-
StopPrice和LimitPrice没有关系, 后者是条件单触发产生的新报单的报单价格, 二者可以相等, 也可以不等.
下图是一个条件单的示例:
报入条件单后, 也像普通单一样, 会收到报单通知(OnRtnOrder回调), 其中"报单状态"(OrderStatus)有THOST_FTDC_OST_NotTouched(尚未触发)和THOST_FTDC_OST_Touched(已触发)这两种特殊的值, 以标识这个条件单是否已触发. 条件单的报单编号(OrderSysID)一般以"TJBD_"(即"条件报单"的拼音首字母)开头, 以与普通报单的报单编号区分开来.
触发后, 自动产生的新报单由于是服务器发出, 并非API客户端发出, 所以新报单的报单通知中的SessionID和FrontID的值都是0. 新报单的报单通知中的"相关报单"(RelativeOrderSysID)的值, 与触发其的条件单的报单编号(OrderSysID)相同, 以揭示其是由哪个条件单触发产生的新报单. 更多条件单内容,回复"条件单"获取
预埋单
预埋单是一种能且仅能在非交易时间(集合竞价前或交易节之间的休息时间)报入, 并在新的交易时段开始时被自动触发并执行一定指令的一种指令。它包含预埋报单和预埋撤单. 简单地说, 就是只能在非交易时间进行的提前下单或撤单.
预埋报单或撤单在被触发后即转化为一个普通的报单或撤单指令, 之后的处理过程与报单或撤单过程完全一样.
预埋报单(Parked Order Insert)被触发时, 一个新的报单被报入交易所. 预埋报单使用的函数是 ReqParkedOrderInsert。报单数据结构为 CThostFtdcParkedOrderField, 字段与与报单数据结构CThostFtdcInputOrderField类似. 预埋报单的用法与报单类似, 但是只有响应函数而没有报单回报推送函数, 对应的响应函数为 OnRspParkedOrderInsert, 响应中的数据结构也是CThostFtdcParkedOrderField (CTP偷懒了
), 与报单通知中的数据结构略为不同的是, ParkedOrderID(预埋报单编号)代替了OrderSysID(报单编号), 作为预埋单的报单编号, 可以用来删除此预埋报单, 另一个重要字段是预埋单状态(Status), 有三种类型的值: THOST_FTDC_PAOS_NotSend(未发送, 即未触发), THOST_FTDC_PAOS_Send(已发送, 即已触发), THOST_FTDC_PAOS_Deleted(已删除), 标识此预埋报单的状态.
TIPS: 预埋报单本身没有报单通知, 即预埋报单的报入, 触发, 删除等都不会有通知, 只能通过查询等方式获知预埋报单的情况, 这可能会对多处同时登录API的业务处理造成一定影响. 预埋撤单也是类似.
预埋撤单(Parked Order Action)被触发时, 一个撤单指令被报入交易所, 请求撤销某笔已经存在的报单(并不是撤销预埋报单). 预埋撤单使用的函数是ReqParkedOrderAction. 对应的响应函数为 OnRspParkedOrderAction, 其中的数据结构是CThostFtdcParkedOrderActionField, 和预埋撤单函数的数据结构相同(CTP又偷懒了
), 其中的预埋撤单单编号(ParkedOrderActionID), 可以用来删除此预埋撤单, 同时也有预埋撤单状态(Status), 取值的类型与预埋报单相同.
预埋报单和预埋撤单都可以删除, 删除预埋报单使用的函数是ReqRemoveParkedOrder, 用来删除已经报入但未触发的预埋报单. 删除预埋撤单使用的函数是 ReqRemoveParkedOrderAction, 用来删除已经报入但未触发的预埋撤单. 删除预埋单使用的关键字段在前面介绍预埋报单和预埋撤单时已经提及, 不再赘述.
预埋报单和预埋撤单都可以查询, 查询预埋报单的函数是 ReqQryParkedOrder, 对应的响应函数是 OnRspQryParkedOrder. 查询预埋撤单的函数是 ReqQryParkedOrderAction, 对应的响应函数 OnRspQryParkedOrderAction.
和条件单类似,预埋报单时并不检测预埋单子的合法性, 例如用户可以预埋报单去平用户没有持有的合约持仓. 但是预埋撤单会检测撤单的合法性(允许重复撤同一个单子, 撤单使用的字段组合最好是ExchangeID+OrderSysID组合, 在SimNow测试使用FrontID+SessionID+OrderRef+InstrumentID组合无法通过检测). 预埋单报入后储存在期货公司机房服务器中, 使用预埋单前建议咨询下期货公司的支持情况. 预埋报单被触发后报入交易所的新报单的SessionID和FrontID为0, 报单引用(OrderRef)也是由CTP系统自动生成. 不过, 与条件单(RelativeOrderSysID字段关联)不同, 预埋单没有可以与其触发产生的新报单互相关联起来的字段, 不是很方便.
最后是一个小测验:用预埋单下一个条件单!