这是回测框架的既定规则,不是异步或多品种导致的。
天勤文档《策略程序回测》里“回测时的成交规则和推进”的规则3写得很明确:某个合约订阅的最小 K 线周期大于 1 分钟时,回测框架会隐式再订阅一根 1 分钟 K 线,保证这个合约 quote 的更新周期不超过 1 分钟。
你用的是日线,周期 86400 秒,远大于 1 分钟,所以必然命中这条。表现就是:日线序列本身仍按天推进,但框架额外挂了一根 1 分钟序列,wait_update 也就按分钟往前走了。
这条隐式订阅的触发条件是这个合约存在 quote 需求,来源有两处:
1. 策略里调用了 api.get_quote();
2. 模拟账户给这个合约下单时,会自动为它订阅 quote,文档在规则3下面专门有这条“注意”。
所以策略只要下过单,这根分钟线就一定在。只跑一个品种、只订阅日线也一样,跟异步多品种没有关系;多品种只是每个下单或取行情的合约各补一根分钟线,把循环次数再乘以品种数,所以更慢。
框架为什么非要保证 quote 不超过 1 分钟:回测的撮合规则是报单价格达到对手盘价格才成交,模拟账户的权益和持仓浮盈也要按当前价盯市。如果这个当前价一天才更新一次,日内就没法判断成交了。
这根分钟线没有开关可以关掉。能省的地方有四处:
1. 主循环里只在 is_changing 判断到日线最后一根 K 线的 datetime 变化时才做重活,其余每次 wait_update 空转时尽量不做事;
2. 缩短回测区间、减小 data_length、减少同一轮一起跑的品种数,循环次数是按分钟数乘以品种数增长的,一年下来是几万到十万次的量级;
3. 需要扫参数或批量回测时,用文档里的批量回测方案多进程并行;
4. 如果只需要日线历史数据、不需要撮合,就不要走回测框架,直接用 DataDownloader。
另外提醒一点:天勤的图形化界面是把界面上的订阅请求转发给同一个 TqApi 的,所以界面上挂着的图所用周期也会算进去。如果你确认代码里既没有 get_quote 也没有下单、回测仍然按分钟推进,可以把界面关掉再跑一次,确认是不是它代你订阅了行情。
有其他问题欢迎加入官方Q群748265037一起交流