执行慢的问题,要由订单路径上损失时间的那一段的负责方来修,所以第一件事是找到那一段。在你能看到的各个节点给每笔订单打时间戳,最大的那段间隔会告诉你该找谁:延迟在你的软件内部,找你的开发人员或工程公司;问题在距离,找服务器托管商;延迟在经纪商那一侧,找经纪商。
简短的答案:在雇任何人之前,先在决策、发出、经纪商确认和成交这几个时刻给每笔订单计时,并测量到经纪商的网络往返时间。订单离开你的服务器之前的间隔,归你的开发人员或工程公司处理;网络慢,是服务器托管方面的问题;经纪商内部的间隔,要么由经纪商来修,要么是你换一种接入方式的理由。
“我们的订单执行太慢”是什么意思?
这句抱怨可能指四种问题,每一种的负责方都不一样。
- 每笔订单都慢。无论是在清淡的上午还是在开盘时,延迟都差不多。这指向每笔订单都要付出的某种成本,比如距离、你接入经纪商的方式,或者你自己的软件在每笔订单发出前做的耗时操作
- 市场忙起来之前,订单都很快。开盘时或有消息公布时,延迟猛增。订单在某处排队,排在一个跟不上的程序、一个消息上限或一台忙于其他工作的机器后面
- 订单按时到达,却成交得晚。限价单会一直挂在订单簿上,直到有人与它成交,而在行情快速变动时,价格会走远。时间戳能说明订单有没有迟到,但说明不了当时能拿到什么价格
- 屏幕慢了。如果交易界面上的价格滞后,交易员就会点得晚,然后怪执行。那是行情数据的问题,本博客有另一篇文章专门讨论
只有真实订单上的时间戳,以及这些订单所响应的价格上的时间戳,才能把这四种情况区分开。用交易员的抱怨来挑选要检查哪几天。
从我们的系统到交易所,毫秒都花在哪里了?
订单发出时要经过四段路,确认则由经纪商发回,有时要等交易所接受订单之后才发回。
- 你这一侧。策略或交易员做出决定,生成订单,运行你自己的检查,然后发出订单。延迟来自发送前所做的工作、程序停顿、网络设置或繁忙的机器。你的开发人员或工程公司可以改动这一部分
- 网络链路。订单从你的服务器传到经纪商的接入点。距离、互联网路由以及 VPN 之类的额外中转,会在这里增加延迟。服务器托管商或机房托管商,或者网络工程师,可以把它缩短
- 经纪商。它的网关接收订单、运行检查,再把订单路由到交易所。延迟来自经纪商自己的系统和它必须执行的检查。只有经纪商能改变这些;你能选的是怎么接入、用哪家经纪商
- 交易所。撮合引擎接受订单并发回确认。这里花的时间很少:Nasdaq 公布,在其托管机房的高速 10G 网络上,从下单到确认的往返时间不到 50 微秒。这一段你雇谁都改变不了;你只能离它更近
在美国,经纪商的检查不是可选项。SEC 规则 15c3-5 要求拥有市场准入的经纪商“阻止超出适当预设信用或资本阈值的订单进入”,并拒绝“超出适当价格或数量参数”的订单。同一规则还把这些控制措施置于“经纪商或交易商的直接且排他的控制之下”。你可以问经纪商它的检查要花多长时间,但这条规则不允许它把检查关掉。
我们怎么找出时间损失在哪里?
为每笔订单记录四个时间戳:
- 决策:策略或交易员决定发出这笔订单
- 发出:订单离开你的服务器
- 确认:经纪商接受订单的确认回报到达你的服务器
- 成交:成交回报到达
从决策到发出,是你的软件。从发出到确认,是网络链路和经纪商的一去一回;如果经纪商要等交易所,还要再加上交易所。问问经纪商它是哪种做法。对于挂在订单簿上的订单,从确认到成交的时间主要取决于市场。
再测一个数:从你的服务器到经纪商接入点的网络往返时间。它能告诉你,从发出到确认的时间里有多少花在网络链路上。
FIX 是一个交易消息标准,由 FIX Trading Community 维护。如果你通过它接入,经纪商的消息会带两个时间戳:一个是消息发出的时间,一个是消息所报告的事件发生的时间。FIX 规范把这两个字段叫作 SendingTime 和 TransactTime,经纪商可以告诉你它们各自由谁的时钟设定。和你自己的时间戳放在一起,它们就能显示往返中的哪一段发生在哪一方。
拿你的时间戳和经纪商的时间戳对比,只有在两边时钟都准的情况下才有意义。FINRA 规则 6820 要求向综合审计追踪系统(Consolidated Audit Trail)报送数据的经纪自营商,将业务时钟与 NIST 原子钟的偏差保持在 50 毫秒以内。按照欧盟规则,采用高频算法交易的交易场所会员,必须将时钟与 UTC 的偏差保持在 100 微秒以内。一个允许偏差 50 毫秒的时钟,定位不了几毫秒的延迟。
发出和确认这两个时间点都读自你自己的时钟,所以两者之间的时间不需要时钟同步。就从这里入手。如果这段往返很短,订单却仍然让人觉得慢,就去看你自己的软件。如果它很长,先确认回复到达时你的程序没有处于停顿或忙碌状态;如果没有,时间就耗在你的软件之外。
然后看最慢的那些订单。把一周的订单按往返时间排序,记下只有百分之一的订单会超过的那个时间;对开盘后的最初几分钟和预定新闻发布前后,也照这样做一遍。平均值会掩盖交易员抱怨的那些时刻。
小型自营交易公司的执行,会被什么拖慢?
先检查这六个原因。
- 经纪商的 API 要经过一个你必须运行的程序。例如,Interactive Brokers 把它的 TWS API 描述为基于“与 Trader Workstation 或 IB Gateway 的连接”,所以每笔订单都要先经过其中一个程序。它的文档为每个客户端连接设定了“每秒 50 个请求”的默认上限,并警告说,在某些情况下,超过这一速率时,“部分订单可能会被排队并延迟”。针对这种情况,Interactive Brokers 建议改用它的 FIX API。如果这就是你的瓶颈,就问问经纪商还能通过什么别的方式接入
- 服务器离订单的去处太远。放在办公室的机器或远处的云区域,每笔订单都要为距离付两次代价,一去一回,而任何代码改动都消除不了它。要把距离缩到最短,Nasdaq 为客户提供机会,“将其服务器和设备托管在 Nasdaq 数据中心内”。在为机房托管付费之前,先测一下从你的服务器到经纪商接入点的网络往返时间
- 订单发出之前,先跑了耗时的操作。把订单写入数据库、等一行日志落盘,或者去问另一个服务这笔交易是否允许,都会给每笔订单加上一段等待。数据库或磁盘一忙,等待就会变长。把订单需要的东西放在内存里,等订单发出之后再写记录
- 网络设置把小消息压住不发。一笔订单就是一条小消息。Linux 手册说,除非设置了名为 TCP_NODELAY 的 socket 选项,否则外发数据会被缓冲,“直到有足够的量可以发送出去”。你的开发人员可以检查它是否已设置
- 程序停顿。有些垃圾回收器在清理内存时会让整个程序停下来。即使是 Go 的垃圾回收器——它的大部分工作都在程序运行的同时完成——也有“短暂的 stop-the-world 停顿”,Go 垃圾回收器指南把它们列为可能的延迟来源之一。如果停顿正好发生在订单发出的时候,订单就会晚走。在同一台机器上运行的图表、回测或报表也有类似的效果,因为订单得等处理器
- 经纪商自己的路径慢。它的网关、检查和路由都在每笔订单的路径上,而你看不到里面。你可以问:它的接入点在哪里,提供哪些连接方式,你的账户适用哪些消息上限,以及它是否愿意分享它自己为你的订单记录的时间戳
每个原因怎么修,工作量有多大?
- 每笔订单从决策到发出的时间都很长。把耗时操作移出订单路径,并检查网络设置。要做的是改你的代码,有时只是改一个设置
- 从决策到发出的时间在繁忙时刻猛增。找出订单在等什么:一次停顿、一个队列,还是一台共用的机器。要做的是改代码或调整服务器托管;如果排队源于设计本身,就要重建订单路径
- 每笔订单从发出到确认的时间都很长。把服务器挪到离经纪商接入点更近的地方,或者更换连接方式。预计要签一份服务器托管合同并搬迁,或者为新连接做对接工作
- 从发出到确认的时间随交易量猛增。找出你撞上的限制,是在经纪商那里,还是在你自己的连接上。可能只需要和经纪商谈一次,或者你这边少发一些消息
- 从确认到成交的时间很长。去看订单类型和市场。这不是工程方面的工作
先修已确认原因中最便宜的那个,把重建留到最后。在还没有人给订单计过时之前,不要重写系统,也不要换经纪商,因为延迟可能在别处。
订单执行慢,谁能帮我们解决?
谁能帮上忙,取决于时间耗在哪里。
- 你的经纪商。唯一能看到并改动它自己那一侧的一方。向它要它为你的订单记录的时间戳、它的各项限制和它提供的连接方式
- 服务器托管商或机房托管商,或者交易所的接入团队。他们出租靠近经纪商或交易所接入点的机柜空间,并出售通往那里的网络线路
- 你的交易平台供应商,如果你是通过一套授权使用的平台来交易的话。只有供应商能改动平台内部,所以把你的时间戳拿给它
- 做交易系统的工程公司。它先测量整条路径,再修改或重建你这一侧的部分,比如订单路径、风控检查和到经纪商的连接
- 你自己的开发人员,如果你有的话。有了这四个时间戳,一个能干的开发人员就能把路径上你这一侧的每个原因都排查一遍
无论你雇谁,先问这四个问题:
- 你们会在提出修复方案之前先测量吗?具体会给哪些点打时间戳?
- 报告会把我们这一侧、网络链路和经纪商分开,并给出最慢的那些订单,而不只是平均值吗?
- 你们报出的任何数字:在哪个分位、什么负载下、哪一天测的?
- 如果最后发现延迟出在经纪商那边,你们会怎么告诉我们?
如果对最后一个问题的回答仍然是重建你的系统,那就再找别家。
amBrain 在其中处于什么位置?
amBrain 是一家位于亚美尼亚埃里温的软件工程公司,用 Rust 构建低延迟交易平台、撮合引擎和实时竞价系统。amBrain 诊断交易、博彩和广告技术领域的慢系统:对运行中的平台做端到端测量,报告会指明时间耗在了哪里。
amBrain 构建算法交易基础设施:订单执行、行情数据和交易前风控。其交易方向的工作包括交易终端开发、订单管理系统和 FIX 协议交易所对接。amBrain 接手在其他团队手里停滞的项目,并把它们推进到生产环境。三种合作方式:整体交付、专属团队,或工程师嵌入你的团队。
如果你才刚起步,就在一个普通的日子和一个繁忙的日子各记下这四个时间戳。无论你找的是谁,amBrain 还是别人,都把它们带上,这样第一次谈话就能从时间耗在哪里谈起。
常见问题
- 用 Rust 重写我们的系统,执行会变快吗?只有当时间损失在你的软件内部、并且就在订单经过的那一部分时才会。Rust 提供内存安全保证,“而无需垃圾回收器”,从而排除了垃圾回收停顿这个原因。对繁忙的机器、距离或经纪商,它都无能为力
- 不改我们的代码能测吗?可以,前提是你的系统已经在日志里记下了带时间的外发订单和收到的确认:从发出到确认的往返时间就在这些日志里
- 执行更快,能让我们拿到更好的价格吗?谁也无法保证。速度缩短的是从决策到订单到达之间的时间;你拿到的价格还取决于流动性、订单类型,以及这期间市场如何变动