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

1. 现象见图中描述

description

1.1 这是接口的错误?

在cta_gateway.py中send_order()函数中,找到出错语句前增加下面的调试打印:

        self.reqid += 1
        print(f"ctp_req={ctp_req}")    # 调试打印
        self.reqOrderInsert(ctp_req, self.reqid)

得到ctp_req的内容如下:

ctp_req={
    'InstrumentID': 'ag2012', 
    'ExchangeID': 'SHFE', 
    'LimitPrice': 6093.0, 
    'VolumeTotalOriginal': 8, 
    'OrderPriceType': '', 
    'Direction': '1', 
    'CombOffsetFlag': '3', 
    'OrderRef': '1', 
    'InvestorID': '147102', 
    'UserID': '147102', 
    'BrokerID': '9999', 
    'CombHedgeFlag': '1', 
    'ContingentCondition': '1', 
    'ForceCloseReason': '0', 
    'IsAutoSuspend': 0, 
    'TimeCondition': '3', 
    'VolumeCondition': '1', 
    'MinVolume': 1
    }

这里面的内容只有最为可疑:

'OrderPriceType': '',

2. 为什么会出错?

2.1 停止单分为两种:

  • 服务器停止单:需要交易所支持,直接可以发送服务器处理
  • 本地停止单:交易所不支持,由本地应用来维护

2.2 CTA的网关目前只处理两类委托请求:

ORDERTYPE_VT2CTP = {
    OrderType.LIMIT: THOST_FTDC_OPT_LimitPrice,   # 限价类型
    OrderType.MARKET: THOST_FTDC_OPT_AnyPrice # 市价类型
}
ORDERTYPE_CTP2VT = {v: k for k, v in ORDERTYPE_VT2CTP.items()}

2.3 用户的CTA策略的停止单是有CtaEngine维护的

用户的CTA策略发送委托停止单的过程:

    1. 调用CtaTemplate的send_order()
    1. 再调用CtaEngine引擎的send_order()
    1. CtaEngine引擎区分委托请求时 限价单还是停止单,
    1. CtaEngine引擎通过过请求中合约的contract,得知是否支持服务器停止单,如果支持直接调用main_engine中ctp_gateway发送到服务器,否则有引擎保存到本地进行维护
    1. CtaEngine引擎中的本地停止单被触发时,CtaEngine引擎把当触发停止单转化未涨停板或跌停板限价单,调用main_engine中ctp_gateway发送到服务器
    1. ctp_gateway对vnpy委托请求OrderRequest中的OrderType进行映射,得到接口识别的请求类型OrderPriceType,OrderPriceType目前只接受两个类型:THOST_FTDC_OPT_LimitPrice和THOST_FTDC_OPT_AnyPrice。
    1. 转化后委托请求ctp_req其实是个字典,然后通过交易接口TdApi发送给交易服务器

3. 假如你从Main_Window(主界面)直接发送停止单,问题就来 !

3.1 Main_Window直接发送停止单过程:

  • 1 系统是直接调用ctp_gateway,它不识别服务器是否支持
  • 2 系统它不会把该停止单发送到CtaEngine引擎,因为你可以压根就没有启动CtaEngine引擎模块,怎么调用?
  • 3 委托请求OrderRequest中的OrderType='STOP',在ORDERTYPE_VT2CTP字典中就没有键值,产生出来的接口请求类型OrderPriceType=''
  • 4 于是就出错啦!!!

3.2 结论:

目前在主界面中是不可以发送任何停止单的!!!
目前在主界面中是不可以发送任何停止单的!!!
目前在主界面中是不可以发送任何停止单的!!!

重要的话说三遍

4. 发送委托停止单出错的修改建议:

  • 1 类型映射错误,就算是服务器停止单支持,我敢断言也会出错,因为OrderPriceType=‘’ 肯定是不可以被接口接受的,这个需要改!
  • 2 主界面中发送的停止单,没有做服务器是支持的判断,如果不支持也的话也无人维护。那么是否可以把下级应用cta_engine的对本地停止单的维护,上提到main_engine中来执行?
  • 3 CTA策略都可以发委托单,为什么手工却不让做呢 ?这么好的功能,应该人工也享受享受!

已经分析过了,那么是否可以改进呢?

Administrator
avatar
加入于:
帖子: 4191
声望: 236

嗯。。。因为CTP柜台本身把停止单功能给关了,手动交易要用的话可以通过AlgoTrading模块的StopAlgo来实现

Member
avatar
加入于:
帖子: 170
声望: 29

老师:
就算CTP柜台没有把停止单功能给关了,OrderPriceType字段也是必填字典,现在这种ORDERTYPE_VT2CTP字典也是映射不到有效值的,也是出错。很多人都碰到主界面中无法下停止单的问题,困惑不已。1)要不在主界面中下单类型一栏不提供'STOP'选项;2)要不就在MainEngine中维护本地停止单,使得手动也可以下单。你看看这两个建议是否可以可行?

Administrator
avatar
加入于:
帖子: 4191
声望: 236

确实是,我们在CTP接口里增加个对于STOP类型委托的报错日志吧,比直接抛异常友好一些

Administrator
avatar
加入于:
帖子: 4191
声望: 236

已在DEV分支修改

Member
avatar
加入于:
帖子: 170
声望: 29

老师 :
在AlgoTrading模块里面如果没有使用StopAlgo策略的话,选择其他策略,下单类型为STOP也是会出错的,因为AlgoTrading模块连本地停止单都没有维护,它也会立即出错。
这么看来不管CTA策略模块,还是AlgoTrading模块,也许还有其他app模块,可能都会有下停止单的需要,如果能够把本地停止单的维护上提到main_engine的话,不光是CTA策略模块可以下本地停止单,AlgoTrading模块也可以下本地停止单,对AlgoTrading模块的策略编写是否就更多一种非常有用的下单手段。您觉得是否有道理?

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