作者 | 陆迤炜、王众

当前的银行间本币市场,债券数量越来越多,价格竞争越来越激烈,单纯依靠交易员人工挂单做市已难以应付,做市程序已逐渐成为报价主力。这些做市程序不间断的在竞价渠道发布报价和平盘,提供了流动性,推动了做市报价高质量发展。回测是验证策略有效性的关键步骤,然而,关于如何回测这类做市报价策略的资料却极为匮乏。本文旨在分享我们在实践中遇到的问题。

做市型的策略一般有以下特征:

使用计算机算法分析分笔行情数据,结合持仓、债券属性等要素做出量价决策,执行交易指令;

风险敞口小、换手率高,既有被动挂单,也有主动平盘;

依赖订单簿形态、短期动量因子等高频信息。

一、回测系统简介

做市程序回测系统需要由分笔行情驱动,并完成以下任务:

逐笔向策略提供行情;

接收策略的下单、撤单指令,依据撮合逻辑向策略返回订单最新状态和成交信息;

记录策略的所有下单、撤单指令,统计出指定的表现评价指标。

其中,撮合逻辑用于判断策略订单的成交时间和成交价量,它的优劣决定了回测能在多大程度上接近真实情况。然而无论撮合逻辑如何精妙,这类回测仍然难以得到可靠的结果。最主要的原因是策略每一次挂单和撤单都可能改变微观结构,甚至会在参与者之间引起连锁反应,使得结果不可预测。例如一个策略为了增加成交概率,总是在比其他人更优的位置下限价单,如果某日两个人同时使用了这个策略,互相竞争后买卖价差急剧减小,导致双双亏损。回测系统一般只是复现市场中其他参与者的挂单、撤单、成交行为,当策略真的闯入了市场,这些行为必将发生变化。

二、回测的必要性

如前文所述,做市策略的回测结果通常是不稳定的,但我们依然认为回测是不可或缺的,它能带来有众多好处。

发现策略的缺陷

一般来说策略的研发过程是“主观的”,交易员可以用任何擅长的方式和工具进行研究,甚至是凭借经验,这导致研究中可能会出现各种不同的错误。但是回测系统是“客观的”,通过回测就可以及时发现这些问题。

01

逻辑存在漏洞

某交易员统计发现银行间市场某只债券的最新买卖价格均值有85%的比例落在之前的买卖价格之间。他据此制定做市策略,按市场价格挂限价单,成交后立刻按当前的买卖价格均值反向挂单,直至平盘成功或者到达止损位置。这个策略看似有点道理,实则毫无胜算。他错误的认为策略有很高概率平盘并实现收益,但实际上短时间内的点击成交大多是同一方向的,策略基本都在实现亏损。

02

执行算法缺陷

为了贪图方便,某交易员研发时假定点击最优做市报价或最优匿名报价,有很高概率立刻达成交易。通常情况下这没有问题,但是当机构在对单个标的做市时,最优价格很有可能是本方的报价,并不能被点击。

03

前视问题

某交易员由于读取数据时时间字段的小数舍入原因,行情按时间排序聚合时错位了,成交行情排到了报价行情前面,利用未来的信息做出了交易决策。

如前文所说,回测系统会严格按照实际顺序提供市场数据,并使用精心设计的撮合逻辑判断策略下达的订单能否成交,不会受到交易员的错误认知或错误操作影响。因此上述缺陷都会在回测中表现出损益异常、订单成交率异常等情况,交易员可根据回测结果快速定位问题。

评估非利润类的指标

交易员研发策略时往往重点关注回报率、夏普比率等指标,忽视了一些和损益无关的指标:例如处理逐笔行情的速度,挂单、撤单的频率,行情到达的频率等。密集的行情和过慢的处理速度会损害策略的执行效果,甚至导致交易系统崩溃;过于频繁的挂单和撤单则可能违反交易场所的相关规定。这些问题比策略亏损更严重,在回测中统计、评估这些指标,能够有效避免在实盘中犯错。

保证代码正确部署到实盘

策略在回测中接受分笔行情,对外输出改单、撤单指令,其行为与实盘完全一致,因此开发回测系统时应该尽量让回测系统接受可直接实盘的代码。代码在回测系统经历了充分的试验,应用同一份代码到实盘即可以保证正常运行。

