从回测到全自动实盘交易,全天候策略需要经历哪些改造?

上期咱唠了一个QMT版本的全天候策略,在回测当中是在每个月的第一个交易日调仓,有的小伙伴拿到源码之后,把日期限制去掉,想进行实盘/模拟盘交易,然后等了整整一天,都没有看到策略发信号下单,说是不是自己没有改对,还是策略里面原本就有bug。

我想说呢,你改对了,策略里面也没有bug,可能只是你还没有了解QMT当中,回测机制和实盘机制的差别,特别是对于日线及其以上周期的策略。

全天候策略回测版本的代码大概有200行,而回测实盘一体版的策略代码却足足有600多行,这多出来的2倍代码,就是为了兼容回测和实盘机制当中的差异,那具体都有哪些差异,下面咱慢慢唠~~~

全天候策略运行在回测模式:

全天候策略运行在实盘模式:

一、数据驱动

在回测当中,所有数据都是已知的,QMT会在历史K线上,从左往右遍历一次,根据每个交易日的买卖信号,对模拟账户的资金进行增减变动,模拟出每日持仓盈亏,最终呈现在收益曲线上,根据这条收益曲线,进而统计出累计收益、年化收益、波动率、夏普率、胜率、最大回撤等绩效指标。

在代码层面来说,对于日线回测的全天候策略,逐K运行函数handlebar会在每个交易日被调用一次,而在实盘当中,K线是"未知的",还没有完全形成的,虽然开盘价已知,但是最高价、最低价、收盘价、成交量和成交额都处于变动状态,跟随着实时行情而不断跳动,因此,在QMT的设计当中,handlebar会在每个tick(股票是3秒)的到来都会被调用一次。

也就是说,在回测当中,handlebar函数一天被调用一次,而在实盘当中,交易时间段内,每3秒钟被调用一次,一天大概被调用4800次。

二、下单模式

看到这里,有的小伙伴可能就疑惑了,因为交易下单函数就是放在handlebar里面的,实盘当中handlebar每3秒被调用一次,那应该就是每3秒就下单一次,为何苦等一整天都没见到有一个委托单,这个就要提到QMT当中的下单模式了。

QMT当中下单交易使用的是综合下单函数passorder,其中的一个关键参数叫quickTrade,它是被用来设置是否立即出发下单的,他有三个可选值:0,1,2。

在全天候策略回测版中,这个参数值被设为0,0表示是在K线完全走完后进行交易,在回测中,数据都是已知的,QMT知道K线在哪里走完,所以是在收盘那一刻进行交易。

而在实盘当中,K线是在不断变动当中的,QMT怎么判断这根K线完全走完了呢?就是在下一根K线的第一个tick到来时,就说明上一根K线走完了。也就是说,quickTrade为0的情况下,日线策略在实盘当中,是要等到第二天开盘才会下单交易的,所以这就是苦等一天不见下单的原因。

再说quickTrade为1的情况,此时只要passorder在最新一根K线上被调用就会下单交易,在历史K线上被调用则无效,所以在回测时该参数值不能为1,因为在历史K线上不会下单。

但也不能说在实盘里面直接把quickTrade设置为1就可以了,因为handlebar每3秒会被调用一次,在当天的K线上你就会每3秒下一次单,那酸爽~~~因此,你需要设置一个标志位,下单后立马取反,保证一天就下单一次,或者把交易逻辑放到定时函数run_time当中,在指定的时间里仅交易一次。

最后讲quickTrade设置为2,这个"2"还是要慎用,能不用就不用,这种情况下只要passorder被调用到就立马下单交易,不管是历史K线还是最新K线,不然你一秒钟就可能下单几百笔,接到券商风控电话时,你就知道自己有多2了。

三、委托跟踪

在回测当中,只要你输入的下单价格在当天的最高价和最低价之间,默认就会全部成交,而在实盘当中,这个就不好说了,这个跟你的资金量、行情延迟和订单厚度都有关系,总之就是两个字"难说"。

所以实盘当中就要考虑委托单不成交或者不能全部成交的情况,这就要做好委托状态的跟踪,比如说,委托单成交了,需要更新记录该策略的仓位,如果长时间没有成交,就需要撤单重新下单,下单量是之前订单的剩余委托量。

四、仓位隔离

"仓位隔离"这一点其实是很多新手,甚至是一些老手都可能会忽略的点。在回测时,你获取的策略持仓就是该策略的持仓,但是在实盘时,你用get_trade_detail_data函数获取到的持仓可能不仅仅是你这个策略的持仓,因为QMT可以区分委托和成交是哪个策略下的,但是无法分辨出持仓中的证券到底是哪个策略开出来的。

假设你同时跑ABC三个策略,在A策略中用get_trade_detail_data函数获取到的持仓,是ABC这三个策略持仓的加总,当你还是像以前一样用if code not in selected_list then sell时,你可能就会把另外两个策略的持仓都给卖出去了,这不符合策略的交易逻辑。

手动交易和程序化交易并行也会存在这个问题,不做仓位隔离的话,程序会把手工交易的仓位自动卖出去。

仓位隔离就是要给每个策略单独记录它们的持仓信息,以防多策略之间的仓位互相干扰。如果你的多个策略都是固定标的池,那就简单了,每个策略只交易固定标的池里的证券,但如果标的池里面存在交集,这个方法也是行不通。最好还是乖乖建立本地文件,维护和更新每个策略的持仓信息,用json、csv、excel、pickle等格式都行,喜欢哪个就用哪个。

当然了,如果你永远只跑单个策略,不考虑多策略组合,并且也不会手工交易,那就不用做仓位隔离。

