演讲来源:Two Sigma Presents(2022 年)
主讲人:Justin Sirignano,牛津大学数学系副教授、Two Sigma Securities 团队成员
Justin Sirignano 是牛津大学数学系副教授,同时也是 Two Sigma Securities 团队成员,主要研究机器学习的理论及其金融应用。在这场 Two Sigma Presents 演讲中,他介绍如何利用深度学习预测高频价格变化,以及如何通过强化学习优化订单执行,探讨预测优势能否转化为实际交易收益。
演讲从限价订单簿与买卖价差出发,依次讨论循环神经网络的价格预测能力、跨股票共享模型的泛化效果、大规模模型训练的计算挑战,以及强化学习在市价单择时和限价单撤单中的应用。最后讨论大额订单的市场冲击、模型的跨时间稳定性,以及金融机器学习研究所需的基础能力。
TL;DR:Justin Sirignano 核心观点
1.预测准确不等于交易盈利。即使模型正确预测中间价上涨,买卖价差也可能吞掉全部收益。高于 50% 的方向预测准确率,不足以证明存在可盈利的交易策略。预测价格与实际完成交易,是两个不同的问题。
2.非线性模型能从高频订单流中提取更多信息。Two Sigma 使用约 1,000 只股票、三年的逐笔数据进行研究。在样本外测试中,LSTM 对下一次价格变动方向的预测优于线性模型。
3.不同股票可能存在共同的价格形成规律。将多只股票的数据合并训练,不仅提高了预测准确率,还能将学到的规律迁移到训练时未见过的股票。这表明不同股票的订单流中可能存在共同结构,也体现了共享数据对减少过拟合的潜在价值。
4.强化学习可以优化订单执行,而不仅是预测价格。模型在 10 秒或 60 秒内决定何时买入、何时撤销限价单。相比立即市价买入,两种策略在历史模拟中都节省了平均成交成本,限价单策略通常略优。
5.历史模拟无法完整复制真实交易。一股订单几乎不会改变市场,因此可以利用历史订单簿模拟执行;但大额订单会影响队列、流动性与价格。如何准确模拟自身交易对市场的影响,仍是强化学习交易落地的重要障碍。
演讲精编
两类任务:预测价格,决定怎样成交
金融机构希望用机器学习做预测和决策,例如预测金融工具未来的价格,再寻找可能的交易策略。金融数据中常见非线性关系、高维输入以及时间序列关系,机器学习模型能够表示这些关系。要找出好的行动更困难;强化学习尝试直接从数据中学习决策规则,使相应的目标函数尽可能大。
机器学习通常在样本量很大时最有用。深度网络可能有几十万乃至上百万个参数,能表示复杂的高维关系;但若数据不够,参数太多也容易过拟合。高频金融数据有数十亿条样本,所以今天我重点讲高频建模。训练大模型还需要高性能计算。金融中也有只有中等规模数据集的应用,依然可能使用机器学习,但必须仔细检查是否过拟合。机器学习正在改变计算机视觉、自然语言处理和语音识别,这也是大家对它在金融中的应用感兴趣的原因。
除了高频数据,机器学习还可能用于更长时间跨度的收益建模、金融衍生品定价、高维偏微分方程求解,以及资产支持证券的提前还款、违约和逾期建模。今天我重点讲两个高频数据的例子:第一个用循环神经网络预测价格变动,第二个用强化学习选择订单提交策略。
订单簿怎样记录市场的供给与需求
在限价订单簿里,每个价格位置都有愿意买入或卖出的订单。最低卖价叫最优卖价,最高买价叫最优买价。想立刻买,就用市价单与最优卖价的挂单成交;想立刻卖,就与最优买价的挂单成交。两者的平均值是中间价,差额是买卖价差。
我们来看订单簿怎样随事件变化。最优买价为 9.99 美元、最优卖价为 10.01 美元时,价差是两美分。一笔卖出 100 股的市价单与 9.99 美元的买盘成交,这一档的挂单量从 200 股降到 100 股。另一个例子里,投资者撤销 9.99 美元档的一笔 200 股买入限价单,最优买价退到 9.98 美元,价差扩大到三美分。再看新增订单的例子:有人在 10.00 美元挂出 100 股买入限价单,最优买价上移,价差缩到一美分。
一只股票一天可能发生数十万、甚至上百万次订单簿事件。新增限价单、撤单和市价成交让订单簿不断变化,构成可见供需的高维序列。我们可以读取不同价位的挂单量和订单流,尝试预测下一次价格如何变化。
预测准确率为何不是交易收益
这里先停一下:就算模型预测涨跌方向的准确率高于 50%,也不能直接推断存在盈利策略。因为预测的是中间价,而交易必须穿过买卖价差。
假设我们的模型预测中间价会上升,我们随即以最优卖价 10.01 美元买入 100 股。中间价后来确实上升了,预测方向是对的;但如果此时用市价单卖出,只能按新的最优买价 10.00 美元成交。按这张幻灯片上的计算,这笔交易亏损 10 美元。关键在于买卖价差是一种交易成本:即使预测方向的准确率超过 50%,基于这个预测的策略仍可能亏钱。
接下来,我用循环神经网络预测高频价格变动,并与线性统计模型比较预测准确率。
第一个实验:预测下一次中间价的涨跌
我们使用约 1,000 只股票、三年的逐笔高频订单簿数据,总共是数千亿条样本。为了训练,把原始数据抽取到发生价格变化的时点;目标是根据此前的订单簿序列,判断下一次中间价变动是向上还是向下。这是一个二分类问题。
我们先用向量自回归模型作线性基准。它也可以看成线性循环网络:上一时点的状态和新到来的订单簿数据,一起更新当前状态。循环神经网络的时间结构类似,不过它用非线性函数更新记忆状态;每来一条新数据,状态便更新一次,模型再给出下一次涨跌预测。我们要检验的正是非线性模型能否学到线性模型学不到的关系。
训练还有计算上的难点。普通的时间反向传播先沿整条序列前进,再把梯度沿全部历史传回去;序列很长时,一次参数更新的计算量随序列长度增长。因此我们常用截断的时间反向传播:记忆状态持续向前流动,但每隔一小段更新参数,只把梯度沿这一小段反传。如果整条序列长 步,而每次只回传 步,单次更新的计算量就从与 成正比降到与 成正比。我们每走过 步,用这一段的目标函数更新一次参数;回传在窗口起点截断,起点的记忆状态按上一次参数更新后的值处理。学习率控制每次参数更新的幅度。这样得到的方向只是近似值,不是完整序列的精确梯度。
循环网络还可能遇到梯度消失:久远的记忆状态对当前梯度的影响很小,训练会变慢。我用手写数字数据集上的多层网络作一个示例:这些网络最终的准确率都超过 90%,但网络越深,达到这个准确率花的时间越长;较早层的梯度也越小。长短期记忆网络(LSTM)加入门控结构,遗忘门可以清除不再有用的信息,输入门可以加入新信息,目的是让模型更好地记住序列中较早的数据。
我们逐只股票计算模型预测下一次价格向上还是向下的准确率:预测正确的次数除以价格变化的总次数,再乘以 100%。然后比较两个模型在每只股票上的准确率差,并画出差值在股票间的分布。约 500 只纳斯达克股票、三个月的样本外结果显示,长短期记忆网络在这些股票上的预测准确率持续高于线性模型。左图是两种模型准确率之差的分布,右图是各自的绝对准确率。这说明非线性模型在这组数据中学到了有助于预测的关系。
一只股票一个模型,还是所有股票共享一个模型
下一步我想问:订单流与价格变化之间的关系,是否在许多股票上都相似?如果 IBM 和通用电气的价格形成过程完全不同,每只股票可能需要各自的模型;如果存在共同关系,我们就能把大量股票的数据合在一起训练一个共享模型。我把它叫作通用模型:它把订单流序列映射成下一次价格变动方向的条件概率分布。还有一个同样重要的问题:训练结束数月后,这种关系是否仍然稳定?
把多只股票的数据合在一起,可能降低过拟合的风险,也可能支持参数更多、准确率更高的模型。这还可以看成迁移学习:用 IBM 的数据帮助通用电气的模型,反过来也一样。从计算角度看,训练一个共享模型也可能比训练上千个单股模型便宜。接下来我们用样本外数据检验这些想法。
我们把一个用数百只股票的合并数据训练的循环网络,与分别为每只股票训练的循环网络作比较。约 500 只股票、三个月样本外测试的柱状图显示,通用模型的准确率持续高于单股模型。这说明不同股票的订单簿动态中可能有共同结构。
我们还检验模型能否用于训练时从未见过的股票。先用约 500 只股票从 2014 年 1 月至 2015 年 5 月的数据训练,再直接预测另外约 500 只股票。2015 年 6—8 月和 2017 年 1—3 月的测试结果,准确率持续高于 50%。后一段测试距离训练结束已经超过一年,因此在这个实验里,通用模型也表现出跨股票、跨时间的稳定性。
这样的大数据集需要高性能计算。训练单股模型时,我们把每只股票分配给一个 GPU 节点,用约 500 个节点并行训练各自的模型。训练跨股票共享模型时,我们把所有股票的数据合在一起,用 25 个 GPU 节点共同训练同一个模型:每个节点从所有股票的数据中随机取一批样本,计算梯度后异步发给参数服务器,更新这套共享参数;节点之间不必互相等待。
第二个实验:已经决定买入,怎样选择下单时机
现在看第二个例子:我们已经决定买入,问题是怎样提交订单才能得到更好的成交价格。完整的订单还可以拆成小单,并选择市价单或限价单、下单时点及数量。我先把实验缩小到买入一股,研究在短期限内何时下单。
在马尔可夫决策过程中,如果已知状态如何变化,就可以用贝尔曼方程求每个状态下的最佳行动。但实际中状态转移规律通常未知;订单簿状态又是高维的,传统数值求解很困难。强化学习尝试从状态、状态变化和行动回报的数据中直接学习决策规则。
假设一股买单在时点 到达。我们可以立即用市价单按最优卖价买入,也可以每秒观察订单簿,选择“现在买”或“继续等”,但最迟要在期限 结束时成交。把立即成交作为基准,它的成本节省为零。如果最优卖价不可预测,例如满足鞅的条件,立即成交就是最优策略。如果模型选择等待,就是在判断最优卖价以后可能下降,我们能在更低的价格买入。我们要问的是,能否学出相对立即买入这一基准具有正的平均成本节省的策略。
为了训练这个策略,我们根据模型给出的行动分布抽取“买入”或“等待”,再用历史订单簿模拟成交价,并用模拟结果优化模型。我们使用纳斯达克订单簿数据,每秒抽取一次决策状态。模型用一年数据训练,再用随后六个月的测试数据评估。我们在 100 只股票上模拟 10 秒和 60 秒两种期限;更长的期限会显著增加计算量,尤其是限价单策略必须逐笔走过期间的订单簿事件。如果到期还没有买入,就立即发出市价单。图中的成本节省用基点表示,比较对象是订单一到就立刻发市价单。
这两组图各有 50 只股票。市价单策略在所展示的股票上都获得了正的模拟成本节省,但股票之间差别很大。一般来说,60 秒期限的节省高于 10 秒期限。
加入限价单后,关键是能否排到成交
只用市价单时,我们能从历史订单簿读出某个时点按最优卖价买入的价格。加入限价单就复杂了:报价并不保证成交,我们必须逐笔追踪订单簿事件,判断这张订单什么时候轮到成交。
第二种策略是订单到达时,先在最优买价挂出一股买入限价单。此后我们每秒决定是否撤单;一旦撤单,就立即用市价单按最优卖价买入。如果到 10 秒或 60 秒的期限仍未成交,也撤掉限价单并发市价单。我们让强化学习模型选择撤单时间,以提高预期成本节省。
为了模拟一股限价单会不会成交,我们把模拟订单插入历史订单簿,再逐笔追踪后续事件。图中红色标出加入的订单,蓝色标出后来使它成交的事件。它也有可能一整天都没有成交。
样本外模拟的结果显示,限价单策略持续取得正的成本节省,股票之间的节省幅度仍有差异。图中紫色表示限价单策略,青色表示只用市价单的策略;限价单策略略胜一筹,某些股票上的差距更大。
这些是一股订单的理想化实验。对于一股订单,我们可以在少量附加假设下,用历史订单簿模拟成交价;金融机构真正关心的往往是更大的订单,那就需要准确模拟自身交易对市场的影响。把强化学习与大额订单的可靠模拟结合起来,仍是有待解决的问题。
还没有解决的事
今天我展示了高频数据上的深度学习和强化学习模型,还有许多开放问题:怎样改进优化方法,怎样设计专门适应金融数据的深度学习架构,怎样为更大订单建立准确的交易模拟,以及怎样利用不同来源、不同时间频率的更多数据。
对于想进入这一领域的学生,我建议先在经典数据集上亲手实现那些广为人知的模型,再积累处理大规模数据集的经验。数学理论也很重要,它能指导我们训练和实现模型。要熟悉 PyTorch、TensorFlow 等工具,也要积累并行计算经验。学习量化金融课程同样有帮助。
Q&A
观众: 不同年份的市场会受到重大事件影响。你的模型在环境变化后还能用多久?
Justin: 金融市场确实会随时间变化。我展示的模型在训练期结束一年以后仍然稳定。更长时间以后是否还能保持稳定,这是一个很好的问题。
观众: 如果想研究金融中的机器学习,应该学哪些课程?
Justin: 与金融数据有关的统计建模课程很有用,概率和应用概率也重要。机器学习本身依赖概率、统计、优化和计算机科学;大学里也有越来越多关于金融机器学习的课程,这些课程和基础课都值得学。
观众: 这些项目用了什么编程语言和工具?
Justin: 示例用了 TensorFlow 和 PyTorch。我个人更推荐 PyTorch,不过两个框架都很常用,也都能用于深度学习以外的计算。我们会根据具体任务选择合适的语言,没有一种语言能满足所有需要。
观众: 类似的强化学习框架能否用于动量崩盘等传统交易策略失效的情形?那时预期回报应怎样建模?
Justin: 这是个有意思的应用,但我没有认真研究过,所以现在给不出好的答案。
观众: 为什么跨股票共享的模型会胜过针对某一只股票专门训练的模型?
Justin: 单股模型的数据少,更容易过拟合;把多只股票放在一起训练,数据更多,我们就可能用参数更多的模型,同时降低过拟合的风险。另一个原因是迁移学习。假设一只股票经历过高波动状态,另一只在我们观察的历史里从未经历过;如果两只股票的状态后来互换,单股模型可能会遇到从没见过的数据。我希望通用模型能从其他股票的历史中学到这种状态,再用于原本没经历过这种状态的股票。
原视频:
https://www.youtube.com/watch?v=2bE2iyRBK1E