harrymissi wrote:
MTF wrote:
- 没办法,因为柜台没推送
- 你可以在on_start函数下实现挂单逻辑,然后在9:25-29分之间启动策略,来实现初始报单
你好,我试了一下在on_start挂单,我测试了下加了个self.buy(price,1)在这个函数里面,然后在9:27左右去启动,但是在委托里没看到我挂的单,请问这个是怎么回事? 😂
楼上的意思是,你可以在on_start里把要挂的单子的参数写到策略的变量pre_order里面(这个pre_order是自己定义的类成员变量),然后在开盘以后,检测这个变量是否为None,如果不为None,就根据这个参数下单,下单后把那个变量设置为None。
这样就可以实现开盘后再报单了
明白了,Qt只能在主线程里管理UI,而回测是新建的线程,所以在新建的线程里创建UI会导致问题。
哎,暂时用投机取巧的办法,新建个进程来显示了
我想在策略close的时候创建一个窗口,输出我需要的信息,
我尝试在策略的on_close里加入:
widget = QWidget()
...
widget.show()
发现回测的时候会直接卡死。
但是用
widget = QDialog()
...
widget.exec_()
却可以,但是这个时候是个模态对话框,我如何创建非模态的窗口呢?
xiaohe wrote:
cta回测策略设计的就是载入单品种的单频率行情,有多种频率需求可以通过原始数据合成。
如果基于Tick数据回测,需要调用load_tick函数,基于K线数据回测,需要调用load_bar函数,文档也有说过。
如果有自己情况特殊的需求,可以做个性化修改。
好的,谢谢,我做了如下处理,算是一种投机取巧吧
def on_init(self):
print("=====================策略初始化=====================")
if self.is_backtesting:
self.load_bar(10, callback=self.on_testquota)
else:
self.load_bar(10)
# 回测加载历史行情
def on_testquota(self, quota: Union[BarData, TickData]):
if isinstance(quota,BarData):
self.on_bar(quota)
elif isinstance(quota,TickData):
self.on_tick(quota)
我感觉这是一个设计上的缺陷吧,
从函数名字也能看出来,load_bar应该只会载入k线,然而如果周期选的tick,那么load_bar载入的就是tick了而且还会错误传到on_bar里面
同理load_tick也一样。
目前我这样写,不行
def on_init(self):
if self.is_backtesting:
self.load_bar(10)
self.load_tick(10)
else:
self.load_bar(10)
我的直觉是,当回测选择tick的时候,那个load_bar就会失效,选择1m的时候,那个load_tick就会失效。
但是实际情况是:
如果选择tick回测,那个load_bar会把tick数据传到on_bar方法里面,造成错误
同理
选择1m回测,那个load_tick会把bar类型的数据传到on_tick方法里面,也造成错误
代码层面没办法判断回测输入的回测数据类型吗?
我现在只能根据测试反复注释这两句来切换,有点麻烦。
至于为什么会同时支持两种回测,
策略实际交易是根据tick数据来下单的,但是回测下载tick数据太慢,所以做了一个兼容1m k线回测的方案,但有时候也需要比较精确的tick回测。
所以就会遇到回测的时候两种周期
实际tick数据会包含9:00之前的数据,从8:55开始就有可能行情进来了,好像是开盘前的撮合竞价,大多数8:59会有开盘前的行情,这个时候貌似有的交易所能报单,有的会拒单。
我看其它的交易软件,他们都是把9:00开盘前的行情当作是9:00的开盘价,也就是说把8:59的行情合并到9:00的k线上的,包括开盘价和交易量。
虽然实际情况下这一点点影响不大,但是我的策略用到了ArrayManager,着多出来的8:59的tick会导致多一根ma出来,造成策略有问题。
同理,晚上20:59分也是一样的情况
请问一个 比较好的处理方式是什么?
直接在on_tick里判断时间,然后把开盘前的数据过滤掉不传给BarGenerator的update_tick?
或者有其它的办法?
CTA不是有一个pos变量用来存储持仓吗?
如果我通过交易软件平仓了,那pos变量会跟着改变吗?
MTF wrote:
- CTP接口没有,所以跳过
- 看是否配置了RQData之类的数据服务,有则成功返回
- 没有则从数据库尝试加载,成功则返回
没有自动保存,你可以打开DataRecorder模块进行录制
好的,谢谢你
MTF wrote:
策略中on_init函数下要调用的load_bar/load_tick函数就是
所以我的问题是,那个load_bar和load_tick是依赖于datafeed服务,还是说vnpy自己会保存之前的行情?
文档里说的是会“先依次尝试通过交易接口、数据服务、数据库获取历史数据”,CTP交易接口不支持获取历史数据吧,所以应该还是从数据服务获取?
CTA策略实盘的时候,使用load_bar或者load_tick会自动调用datafeed的接口吗?
我是用no ui的方式启动的策略,看官方的示例,到了停盘的时候会停掉对应的子进程,
到了开盘的时候,再重启策略,但ArrayManager的数据怎么办,又得重新初始化?
虽然策略在初始化的时候使用了load_tick或者load_bar,
比如1号启动了策略,到了2号凌晨2点多,策略停止,然后到了2号上午8点45策略重新启动,这个时候load_tick或者load_bar加载的是凌晨停盘前的数据吗?
我记得历史行情需要手动下载的,总不能每次停盘以后就要手动下载停盘之前的数据用于下次启动初始化吧? 所以很疑惑。
解决了,cta引擎要先初始化
使用VeighNa Station创建了工作目录,并且在工作目录里创建了strategies文件夹,把自己的策略文件放里面
在VeighNa Station里能正常加载自己的策略,回测这些都没问题。
但是自己写了个no ui的run.py脚本放工作目录里面,就找不到这个策略类了。
难道no ui的方式不支持工作目录?
但奇怪的是,使用no ui的方式,日志却保存在工作目录里的.vntrader下的log文件夹里了,说明no ui的方式也是认工作目录的啊。
看懂了,如果回测用的tick数据,就不会直接调用on_bar,那个on_bar得通过BarGenerator来调用,所以肯定是同步的。
作为新接触vnpy,现在好奇一个问题,为什么回测的时候需要手动load_tick呢,CTA回测的那个界面不是有选择开始时间和结束时间嘛,为什么还要在代码里手动加载历史行情?感觉有点多此一举额,是有什么特别的考虑嘛
也就是说我的策略是同时基于tick和k线的,
回测的时候,tick数据和k线数据是互相保持同步的?还是各自一股脑推进来的?