三、回测偏差的原因和应对方案

策略实盘运行时会对市场造成交易冲击,回测不可避免地会与实盘结果有出入,但除此之外,回测的准确性还受多方面复杂因素影响。为了让回测结果尽可能接近实际交易情况,我们在实践中总结了以下一些问题的原因和应对方案。

指令时滞问题

真实环境下,从策略给机器发出交易指令到交易所处理再到交易所给出回报存在延时,时间的长短取决于各方面因素,如网络链路长短、交易前风控校验时间等等。但回测系统为了提高运行效率,从接收行情,运行策略逻辑,下达交易指令到回测系统生成模拟交易回报,这整个过程几乎是瞬间完成的,系统随即就能撮合成交,或是运行策略重新挂撤单。但实际交易中,由于时滞,策略无法以理想的价格成交,或是错过最佳交易机会,这会导致回测结果成交量和挂撤单量远高于现实情况,损益的表现也会更好。为了解决这个问题,一个完美的解决方案可能是为回测构建一套交易所模拟系统,独立于策略之外,和策略用生产的方式通信,同时加入一些通信等待时间。这里推荐一个更简单有效的方法,下达交易指令时记录下当时行情的时间戳,在播放行情时暂时不处理那些和当前行情时间很接近的交易指令,等到后续的行情和交易指令时间间隔足够长了再处理。

成交排队问题

如果在订单簿一档价格有很多订单排队等待成交,此时在一档挂限价单就要等待一会儿才能成交,这在现实中是很常见的情景,回测时需要尽量模拟还原这种情况。尤其在一些tick最小步长较大的竞价市场上,如X-Swap利率互换,排队问题对回测结果的准确性影响更大。我们当前的实践方案是模拟交易所的订单簿,根据订单簿实际的变化来推断排队位置的变化,最初下达交易指令时排在该档队尾,记下该档位当前可成交量为队首,记下0为队尾;后续如果该位置可成交量变多,则认为市场有新增挂单,排在队伍最后,队尾增加挂单量;如果可成交量变少,则认为市场有人撤单,则按当前推测的队首、队尾挂单量比例分别在队首、队尾撤单,减去撤单量;如果市场达成成交,则从队首减去成交量。

市价单与限价单的回测准确性

不同订单类型的回测准确度也有所不同。市价单可能会对市场价格产生较大的影响,尤其是当交易量很大时,这种大额的交易可能会改变市场上的供需关系,从而影响市场定价。但成交量小的市价单可能只改变订单簿的第一档,不影响市场供需关系,这一类交易的回测结果和真实运行情况所差无几。限价单相比市价单对市场影响较小,但在某些情况下,也会对市场有间接影响。比如挂最优价会缩窄市场报价,为市场注入流动性,吸引其他市场参与者以更好的价格参与交易,尤其在程序化交易程度较高的市场,订单簿一档的变动会触发市场背后多个交易策略快速反应,带动一系列连锁反应,对市场的影响难以衡量,在回测模拟中也需要评估这些影响。

四、回测无法发现的危险

行情内容异常

正确答案只有一个,但是错误多种多样:市场可能出现错价,行情报文也可能出现各种异常。你无法预料下一次异常会是什么,这就要求策略代码不仅仅是在理想状况下能实现业务逻辑,在异常状况下也要能做出反应,比如舍弃错误消息、自动暂停等。特别的对于债券交易,交易中心以净价优先,且没有强制规定收益率要与净价匹配,统一使用净价来表达债券价格可以避免很多麻烦。

网络异常

由于网络波动等原因,市场行情、订单信息、成交信息等都有可能出现延迟甚至丢失,导致策略收到消息的时间明显晚于交易场所的发出时间;接收到消息的顺序也可能前后错位,例如先收到了订单成交信息,后收到订单生效信息。策略代码要有足够的容错能力,且能及时做出暂停发单等应对,如果应对失当,策略行为可能会无法预测,交易系统也有可能崩溃。

五、结语

以上都是我们实践中的经验总结,希望能对各位读者有所帮助。最后祝福大家交易平安,算法永远不出bug。

   END  

往期精选


追加内容

本文作者可以追加内容哦 !