五、异常处理

回测是模拟交易逻辑的理想情况,而实盘当中就会有许多坎坷,这些坎坷就需要咱去特别处理。比如刚才说的委托不成交就是一种异常,需要你去检查订单,筛选出长时间未成交订单撤单重下,咱再唠一下3种常见的异常状况和处理方法。

第一种异常,由于券商柜台服务器测试等各种原因,在非交易时段,QMT也是会收到券商推送的数据,这些数据被称为"脏数据",这些数据丢弃即可,一般的做法是时间过滤,判断当前时间是否是在交易时间段内,非交易时间段内的推送统统不予理会。

第二种异常,例如你已经做好仓位隔离,每个策略都有单独的本地持仓记录文件,但是由于自己手贱操作错误等原因,手动卖出了部分仓位,这就导致持仓文件中的仓位跟实际仓位就不对应了,你要是还按照原来的数量卖出就会直接废单。所以建议在策略程序启动时,先做一遍仓位校验,如果持仓文件中某个证券仓位大于实际仓位,则进行相应调整。

第三种异常,就是策略意外死机后重启,这里要特别留意的就是,策略在死机之前可能发出过委托单,这时就要在策略重启时,先做一遍历史委托检查,根据order对象中的委托时间和本次策略启动时间,判断出哪些订单是本策略在本次启动前下的,然后做相应的处理。

最后给想使用全天候策略进行实盘或模拟盘的小伙伴,说说参数设置的要点。

ACCOUNT_ID:就是你自己的股票账户的资金账号,回测的时候可以不填或乱填,实盘的时候一定要填自己正确的账号。

ACCOUNT_MODE:就是你打算用多少钱来跑这个全天候策略,可选值为MONEY和RATIO。选MONEY就表示按照ACCOUNT_MONEY设定的金额,选RATIO就表示使用总账户ACCOUNT_RATIO那么多比例的资金。

ACCOUNT_MONEY:策略金额,因为国债ETF一手要一万多,所以算下来,本全天候策略最低启动资金大约是10w。

ACCOUNT_RATIO:占总账户资金的比例,数值在0~1.0之间,0.3表示占30%比例。

STRATEGY_TRADETIME:策略进行交易的时间,因为全天候策略是日线策略,一天那么长,所以需要指定一个具体的时间进行下单交易。

ORDER_TIMEOUT:订单超时时间,默认是60秒,下单后超过60秒没有全部成交就是超时,策略程序会自动检查出超时的委托单,然后撤单重下。

STRATEGY_PATH:策略相关文件的存储路径,策略程序会在STRATEGY_PATH这个路径底下再新建一个名为STRATEGY_NAME的文件夹,策略相关的持仓文件和交易日志文件都会保存在这个文件夹底下,这些文件是做仓位隔离和信息回溯的关键。

STRATEGY_NAME:策略名称,一旦开启实盘之后,策略名称不要随意修改,不然就无法识别策略持仓文件,如果在盘中修改然后重启策略的话,就识别不了修改之前下的委托单和成交单。

因为在回测当中是模拟每月第一个交易日换仓,所以实盘当中没有必要全天挂机,只需要到你想调仓的那天运行该策略程序即可,也可以不是每月的第一个交易日。

全天候策略的回测实盘一体版源码和相关资料,已经分享在『量化达摩院』当中,请原路径自取,还不会使用QMT进行策略回测和实盘的小伙伴,请参照知识库第二章的第3和第4部分进行操作。并且,还可以在原策略当中,自行增/删/改资产类别和子资产列表,对应权重也可以修改。

需要特别说明的是,有些ETF上市时间比较晚,如果回测起始时间早于它的上市时间,按照原策略预留的样例格式设置对应的替代资产就可以了,未上市时就会用这个资产进行替代交易,上市后用回原资产,不想/懒得设置的话也可以,程序当中会用统一的资产品种进行替代。

我是量化君,下期见~

参考资料:

Edward Qian,2005,《Risk Parity Portfolios:Efficient Portfolios Through True Diversification》

Bridgewater,2011,《Risk Parity is about Balance》

Bridgewater,2012.2,《The All Weather Story》

Anthony Robbins,2014.11,《Money Master the Game》

华泰证券,2022.5,《风险平价策略的前世今生》

国泰君安,2023.5,《桥水全天候策略和风险平价模型全解析》

风险提示:市场有风险,投资需谨慎。所有策略思路和策略源码仅供参考和学习,不构成投资建议,策略回测仅代表历史收益,不代表未来收益。

相关推荐
装不满的克莱因瓶1 小时前
自然语言处理发展历史——从规则系统到大语言模型的演进之路
网络·人工智能·python·深度学习·语言模型·自然语言处理
机汇五金_1 小时前
深圳冷轧板钣金外壳定制
金融
GensAI1 小时前
智能语音机器人哪家好?实测4款主流产品,从方言识别到外呼稳定性的全面对比
人工智能·语音识别
2601_951645781 小时前
Linux 编程语言全解析:C、C++、Python、Go、Rust 谁更强?
linux·python·go·c·编程语言
themingyi1 小时前
Abaqus2024安装python包pandas
开发语言·python·pandas
暂未成功人士!1 小时前
简单了解李群和李代数的相关概念以及典型应用
人工智能·机器人·slam·姿态·李群李代数
searchforAI1 小时前
Obsidian加上AI之后,我的知识管理和内容创作流被重写了
人工智能
殇淋狱陌1 小时前
Python列表知识思维导图
开发语言·python·学习
fox_lht2 小时前
第十五章 函数式语言:迭代器和闭包
开发语言·后端·学习·算法·rust