下单时CTP报错,2022-04-21 09:00:01,123 INFO: 交易委托失败,代码:15,信息:CTP:报单字段有误,这是什么原因,具体如截图,
MTF wrote:
夜盘时段归属在第二天交易日内,所以日盘加载昨天夜盘数据,就类似于当天日内下午启动加载之前上午的数据,一个原理
是这个逻辑没错,主要是rqdata的数据一天清洗一次,清新前后数据可能会有差异,所以当天8:45和16:00加载的前一天夜盘数据可能会出现不一致的情况
vnpy的期货策略,Demo给的策略启动时间为8:45-15:00及20:45-2:45,而策略启动一般都需要加载前置数据,即load_bar(n),而vnpy推荐使用rqdata的数据,而rqdata的数据清洗完成一般在下午4点左右,早上启动时,rqdata前一天的夜盘数据还未清洗,所以可能会出现实盘和回测信号不一致的问题,所以在此请教下有经验的友友是怎么解决这个问题的,十分感谢!
郭易燔 wrote:
首先要看接口是否支持保证金查询,以ctp为例的话。查询返回值data中只使用了六个字段。
在从c++接口获取数据时是获取了所有字段的,这里的字段都是可以用的。
具体每个字段的含义可以看这个结构体。
感谢你的详细解答,上次问的问题也是你帮我解答的,太感谢了!
求助,请问vnpy如何获取占用保证金,调用get_all_accounts,只查到balance,也就是动态权益,有没有获取占用保证金的方法
郭易燔 wrote:
不行。
- 无论是tick还是bar都推荐在下新单之前把所有之前未成交的单都撤销掉,不然一来会错失交易机会,二来对订单的管理容易出错
- 所以t时刻的tick就在t+1时刻的tick判断
- 就算1分钟的bar也包含很多tick,很可能在你下单的tick之前,你的成交机会就已经没了,所以不能用来判断。
了解了,这个判断的逻辑,一直困扰了我好久,真的太感谢你了~
郭易燔 wrote:
不好意思,上一句说的有点问题。
1.简单来说,为了避免未来函数的问题。t时刻的委托只有在t时段走完,到达t+1时刻才能确定是否成交。
2.在t+1时刻你才看到t时间段内全部的数据
3.这里是在t+1时刻里先将数据更新为t时段的k线数据,然后对t时刻的指令进行撮合,最后再发出t+1时刻的指令。
如果还是有疑惑的话可以看一下官方的cta视频教程,里面会有更详细的解释。
豁然开朗,太感谢你的回答了!不过如果我的信号是基于截至到t-1时刻的bar,在实盘是根据tick来下单,而tick只是当前bar的中间某个时刻,这逻辑对应的回测,是不是可以根据当前时刻bar的最高价最低价来判断是否能成交?再次感谢!
郭易燔 wrote:
1.实盘的撮合时由交易所来执行的,委托会直接发给交易所,本地不进行撮合。
- backtesting是回测功能代码,实盘代码在engine中。
- 回测的撮合可以简单理解为,如果上个委托价格在上一根bar的最高最低价之间,则可以成交。否则,这单就不能成交。
再次感谢回答,“如果上个委托价格在上一根bar的最高最低价之间,则可以成交”,如果是这个逻辑,那是没问题的,
如图所示,new_bar先把self.bar置为当前bar,再去判断上个委托价格的,所以是判断了上个委托价格是否在当前这一根bar的最高最低价之间,而不是上一根bar的最高最低价之间,这就让我很难理解
郭易燔 wrote:
self.cross_limit_order()和self.cross_stop_order()是用来撮合成交的。而判断一个订单能否成交,依靠当前时间点的是无法判断的,只有下一个时间点才能判断。所以先要撮合上一个时间点的订单。再去调用当前时间点的策略回调。
感谢回答,但是按照这个逻辑,如果实盘是在on_tick里下单,对应的是当前的bar,价格是在当前bar范围内,是否根据当前bar撮合成交,backtesting是不是针对回测用bar的close_price下单,所以需要通过下一根bar来判断?
一直没搞懂,为什么在backtesting的new_bar里,self.cross_limit_order()和self.cross_stop_order()是写在self.strategy.on_bar(bar)前面,on_bar里进行下单,订单信息存到self.active_limit_orders里,在下一次new_bar去判断上一次self.active_limit_orders的订单能不能成交,就是上一根bar下的单,用了当前bar的价格去判断,为什么要这么写?难道self.cross_limit_order()和self.cross_stop_order()不应该放在self.strategy.on_bar(bar)后面吗?
xiaohe wrote:
那请自己打印排查一下吧
所以理论上是不会漏数据吗?如果在盘中启动策略,load_bar(10)还没执行完,新的on_bar的数据会存到哪里?
还发现一个问题,在盘中开启策略,load_bar会导致实盘的on_bar丢失数据,如下截图,10点05开启策略,10点12才load_bar完成,中间的数据没了
pin wrote:
xiaohe wrote:
ctp接口是不提供历史数据的,要配置数据服务或者数据库里有历史数据才能拉取成功
load_bar函数文档里有详细介绍https://www.vnpy.com/docs/cn/cta_strategy.html#cta-ctatemplate
了解,多谢,补充一个问题,如果在盘中启动策略,比如9点45分启动,初始化load_bar(10)需要2分钟,也就是9点47分才会初始化完成,那9点46分的bar数据会怎么处理?
9点46分的on_bar会触发交易吗?还有所有on_bar的bar数据都会存到database.db里吗?我在源码貌似没看到触发on_bar后将数据写入数据库的操作
xiaohe wrote:
ctp接口是不提供历史数据的,要配置数据服务或者数据库里有历史数据才能拉取成功
load_bar函数文档里有详细介绍https://www.vnpy.com/docs/cn/cta_strategy.html#cta-ctatemplate
了解,多谢,补充一个问题,如果在盘中启动策略,比如9点45分启动,初始化load_bar(10)需要2分钟,也就是9点47分才会初始化完成,那9点46分的bar数据会怎么处理?
所以结论就是策略on_init时load_bar(10)能不能加载历史10天数据是gateway决定的?
问题跟进:跟踪源码,MainEngine在初始化的时候添加了LogEngine,OmsEngine,EmailEngine三个Engine,其中OmsEngine在初始化时register_event包含一个process_contract_event,然后CtpGateway connect包括td_api.connect(交易服务器连接)和md_api.connect(行情服务器连接),在td_api.connect成功后,调了一个init(),也就是vnpy_ctp下的vnctptd.py的init(),触发了OmsEngine的process_contract_event,把所有的contract信息存到OmsEngine内部维护的self.contracts字典里,在策略on_init() load_bar(10)的时候,进入CtaEngine的load_bar方法,会调用self.main_engine.get_contract(vt_symbol),即OmsEngine的get_contract方法,把OmsEngine内部的self.contracts对应的值查询出来,而self.contracts存放的是ContractData对象,所以ContractData里各个字段的值都是交易所返回的?对比了一下ETHUSDT.BINANCE和rb2201.SHFE的区别,前者ContractData里history_data为True,后者为False,True则会去查询历史数据,False则不会,再配上如下截图:
xiaohe wrote:
你是说没有获取历史数据成功的日志输出吗?
不仅日志没有输出,load_bar(10)的时候on_bar也没走
rb2201.SHFE截图如下,并没有加载10天历史数据
补充:vnpy版本是最新的2.5.0,ETHUSDT.BINANCE是BinanceUsdtGateway,截图如下: