一个熟悉的故事:你构建了一个机器学习模型,运行回测,数据看起来非常出色。稳定的利润、干净的权益曲线、合理的回撤。你将模型部署到生产环境,几天之内,它就开始亏损。
当这种情况发生时,首先被怀疑的通常是同样的几个问题:过拟合、数据泄露、市场状态转变。有时这些确实是真正的问题。但更多时候,它们不是。
在实践中,许多“盈利”模型的失败原因要平凡得多:它们从未学习过自己的预测将如何被实际执行。
回测在一个价格干净且即时可用的世界中运行。模型预测价格变动,交易被假定为以该价格发生,利润据此计算。真实市场的运作方式不同。在预测与实际利润之间,存在着执行环节——而正是这里,隐藏成本不断累积。
模型预测价格。交易系统执行订单。两者之间的鸿沟,是大多数策略悄然消亡的地方。
执行不仅仅是一个工程细节。它会以系统性的方式改变结果。延迟、队列位置、市场冲击和逆向选择,都会扭曲模型表面拥有的理论优势。忽视这些影响,即使是最优的预测信号也会变得无法交易。
这种脱节在面试中表现得尤为明显。我经常问候选人一个简单的问题:“你有一个在回测中表现不错的模型。部署之后,它开始亏损。你忘记了什么?”大多数回答都围绕着建模错误。很少有人提到执行。
在这篇文章中,我想聚焦于这个被遗漏的部分——当模型遇到真实订单簿时出现的隐藏成本。
我们将探讨两种基本的执行模式。第一种是主动吃单执行,即使用市价单激进地成交。第二种是被动挂单执行,策略依赖于限价单和流动性提供。两者在纸面上看起来都很简单。一旦涉及真金白银,两者都会引入微妙但强大的失败模式。
理解这些影响并非可有可无。如果执行不是你建模假设的一部分,那么你的回测就不是一次模拟——而是一种幻想。
两种亏钱方式:主动吃单与被动挂单
执行问题通常以两种截然不同的方式显现,具体取决于策略的交易方式。
第一种情况是主动吃单执行——市价单,激进地消耗流动性。
第二种情况是被动挂单执行——限价单,提供流动性,做市。
表面上,这两种方法看起来是对立的。在实践中,两者都会引入回测中很少可见、而在生产环境中痛苦明显的隐藏成本。
主动吃单执行:当速度变成价格
让我们从较简单的情况——主动吃单执行开始。市价单看起来很直接:你想立即交易,接受当前价格,然后完成。然而在现实中,即使“立即”也有成本。
执行延迟与滑点
想象两个参与者收到相同的信号:市场即将上涨。两人都向同一个订单簿发送市价单买入 100 BTC。
一个订单先到达。另一个稍后到达。
第二个交易者以明显更差的价格买入。这里没有什么神秘的事情——这只是市场的运作方式。这个差异被称为滑点。
根本原因是执行延迟:从发送订单到订单成交之间的时间。即使是微小的延迟也会改变结果,因为市场是竞争性系统。更早看到信息——并更早行动——是一种优势。
这一点一直成立,远在毫秒成为重要指标之前。在《货币崛起》一书中,尼尔·弗格森描述了罗斯柴尔德家族如何比市场其他参与者早数小时得知滑铁卢战役的结果而获利。这里的延迟不是技术性的,而是信息性的。但效果是一样的。
从某中心服务器到交易所的典型延迟。如果超过20毫秒,你的订单将永远迟到。
延迟不是一个细节。它是交易中最古老的优势之一。
为什么简单的延迟建模会失败
当人们试图在回测中考虑延迟时,他们通常会采用一个简单的修复方法:假设一个恒定的执行延迟。
这几乎从未奏效。
首先,网络延迟不是恒定的(在毫秒尺度上如此,更不用说纳秒了!)。其次,在波动率飙升期间,延迟往往会增加——有时是急剧增加。交易所变慢,队列增长,内部系统吃力。第三,一个交易策略必须具有鲁棒性。如果它只在理想延迟下有效,那它实际上并不有效。
延迟很重要:超过20毫秒的往返意味着你的订单总是迟到
一个在条件恶化时就会崩溃的脆弱策略不是策略——它是押注于完美的基础设施。
一种更现实的思考延迟的方式
更实用的方法是将执行延迟视为一个随机过程,而不是一个固定数字。
在实践中,可以这样做:
你在实盘交易中收集真实的执行延迟统计数据,并将其视为一个时间序列。在回测中,每个模拟订单都被分配一个从与当前市场状况相关的延迟分布中采样的延迟——不是逐字复制历史,而是概率性地抽取。
即使是粗糙的分布也比恒定值要好。而且,刻意注入一个小概率的极差延迟,会迫使策略面对现实。如果它无法在这些情况下生存,生产环境最终也会教会这一课——只是成本更高。
这与“预测黑天鹅”并不完全相同,它恰恰是关于塔勒布所说的“反脆弱性”。
市场冲击:当市场对你做出反应
即使延迟被神奇地消除,主动吃单策略也面临另一个更深层次的问题:市场冲击。
假设你需要买入价值 1 亿美元的某资产。你不会发送一个巨型订单——你会把它切分成小份。第一份成交了。其他参与者看到了激进的买盘。价格变动。后续的小份在更差的价位成交。
你最终付出的价格比你的模型曾经假设的要高。
市场冲击之所以困难,是因为它是反身性的。市场不仅揭示价格——它还会对你的行为做出反应。你的回测隐含地假设了一个你交易而不影响市场的世界。在现实中,你的订单改变了你正试图利用的那个分布本身。
这就是为什么市场冲击建模是一个庞大的研究领域——也是为什么它从根本上仍未解决。我们不知道如果我们没有交易,市场会如何表现。在真实市场上进行实验是昂贵、缓慢且不可靠的。
许多机器学习回测悄悄地假设市场冲击为零。
这个假设几乎总是错误的。一个真正的回测应该是“交互式的”——即对你的策略行为做出反应。
被动挂单执行:收到报酬——然后又还回去
乍一看,被动挂单执行看起来更安全。没有滑点。更好的价格。有时甚至还有返佣。
但风险并没有消失——它们只是改变了形式。
队列优先级与信号传递
对于限价单,延迟仍然重要。如果两个参与者以相同价格下单,先到者获得优先权。另一个可能永远无法成交。
市场冲击也不会消失。挂出一个巨大的可见限价单通常比切分激进订单更糟糕。订单簿中的一堵“巨墙”会变成一个信号。其他参与者做出反应。价格向反方向移动。该订单不再是流动性,而变成了信息。
这自然引出一个诱人的想法:我们能不能用这种方式操纵市场?
是的——这正是此类行为被禁止的原因。
有毒执行与逆向选择
被动挂单策略中最微妙——也是最危险——的风险是有毒执行。
如果你的限价单成交了,这通常意味着某个其他人知道一些你不知道的事情。一个知情的参与者认定与你交易是有利可图的。成交之后,价格往往会继续移动——而现在它朝着对你仓位不利的方向移动。
换句话说,执行本身变成了一个负面信号。
这个概率取决于交易品种和竞争水平。矛盾的是,挂在订单簿很深位置的订单可能更危险。如果这样一个订单成交,通常意味着市场已经移动了足够远的距离,以至于发生了某些意外——而你已经迟了。
从某种意义上说,这是市场冲击的镜像。不是你推动市场,而是市场穿过你。
负的标记回报:5-10秒后平仓损失约1个基点。
生活在生态系统中
市场不是公平的系统。它们是生态系统。
一些参与者更快、信息更灵通或资本更雄厚。不加区分地与他们互动是危险的。一个实用的被动挂单策略试图避免“喂鲨鱼”。
这通常意味着:
- 避免与明显知情的资金流互动;
- 监控看起来是算法或协同行为的订单行为;
- 观察多个场所的活动——同时发生的激进交易通常标志着大型知情参与者;
- 并且当执行本身变成警告信号时,准备迅速退出。
最终,这会将你推回预测——但你现在预测的不是价格。你预测的是你在与谁交易。正如前一篇文章所讨论的,这不是一个简单的问题。
结论:执行不是事后才考虑的事情
一个交易模型失败,不是因为预测错了价格。
它失败是因为忽略了该预测将如何被执行。
回测生活在一个简化的世界中:价格可执行、延迟不可见、市场不反应。生产环境生活在一个竞争性的、对抗性的环境中:每一笔订单都会留下痕迹。
执行不是一个实现细节。它是模型的一部分。
如果执行成本没有嵌入到你的假设中,那么你的回测就不是对现实的模拟。它是对一个并不存在的市场的模拟。
而市场非常擅长惩罚幻想。FINISHED