开发高频交易系统
从头开始使用 C++或 Java 基础实现高频交易
塞巴斯蒂安·多纳迪奥
开发高频交易系统
从头开始使用 C++或 Java 基础实现高频交易
塞巴斯蒂安·多纳迪奥 苏拉夫·戈什 罗曼·罗西埃
开发高频交易系统
版权所有 © 2022 Packt Publishing
版权所有。本书的任何部分未经出版商事先书面许可,不得以任何形式或方式进行复制、存储于检索系统或传播,简短引用于关键性文章或评论除外。
这本书在编写过程中已尽力确保所提供信息的准确性。但本书中的信息是在不作任何明示或暗示担保的情况下出售的。作者、Packt Publishing 以及其经销商均不对本书直接或间接造成的任何损害承担责任。
帕克特出版社已尽力提供本书中提到的所有公司和产品的商标信息,通过适当使用大写字母。但是,帕克特出版社不能保证这些信息的准确性。
出版产品经理:Heramb Bhavsar 内容开发编辑:Shreya Moharir 拉胡尔·林巴齐雅 萨菲斯编辑 项目协调员: 法琳·法蒂玛 校对员: Safis Editing 索尼·特加尔·达鲁瓦勒 制作设计师:罗尚·卡瓦莱 市场营销协调员:普里扬卡·马特里
首次发布:2022 年 6 月 1160622
由 Packt 出版社出版。 禮服廣場 35 利弗里街 伯明翰 英国 B3 2PB.
贡献者
关于作者
塞巴斯蒂安·多纳迪奥拥有二十年高性能计算、软件设计和金融计算的经验。目前是彭博首席技术官办公室的一名架构师,他有广泛的专业经验,包括担任外汇/加密货币交易公司的首席技术官、工程主管、定量分析师以及一家高频交易对冲基金的合伙人。塞巴斯蒂安在过去十五年里在哥伦比亚大学、芝加哥大学和纽约大学等多所学术机构教授过各种计算机科学和金融工程课程。塞巴斯蒂安拥有芝加哥大学颁发的高性能计算博士学位、金融管理硕士学位和分析学硕士学位。他的主要热情是技术,但他也是一名潜水教练和一名资深的攀岩者。
苏拉夫·戈什在过去十年里曾在几家专有的高频算法交易公司工作。他为世界各地的交易所建立和部署了极低延迟、高吞吐量的自动化交易系统,涉及多种资产类别。他专长于统计套利做市和交易全球最流动期货合约的配对交易策略。他现任一家位于巴西圣保罗的交易公司的副总裁。他拥有南加州大学计算机科学硕士学位。他的兴趣领域包括计算机架构、金融科技、概率论与随机过程、统计学习与推断方法,以及自然语言处理。
罗曼·罗西耶拥有超过 19 年的经验,主要担任金融行业软件架构师,专注于低延迟、高性能的 Java 软件设计和开发。他目前是 HCTech FX 专有交易引擎的首席架构师。他还建立并领导了 HCTech 的软件开发团队,负责开发 FX、期货和固定收益的 HFT 平台架构。在加入 HCTech 之前,罗曼曾担任 Currenex 实验室的总监,领导团队负责 Currenex 智能定价系统的开发。罗曼拥有瑞士洛桑联邦理工学院通信系统专业的硕士学位。
关于评论者
约翰·里佐运用他对技术和构建复杂计算机系统的热情,在整个职业生涯中为金融市场提供支持。在过去的 17 年里,他担任过多个技术领导角色,包括首席技术官、董事和基础设施架构师,在金融服务行业的各种对冲基金和其他公司任职。他创办并出售了一家公司,该公司开发了帮助管理贷款生命周期和银团贷款市场各个方面的系统。如今,他专注于彭博社首席技术官办公室的基础设施安全。
菲尔·韦尚在彭博社从事与身份、认证和数据科学应用于运营安全挑战相关的项目。在此之前,菲尔共同创办了一家专注于高速数据包捕获和分析的初创公司。他还开发了高频交易系统,设计并实现了身份和安全基础设施设备的固件,构建了合成孔径雷达数据处理工具,并从事承运商路由器的数据平面流量工程。他的主要兴趣是开发与商业问题相关的威胁模型,设计安全的嵌入式系统,以及努力提高我们日益互联世界中的个人隐私保护。
目录
序言
第 1 部分:交易策略、交易系统和交易所
1
高频交易系统的基础
高频交易的历史
1930 年代后期 现代时代 为什么有高频交易? 什么让高频交易与常规交易如此不同? 暗池效应 谁进行高频交易? 开始高频交易需要什么? 高频交易策略 资产类别 流动性
四个逐个数据和数据分布 流动性回扣 12 匹配引擎 13 做市 捡漏 统计套利 15 套利延迟 16 新闻 17 的影响 动量点火 17 返利策略 18 18 非法活动 摘要 20
2交易系统的关键组成部分 理解交易系统...22 交易系统架构 … 24
连接交易所的网关 25 与交易所交易的交易系统 检查通信 API ... 29 订单管理... 30 订单簿考虑...32 制定交易决策的策略 世界卫生组织 关键组件 ... 36 非关键组件 ... 37 指挥与控制…37 服务 ... 38 总结...39
3理解交易交换动力 架构一个大规模处理订单的交易交易所…交易所历史 42 交易所特性理解 42 交换架构 43
44一般订单簿和撮合引擎...46 最佳价格方案... 47 部分填写方案…48 无匹配场景...49 同样价格的多个订单...50 摘要 ... 53 如何设计高频交易系统
4高频交易系统基础 - 从硬件到操作系统 了解高频交易计算机...58 内存管理 中央处理器,从多处理器到多核心
分页内存和页表 主存储器或 RAM ... 62 系统调用 共享内存 64 输入/输出设备 ... 65 使用操作系统进行高频交易系统 用户空间和内核空间...66 进程调度和 CPU67 缝纫... 71 干扰管理…72 编译器的作用 可执行文件格式 … 74 静态链接与动态链接 总结...75
5
动态网络
高频交易系统中的网络理解...78 学习网络概念模型...78 网络通讯 在 高频交易系统 理解开关的工作原理…82 重要的协议概念 ... 89 使用以太网进行高频交易通信...90 使用 IPv4 作为网络层 UDP 和 TCP 用于传输层 为高频交易交易所设计金融协议
6高频交易优化-架构和操作系统 表现心智模型 112 理解上下文 112 上下文切换类型 为什么上下文切换是好的...114 步骤和操作涉及到一个上下文 开关操作 … 115 为什么上下文切换对高频交易不利?116 避免或最小化上下文切换的技术 构建无锁数据结构 修复协议…95 内部网络与外部网络... 101 理解数据包生命周期...102 理解发送/接收(TX/RX)路径中的数据包生命周期...104 接收数据包的软件层... 105 监测网络 … 105 数据包捕获和分析 ... 106 时间分配的价值... 108 时间同步服务…109 总结... 110 为什么需要锁(非高频交易应用程序)... 118 同步机制类型 使用锁存在的问题和效率低下 预取并预分配内存...127 存储器层次结构 … 128 预取以提升性能的替代方法...131 动态内存分配 … 133 基于预分配的动态内存分配替代方案...134 总结 … 135
7
Comparing kernel space and
138What is kernel and user space?139Investigating performance - kernelversus user space140Using kernel bypass141Understanding why kernel bypass isthe alternative142Presenting kernel bypass latencies142Learning aboutmemory-mapped files143Using cable fiber, hollow fiber,and microwave technologies146Evolution from cable fiber to hollowfiber to microwave147
中空纤维的工作原理 微波炉如何工作...148 深入了解日志和统计数据...150 高频交易中登录的需求 ... 150 高频交易中在线/实时统计计算的需求...150 测量性能 … 152 衡量绩效的动机...152 Linux 工具用于测量性能...153 自定义衡量性能的技术…156 摘要…161 第 3 章:高频交易系统的实施
8
C++ - 追求微秒级延迟 C++ 14/17 内存模型
f
f
f \boldsymbol{f} ...166 什么是内存模型?… 166 需要一个内存模型 C++ 11 内存模型及其规则...68 C++内存模型原则 去除运行时决策...176 去除运行时决策的动机...177 虚函数 性能开销 … 179 动态内存分配 运行时性能损失 … 184 有效地使用 constexpr 影响性能的异常 减少运行时间的模板 188 什么是模板?… 188 模板特殊化
τ
τ
tau \boldsymbol{\tau} … 189 为什么使用模板? 模板的缺点 静态分析类型 模板的性能... 192 标准模板库(STL)…193 静态分析 … 195 C++静态分析 静态分析的需求 静态分析步骤...197 静态分析的利弊 构建外汇高频交易系统 摘要
9
Java 和低延迟系统的 JVM Java 基础入门 实时性能指标 … 220 减少影响 的 GC =(予 207 如何保持 GC 事件...208 预热 JVM 分层编译在 JVM...214 优化 JVM 以提升启动 性能 测量 Java 软件的性能 为什么 Java 微基准测试很难创建?… 219 Java threading
τ
τ
tau \boldsymbol{\tau} … 221 使用线程池/队列...222 高性能 任务队列 队列 … 227 循环缓冲区 228 日志和数据库访问 ... 230 外部或内部螺纹?…231 总结... 232
10
Python - 解释型但开放于高性能 Python 简介 利用 Python 进行分析...234 为什么 Python 慢?… 236 我们如何在 Python 中使用库? Python 和 C++用于高频交易 ... 239 在 Python 中使用 C++ 使用 Python 和 C++…240 Boost.Python 库... 241 使用 ctypes/CFFI 加速 Python 代码...243 施维格 … 244 提高 Python 代码在高频交易中的速度...246 总结…248
11
高频 FPGA 和加密
使用 FPGA 降低延迟 ov…250 高频交易的激烈竞争速度的演化...250 现场可编程门阵列简介 ... 251 钻入 FPGA 交易系统...254 现场可编程门阵列交易系统的优势...256 现货交易系统的不利因素... 257 关于 FPGAs 的最后话语...258 探索与加密货币的高频交易 什么是加密货币?259259 加密货币交易是如何运作的? 索引 什么是区块链?… 260 什么是加密货币挖掘?… 260 传统资产的相似之处 贸易和加密货币交易... 260 传统资产交易与加密货币交易的主要差异是 265 与加密货币交易所交易...267 加密货币中的高频交易策略...271 建立加密货币交易的高频系统 如何在云端构建交易系统 ... 275 总结...280
序言
交易市场的世界是复杂的,但利用技术可以更简单。当然,你知道如何编码,但从何处开始?你应该使用什么编程语言?如何解决延迟问题?《开发高频交易系统》一书解答了所有这些问题。
这个实用指南将帮助您导航算法交易的快节奏世界,并向您展示如何从复杂的技术组件构建高频交易系统,这些组件由准确的数据支持。
从高频交易(HFT)、交易所和交易系统的关键组件开始入门,本书迅速进入优化硬件和操作系统(OS)以实现低延迟交易的细节,如绕过内核、内存管理和上下文切换的危险。监控系统性能至关重要,因此您还将掌握日志记录和统计的知识。
当您超越传统的高频交易编程语言(如 C++和 Java)时,您将学会如何使用 Python 来实现高性能水平。没有潜入加密货币的交易书籍就不算完整。
到本书结束时,您将准备好使用高频交易系统进入市场。
这本书是为谁而写的
这本书适用于软件工程师、量化开发人员或研究人员以及 DevOps 工程师,他们希望了解高频交易系统的技术方面以及实现超低延迟系统所需的优化。具有 C++和 Java 的工作经验将有助于您更容易掌握本书涵盖的主题。
这本书涵盖
第 1 章,高频交易系统的基础知识,概述了高频交易的历史。您将了解市场参与者、基本的 HFT 要求(低延迟连接和基础设施)、HFT 与非 HFT 的交易时间范围,以及持仓期/头寸管理(HFT 与超 HFT)。我们还将详细说明赚钱的 HFT 专有策略。
第 2 章,交易系统的关键组成部分,深入解释了交易系统的工作原理。您将了解市场数据如何进入系统,以及处理数据和向交易所发送订单所需的不同功能。
第 3 章,了解交易交易所动力学,介绍了交易所如何成为市场微观结构的一部分。我们将首先介绍交易所的一般基础设施,并讨论匹配引擎的工作原理以及订单是如何匹配和传播给所有市场参与者的。
第 4 章,HFT 系统基础 - 从硬件到操作系统,阐明了硬件和操作系统如何协同工作。您将对软件与操作系统和硬件的交互功能有清晰的了解。本章将从处理器到交易系统进行讲解,包括操作系统、网络、操作系统调度程序和内存在内的所有层次。
第 5 章,网络运动中,表达了网络如何为高频交易提供帮助。你将对网络堆栈的功能以及在交易系统和交易所之间进行通信时的使用有一个清晰的理解。
第 6 章, 高频交易优化 - 架构和操作系统, 阐述了如何从一个常规交易系统创建一个高频交易系统。本节将涵盖多种现代技术, 以实现专为高频交易应用程序的最优低延迟性能。我们将讨论操作系统特性及其调度程序, 并深入研究操作系统的内核功能。
第 7 章,HFT 优化-日志记录、性能和网络,涵盖了交易系统的一个关键部分:日志记录和网络。您将了解日志记录如何帮助监控 HFT 系统,我们将学习如何在 HFT 环境中提高其效率。最后,我们将介绍如何使用网络优化与交易所的通信。
第 8 章,C++ - 微秒延迟的追求,定义了在超低延迟系统中优化缓存、内存和代码执行来使用 C++的情况。您将学习现代 C++功能和技术来有效地编写超低延迟代码。
第 9 章,针对低延迟系统的 Java 和 JVM,详细介绍了在超低延迟系统中优化垃圾回收、通信和数据结构方面使用 Java 的情况。
第 10 章, Python - 解释性但开放高性能, 说明如何在 HFT 系统中使用 Python。本章解释如何在 Python 中创建和使用 HFT 库。
第 11 章,高频 FPGA 和加密,描述了如何使用现场可编程门阵列(FPGA)创建更快的 HFT 系统。它将介绍在云中为加密货币构建 HFT 系统。
从这本书中获得最大收益
这本书假定您熟悉编程、硬件架构和操作系统。因为这本书将讨论减少交易延迟所需的优化,所以拥有计算机工程的基本知识是至关重要的。
大多数高频交易系统都运行在基于 Unix 的操作系统上。我们建议您使用 Linux 操作系统来应用本书中的知识。
这本书是来自许多计算机工程和金融领域的知识宝库。我们建议您阅读其他帕克出版社的书籍,如下所列:
我们也建议您阅读《编译器:原理、技术与工具》和《计算机体系结构:量化方法》等书籍。这些书籍将为您提供更深入的优化 HFT 的知识。
下载彩色图像
使用的惯例
本书中使用了许多文本约定。 代码在文本中:指文本中的代码词,数据库表名,文件夹名,文件名,文件扩展名,路径名,虚拟 URL,用户输入和 Twitter 句柄。这里有一个例子:"它为一个生产者到一个消费者(OneToOneRingBuffer)或多个生产者到一个消费者(ManyToOneRingBuffer)提供解决方案。" 以下代码:
/* Put header files here or function declarations like below */
extern int add_1(int n);
extern int add(int n, int m);
任何命令行输入或输出都写为如下所示:
>>> import math
>>> math.add_1(5)
6
粗体:表示新术语、重要词语或屏幕上显示的词语。例如,菜单或对话框中的单词以粗体显示。例如:"Load Data 组件(注释 1)将帮助获取历史数据。"
小贴士或重要说明
出现如此。
联系
我们的读者反馈总是受欢迎的。 如果您对本书的任何方面有任何疑问,请发送电子邮件至 customercare@packtpub.com,并在邮件主题中提及书名。
盗版:如果您在互联网上发现我们作品的任何非法副本,我们将非常感谢您提供该位置地址或网站名称。请通过 copyright@packt.com 与我们联系,并提供相关材料的链接。
分享您的想法
读完《开发高频交易系统》后,我们很想听听您的想法!请点击此处直接前往亚马逊评论页面,分享您的反馈。 您的评论对我们和科技社区很重要,将帮助我们确保我们提供优质的内容。
第 1 部分:交易策略、交易系统和交易所
高频交易(HFT)的历史概况,市场参与者,HFT 的基本要求(低延迟连接和基础设施),HFT 与非 HFT 的交易时间范围,以及持仓期/头寸管理(HFT 与超 HFT)。我们还将讨论 HFT 的地点。本书不是关于交易或 HFT 的业务,而是关于如何使用 Java、C++和 Python 具体实施 HFT 系统。您将了解交易系统的工作原理以及可以运行的交易策略。
这部分包含以下章节:
第 1 章,高频交易系统的基础
第 2 章,交易系统的关键要素
第 3 章,理解交易交易动力学
高频交易系统的基础
欢迎来到开发高频交易系统! 高频交易(HFT)是一种自动化交易形式。在过去 20 年里,HFT 在媒体和社会中越来越受到关注。2014 年,迈克尔·刘易斯撰写的一本名为《闪电男孩:华尔街的反抗》的书在纽约时报最畅销书榜上占据榜首 3 周。它涉及对 HFT 行业及其对交易世界的影响进行的调查。学者、金融界和非金融界都对这种交易形式感兴趣。与此同时,这个全新的交易时代也引发了很多恐惧,并让机器获得了越来越多的控制权。
本书的目标是回顾高频交易(HFT)是什么以及如何从技术角度构建这样的系统。高频交易是一个涉及计算机架构、操作系统、网络和编程等多学科知识的复杂事务。通过阅读本书,您将了解如何从头开始构建交易系统,并使用最先进的技术选择来优化速度和可扩展性。我们将本书分为三个主要部分。
在第一部分中,我们将介绍高频交易策略是如何运作的,以及我们可以预期从高频交易中获得何种交易。然后我们将介绍高频交易系统的功能。我们将以对交易所如何运作的描述来结束这一部分。
在本书的第二部分,我们将解释操作系统和硬件的理论,以及优化交易系统所需的知识,同时考虑硬件和操作系统的特性。
这将详细解释如何使用 C++、Java、Python 和 FPGA 来创建一个 HFT 系统。我们还将把这些知识扩展到加密交易,并将探讨如何在云中建立交易系统。
在这一章,我们将讨论我们是如何进入高频交易的。我们将回顾哪些交易策略适合高频交易。我们将详细解释是什么使高频交易与普通交易如此不同。 我们在本章的目标是涵盖以下主题:
高频交易的历史
高频交易
参与者有谁
高频交易中有效的交易策略
高频交易的历史
让我们讨论 1930 年前的交易所和金融市场的历史。 当我们谈论高频交易时,很难给出它开始的确切日期。我们需要回到人类接触贸易的原始时代。在现代现金发明之前,古人严重依赖互赠经济进行产品和服务的交易。根据彼得·沃森的说法,远距离贸易可以追溯到近 15 万年前。随着人口、货物和金钱的增加,贸易逐渐成为人类最重要的活动之一。赚钱显然意味着更多的业务。其中一个参数是速度。如果你进行更多交易,你就会赚更多钱。许多故事描述了商人渴望获得更好的交通工具等技术,以便更快地成交或更快地获取消息,从而利用那些无法获得这些新技术手段的人。
我们没有等待很长时间就看到了涉及那些在技术优势方面领先于他人的不公平贸易案例。1790 年,一位乔治亚州代表在美国众议院发言,揭露了高速交易者的行为。确实,国会正在讨论财政部长亚历山大·汉密尔顿的提议,即美国政府吸收各州在革命期间积累的前期债务(1790 年资金法案)。立即学会该决定的交易者马上购买或租用快船。他们的目标是超越信差,买入旧债,因为法案的通过会提高市场价值。在 20 世纪,高频交易或 HFT 的概念出现。
1930 年代后期
交易是商品交换的过程。它可以涉及金融产品、服务、现金、数字资产等。交易的目标之一是从这些交易中获利。交易数量与资产交换产生的金钱数量相关。当我们设法提高交易次数与时间的比率时,我们可以提高长期盈利能力。因此,提高交易次数的能力至关重要。交易参与者很快认识到他们需要缩短交易时间,并开始集中在某些特定场所。他们习惯在这些地点下订单,现在被称为交易所(或交易大厅)。高速自动化交易的扩张参与了一些主要事件。
1969 年:Instinet 是首批自动化系统基础设施之一。它加快了高速交易的结合。
1971 年:全国证券交易商协会自动报价系统(纳斯达克)于 1971 年创建,进行电子交易。
这是世界上第一个电子股票市场。最初,它只用于发送报价。
1996 年:岛屿 ECN 是美国股票交易的开创性电子通信网络,而 Archipelago 则通过创建 Archipelago Exchange(ArcaEx)促进了在美国交易所的电子交易。
2000 年代:10%的交易是 HFT 交易。
金融行业在 2000 年代初期吸引了越来越多的技术人才。通过引进这些技术人才,该行业开始快速发展。自动化、吞吐量、性能和延迟成为交易公司熟知的词语。高频交易交易量超过市场交易量的
10
%
10
%
10% 10 \% 。到 2009 年,
2
%
2
%
2% 2 \% 个交易公司占据了
75
%
75
%
75% 75 \% 的股票交易量。如今,仅有少数公司如 Virtu、Jump、Citadel、IMC 和 Tower 仍在从事高频交易。
现代时代
1930 年代后期关注股票市场(和商品市场的交易所)的透明度和监管。现代时代突出了电子交易,并提高了透明度。2000 年,美国证券交易委员会(SEC)提出了中央限价订单簿(CLOB)。CLOB 是一个透明的系统,用于匹配参与者之间的订单。更多的交易所(如 Island 和 Arca)进入了交易领域。交易公司、对冲基金和电子交易参与者的数量不断增加。他们创建了自己的技术栈,以更快地交易并保持竞争力。10 年后,只有少数交易公司设法保持竞争力,成为占所有股权交易量
75
%
75
%
75% 75 \% 的
2
%
2
%
2% 2 \% 。
高频交易(HFT)的必备技能需要大量投资:资金、人员和时间。它是低级系统专业知识和量化交易专家的结合,也吸引了聪明的投资者(投资者日益精通技术)。能够为设计超低延迟系统创建出色代码的工程师非常昂贵。只有少数工程师拥有这些技能。这种系统的性能要求专门的硬件。路由器、服务器和网络设备也很昂贵。因此,经验和进入门槛将阻碍许多新人进入,并限制竞争。除了我们之前讨论过的五家公司外,还有一些小型交易商店,利用他们在市场结构或某些技术事实中发现的优势来交易高频交易策略。大型高频交易公司是负责移动大部分股票交易量的公司。如今,高频交易估计占到美国股票(股票)交易量的至少 70%。自 2009 年顶峰以来,高频交易的市场份额和盈利能力都有所下降。
继 2015 年后,数字货币的增长为高频交易者开辟了新的机会。如今,我们可以看到许多知名的加密货币交易所,如 Coinbase、Binance 和数百家其他加密货币交易所,正在大幅增长应用高频交易策略。 这个现代时代确实将技术和自动化交易稳固下来了。交易模型是数据驱动和模型驱动的。市场数据业务无疑成为交易的重要组成部分。交易所和交易公司开始通过生成或收集市场数据赚钱,这些数据是任何算法交易员的原材料。
为什么有高频交易?
高频交易旨在每秒完成大量交易。通过这种方式,公司可以更快地对变化的市场做出反应。他们可以利用比没有这种速度时更多的机会。此外,大型机构从高频交易中获益,通过向市场提供大量流动性获得微小但可观的优势。他们下单数以百万计,这是他们系统所能胜任的。他们帮助市场,因此能够提高有利可图的交易收益,并获得更好的价差。由于回报率很低,他们必须进行大量交易才能获益。除了这些收入,他们还将获得交易场所提供的返点或优惠交易费,以吸引高频交易公司。
什么让高频交易与常规交易如此不同?
高频交易应该具有尽可能最短的数据延迟(时间延迟)和最高水平的自动化。高频交易与算法交易和自动化交易有关。因此,参与者选择在具有高度自动化和交易平台集成的市场进行交易。公司利用编程有精确算法的计算机来寻找交易机会并在算法交易中执行订单。为了提高交易速度,高频交易员使用自动化交易和快速连接(以及撤销或修改)。这是由于交易公司所拥有的技术以及交易所的技术。以下交易所已投资数亿美元用于高频交易技术:
纳斯达克交易所,位于纽约市,是世界上第一个电子股票交易所。其所有股票均通过计算机网络进行交易。它在 1971 年通过取消实体交易场所和现场交易的要求,革新了金融市场。它是世界第二大股票交易所,市值排名。纳斯达克综合指数的一半由科技公司构成。消费行业占综合指数的不到 20%,排名第二,其次是医疗保健行业。
纽约证券交易所(纽交所),位于纽约市,是世界最大的股票市场交易所。2013 年,洲际交易所(ICE)收购了纽交所。
伦敦证券交易所(LSE),位于英国伦敦,是欧洲最大的证券交易所,也是英国主要的股票和债券交易所。它成立于 300 年前左右。
东京证券交易所(TSE)是日本最大的证券交易所,总部位于东京。它成立于 1878 年。该交易所拥有 3,500 多家上市公司。由日本交易集团运营的 TSE 是世界上最大和最著名的日本公司的所在地,包括丰田、本田和三菱。
芝加哥商品交易所(CME),有时也被称为芝加哥商品交易所,是位于伊利诺伊州芝加哥的一家受监管的期货和期权交易所。CME 交易的行业包括农业、能源、股票指数、外汇、利率、金属、房地产和天气。
直接边缘,泽西城。它的市场份额迅速上升至美国股票市场的第十位,每天通常交易超过 20 亿股。更好的替代交易系统(BATS)全球市场是一家总部位于美国的交易所,交易各种资产,包括股票、期权和外汇。2017 年,CBOE 控股公司收购了它,它于 2005 年创立。BATS 全球市场在被收购前是美国最大的交易所之一,以为经纪交易商、零售和机构投资者提供服务而闻名。
芝加哥期权交易所
所有先前的交换都受到多个层面的控制:
交易限制
交易系统透明度(市场参与者之间共享的关于架构细节以及订单处理方式的信息)
被接受的金融工具类型
发行人的限制
大多数监管交易所的订单规模是一个问题。大宗交易对市场有重要影响(可能会产生市场冲击)。交易者使用备选交易系统(ATS),与传统交易所相比,这些系统受到的监管要少得多(不需要透明度)。暗池是最常见的 ATS 类型。美国目前有大约 30 个暗池,占美国合并交易量的四分之一。
暗池对高频交易商是有益的,因为他们能够满足速度和自动化需求,同时缩减了费用。这不是其他任何类型交易的情况,这使高频交易与一般交易不同。在下一节中,让我们了解更多有关暗池的信息。
暗池效应
为了财务安全,在暗池中买卖订单不会显示(价格和交易量)。换言之,暗池是不透明和匿名的,因为订单簿不会公开。由于在这种交易交易所无法看到订单规模,下大单的投资者不会影响市场。由于其他参与者看不到订单规模,暗池以固定价格执行这些大单。这减少了交易交易所带来的负面滑点。
暗池池被要求在交易发生后通知交易,尽管缺乏交易前透明度。
高频交易和暗池有着复杂的互动。暗池的兴起部分是由于投资者寻求保护,以免受到高频交易员在公开交易所的欺诈性活动的影响,而高频交易员也发现无法通过"扫描"来了解暗池中的大单。暗池引入了市场透明度的缺失,使得能力不足的参与者(即卖方)能够跟上当时的商业惯例,这些惯例与最先进的状态并不一致。当然,海因·博德克写了两本书(《高频交易的问题》和《市场结构危机》),探讨在暗池中发现不寻常的订单类型。
另一方面,一些黑暗池鼓励高频交易者在他们的交易所交易。高频交易策略增加流动性和订单成交的可能性。黑暗池帮助高频交易实现其速度和自动化需求,同时仍有较低的开支。高频交易者对黑暗池中订单规模的减少负有责任。黑暗池受到定位隐藏大单的探针交易策略的影响。
因此,如果存在这些高频交易策略,暗池的利益可能会受到损害。例如,在 2014 年,纽约州总检察长起诉巴克莱银行的暗池业务,指控其误报了巴克莱银行在暗池中的交易量。在 2016 年,巴克莱银行向美国证券交易委员会支付了数百万美元罚款,并向纽约州支付了数百万美元。
暗池可以施加某些限制,以防止高频交易者从事掠食性行为。目标是减少 ping 交易策略。 2017 年,Petrescu 和 Wedow 施加了最低订单量,以最小化这种类型的策略。
我们可以花更多时间讨论高频交易对暗池的影响的利弊,但最终我们会说,拥有更多流动性和更快的执行速度的优势足以让一些暗池支持高频交易。只要投资者充分了解交易场所的工作原理,从而做出有依据的判断,这对投资者来说是公平的。
我们已经讨论过主要交易所的位置。现在我们将在下一节介绍高频交易参与者。
谁进行高频交易?
每个人都有。从买方到卖方,从 ECN 到交易商和券商市场,它们都使用高频交易。高频交易由自营交易业务主导,涵盖了广泛的产品,包括股票、衍生品、指数基金、交易所交易基金(ETF)、货币和固定收益工具。自营交易业务占现有高频交易参与者的一半,多服务券商自营交易部门占不到一半,其余是对冲基金。凯盛集团(由 Getco 和 Knight Capital 合并而成)和主要银行的交易部门是该领域的主要参与者。一些新型场所(如 Dealerweb 的 OTR Exchange 和 IEX)正寻求提供一个卖方交易商觉得安全的交易场所,并由高频交易提供流动性。
高频交易已成为市场的主要参与者。他们也在抓住零售流。Citadel 正在控制大部分的零售流。
开始高频交易需要什么?
参与 HFTs 的人必须具备以下条件:
快速计算机:HFT 在大多数情况下关注单核处理能力,策略通常不使用并行处理。
在美国,我们使用共同位置。这是一个所有高频交易参与者都有他们的生产服务器的地方。他们将支付将他们的计算机与交易所的计算机服务器共同位于同一数据中心,以降低延迟并缩短完成交易所需的时间,甚至是微秒。连接所有市场参与者交易系统与服务器的电缆长度相同,以确保没有参与者拥有优势。美国证券交易委员会已发布广泛征求有关共同位置费用以及影响股票市场结构的其他问题的反馈的请求。为确保市场参与者之间的公平性,重要的是共同位置费用应合理定价。美国证券交易委员会邀请共同位置方报告他们的费用。
低延迟:在高频交易中,延迟指从数据到达交易员计算机、交易员根据数据下单以及订单被交易所接受的时间。订单可能在最有利的时候与其他交易员下的众多订单一起进入市场。在这种情况下,存在与大量其他人竞争的危险。订单的盈利性可能不如预期。高频交易员能够以难以置信的快速速度下单,这得益于被宣传为低延迟或超低延迟的技术。使用专门设计用于减少数据从一个地方到另一个地方的传输延迟的设备很重要。
计算机算法,它们是 AT 和 HFT 的核心,以及实时数据源,可能会损害收益。
在前几个部分中,我们了解了高频交易商在哪里进行业务。我们还讨论了进行更快交易的技术前提。现在让我们深入了解什么是 HFT。
高频交易策略
高频交易策略是算法交易策略的一个子集。它们以微秒(有时纳秒)的速度执行。这些策略必须意识到这一时间限制才能高效执行。它们部署尖端技术来比竞争对手更快获取信息。这种策略的主要目标是 tick-to-trade,即对市场数据作出响应的时间。正如我们将在下一章解释的那样,在尖端机器上托管交易策略很重要,它们还必须在托管环境中运行。
我们将定义应用程序的领域和一些术语,以在讨论高频交易策略时使用。
资产类别
高频交易策略可以应用于任何资产类别,如股票、期货、债券、期权和外汇。我们也有使用高频交易策略交易加密货币,尽管速度的定义不同(因为结算时间的原因)。
流动性
玩家对某种资产产生交互意愿被称为流动性。 我们将深度定义为给定资产的价格水平数量。我们会说一本书很深,当它有很多层(层)给定资产。我们将定义一本书是大或广,如果每层的成交量很高。如果一本书很深或很大,我们将定义给定资产的流动性为流动。这一陈述的结果是,无论何时交易者想进行交易,都会更容易买卖这种资产。结果,交易者都想要拥有大量流动性的交易所。加密货币交易所目前很难找到流动性。
逐笔数据和数据分布
高频交易每微秒都会生成订单。由于有很多参与者,这可能会产生大量数据。当我们研究高频交易数据以创建交易策略模型时,数据存储将是关键。
每个交易日,在流动性市场上会产生成千上万的价格变动(从一个订单到另一个订单),这构成了高频数据。这些数据在时间上呈现随机分布。高频交易数据呈现出肥尾分布。这意味着交易策略需要考虑可能出现大量损失的可能性。
市场数据的分布可分为两类:
波动率聚集:大变化会导致后续大变化,无论是正负,而小变化则会导致后续小变化。
远程依赖(长期记忆)指的是当两个位点之间的时间间隔或空间距离增加时,它们之间的统计依赖性衰减的速度。
流动性回扣
为了支持股票流动性的提供,大部分交易所都采用了 maker-taker 模式。在这种安排中,放置限价单的投资者和交易商通常会从交易所获得一定的返佣,因为他们被认为为股票流动性做出了贡献,即'makers'。
那些下市价单的人被认为是提供流动性的接受者,交易所会对他们收取小额手续费。尽管这些回扣通常只有每股几分之一美分,但对于高频交易者每天交易数百万股的情况来说,这些回扣加起来可能会是一大笔数额。许多高频交易公司使用旨在尽可能利用更多流动性回扣的交易技术。
匹配引擎
交易所的交易系统的核心,自动匹配买卖订单的软件程序,取代了交易所专业人士传统的工作,被称为"撮合引擎",对于保证交易所的高效运营至关重要,因为它负责匹配所有股票的买家和卖家。撮合引擎存储在交易所的计算机上,这也是为什么高频交易企业力求靠近交易所服务器的主要原因。我们将在第 3 章"了解交易所动态"中学习相关内容。
做市
在深入探讨做市商是什么之前,我们需要解释市场参与者和做市商之间的区别。
做市客/做市商
图 1.1 代表了交易所的限价订单簿。当交易策略下达的订单接近订单簿顶部(表示买入和卖出的最佳价格),我们称这是一个进攻性订单。这意味着该订单很可能与其他订单配对成交。如果订单执行,这意味着市场流动性被移除;它是一个市场接手者。当交易者以订单簿顶部的卖出价格下达买入订单时,我们称之为跨价。如果订单较为被动,该订单将不会从市场中移除流动性;它是一个做市商。
图 1.1 - 订单簿 - 被动/主动订单
让我们看看做市商策略。
做市商策略
交易公司可以在交易所提供市场制造服务。随着时间的推移,做市商协助买家和卖家配对。市场做市商并不是基于其相关资产购买或出售证券,而是维持持续的买卖报价,并从报价差中获利。
为减少长期持有股票的风险,每次购买都应该配合销售,每次出售都应该配合购买。如果某股票交易价格为
$
100
$
100
$100 \$ 100 ,"做市商"可以同时保持在
$
99.50
$
99.50
$99.50 \$ 99.50 的买入价和
$
100.50
$
100.50
$100.50 \$ 100.50 的卖出价。如果他们成功找到买方和卖方,即使没有其他人想买入,也能让那些想立即卖出的人实现出售,反之亦然。
做市商,换句话说,他们提供流动性-他们使交易更加简单。对于最交易活跃的股票,这种技术并不重要;然而,对于较小的公司(交易量小于大公司),增加交易量以促进交易可能是关键。做市是许多高频交易企业使用的一种方法。他们通过快速变更报价并进一步缩小价差来与其他人竞争:因为他们的做市业务可以迅速扩大到大量交易,所以他们愿意每次赚的钱更少。然而,高频交易公司的技术可用于其他目的,如套利(利用相关证券之间的细微差异赚钱)或执行(分解大型机构的交易以最小化市场影响)。我不会深入讨论太多,因为重点是高频交易能做的不仅仅是做市。速度才是最重要的。
做市可以通过订单流分析来实现
大量的买卖可以推动市场价格,基于动量。
流体的流动(买单和卖单有多大:小、中或大)。
动量耗尽(当订单流量枯竭时,这可能预示着价格反转)。
做市交易是高频交易者最广泛使用的交易策略。我们将在下一节讨论其他 HFT 策略。
炒股
皮肤掉落是一种交易方法,专注于从细微价格波动中获利并迅速转售。皮肤掉落是日内交易中用来描述一种专注于从微利中产生大交易量的技术。皮肤掉落需要严格的出场计划,因为一次重大损失可能会抵消交易者努力挣得的所有小赢利。要使这种技术奏效,你需要必要的工具,如实时行情、直接接入券商和进行大量交易的耐心。
寻找短期交易机会是一种概念,大多数股票将完成趋势的第一阶段。但从那里去向何处仍不清楚。一些股票在该早期阶段后停止上涨,而其他股票继续上涨。目标是尽可能从更多小额交易中获利。另一方面,让获利持续的思维旨在通过扩大获胜交易规模来最大化良好交易结果。通过增加获胜比例来弥补收益幅度,这种技术实现了结果。很少有长期交易者能够在仅赢得
50
%
50
%
50% 50 \% 或更少交易的情况下获得良好利润 -区别在于获胜交易的收益远大于亏损。
统计套利
有效市场假说(EMH)声称金融市场在信息上是有效的,这意味着交易资产的价格是准确的,并且在任何一个时刻代表所有已知信息。基于这一假设,如果没有任何基本消息,市场不应该波动。然而,这并非如此,我们可以用流动性来解释。
在一天之中,许多大型机构交易实际上与信息无关,而是与流动性有关。认为自己过度暴露的投资者会积极对冲或出售头寸,从而影响价格。寻求流动性的投资者常常愿意支付溢价以退出头寸,为流动性提供者带来利润。尽管这种从知识中获益的能力似乎违背了有效市场理论,但统计套利正是建立在此基础之上的。
统计套利旨在通过利用价格和流动性之间的相关性来获利,该策略基于统计模型对资产的预期价值来识别资产的被错误定价。
同一证券在不同场所的短期价格差异,或相关证券的短期价格差异,被用于统计套利,通常称为统计套利。统计套利基于这样的假设:证券市场存在价格差异,但会很快消失。由于价格差异可能只持续数秒,算法交易非常适合统计套利。
在多个场所交易同一证券时,例如,算法跟踪证券交易的所有位置。当价格差异出现时,算法在较低的市场买入,在较高的市场卖出,从而获得利润。由于此类差异的机会窗口很小(不到 1 毫秒),算法交易非常适合这种形式的交易。
统计套利在投资于关联证券时变得更加具有挑战性。一个指数和该指数内的单一股票,或一只单一股票和同一行业内的其他股票,都是相关证券的示例。在关联证券中,统计套利方法需要收集大量历史数据,并估算两个市场之间的典型关系。当存在偏离常态的变化时,该算法就会执行买入或卖出操作。
延迟套利
现代股票市场复杂,需要高度技术的系统来管理大量数据。由于其复杂性,数据不可避免地以不同的速度被处理。延迟套利利用市场参与者的不同速度。延迟套利旨在利用高频交易者更快的速度,通过利用高速光纤、优越的带宽、共同位置的服务器以及来自交易所的直接价格源等方式,在其他市场参与者之前下单。
低延迟套利背后的假设是,在美国,用于确定所有美国证券交易所的国家最佳买卖价差(NBBO)的综合数据源比高频交易者可获得的直接数据源更慢。HFT 程序的算法可以比许多其他市场参与者更快地读取交易数据,在证券信息处理器(SIP)数据源(这是综合的美国证券交易所价格数据源)之前的一小部分秒内看到价格变化,这主要是由于其更快的速度。这实质上为 HFT 软件提供了在其他市场参与者之前获取价格走向信息的能力。
新闻影响
信息是所有交易的核心,它被用于作出财务决策。算法交易系统利用新闻数据来生成交易决策的做法被称为信息驱动策略。
算法已经被开发出来阅读和分析来自主要新闻机构的新闻报道以及社交媒体上的内容。任何有可能改变市场价格的新闻都会导致算法进行购买或者出售。
高频交易者已经习惯于使用以信息为驱动的方法,以至于某些新闻机构现在以一种使计算机能够轻松分析它们的方式来包装他们的新闻稿。他们使用预先确定的关键词来描述有利或不利的事件,例如,这样一个算法就可以根据新闻稿中的关键词采取行动。在计划发布之前,新闻提供商还将新闻报道放在关键地理区域(如主要金融中心)的服务器上。这减少了数据从一个位置移动到另一个位置所需的时间。对于这种服务,新闻服务提供商收取额外费用。
根据先前推特上关于美联社被黑的报道,信息驱动型举措使用社交媒体正在增长。2013 年,一名黑客发推特称白宫发生爆炸,总统受伤,全球股票市场顿时暴跌,因算法从可信来源获取了坏消息并开始抛售。
下一步,让我们学习动量点火交易技术。
动量点火
您有机会进行金融交易,如果您发送到市场的订单可能导致价格变动,而您知道这一点。动量启动交易技术的目标是实现这一点。目标是让其他算法和交易员开始交易某只股票,从而引起价格变动。从本质上说,动量启动方法试图欺骗其他市场参与者相信即将发生大幅价格变动,从而引发他们的交易行为。结果,价格变动成为一种自我实现的预言:交易员相信价格将会变动,他们的行为也导致了这一变动。
向订单簿中发送大量订单并随后取消这些订单是动量引燃方法。这会营造出股票交易量出现巨大波动的假象,可能会引发其他交易者下单,从而导致短期价格趋势的开始。在尝试点燃市场行情之前,动量引燃方法包括执行真实的目标交易头寸。这意味着完成一笔对市场影响不大的交易。这使采用动量引燃方法的交易者能够在价格运动开始之前进入市场。在交易完成后,提交大量订单并随后取消这些订单,希望其他交易者跟随并推动价格变动,从而设置动量引燃。
交易员使用动量引爆技术后,当价格开始上涨时,便退出了最初的头寸并获得利润。
动量点火方法需要使用特定的订单类型,交易者只能利用能在短时间内发送和取消大量订单的算法来执行它们。
返利策略
市场订单交易者必须向交易所支付费用,而限价订单在增加流动性时则获得返现。因此,特别是从事高频交易的交易者会提交限价订单来建立市场,从而为交易所创造流动性。对于下大量限价单的交易者来说,这种定价方式风险较低无疑很有吸引力。
交易商-制造商定价
正在 Ping
通过下单少量可执行订单(通常为 100 股)来了解交易交易所和暗池中大订单的策略。
为了减少大订单对市场的影响,买方企业利用这种交易技术将大订单拆分成多个小订单。这种算法将这些订单缓慢地输入交易所。为了检测到这些大订单的存在,高频交易公司为每只上市股票安排 100 股的买卖报价。
这些 ping 交易将提醒高频交易参与者大订单的存在。高频交易商将利用这些信息确保从买方获得无风险利润。
一些重要的市场参与者已将 "pinging" 与"诱饵"进行了比较,因为其主要目标是诱使大型机构出具其庞大的订单,从而暴露它们的交易意图。
非法活动
美国证券交易委员会(SEC)、联邦调查局(FBI)以及其他监管机构近年来对指称的高频交易(HFT)违规行为进行了打击。以下章节是可能的违规行为的例子。
前跑
基于尚未公开发布的信息下达交易订单被称为"提前交易"。证券交易委员会(SEC)和金融业监管局(FINRA)已将这种做法定为非法。有人将"提前交易"一词用于描述高频交易公司利用算法交易技术来识别给定工具的大量新订单的做法。在这些大量订单进入市场之前,我们下单以从中获利。高频交易公司可以在购买资产后立即售出,从中获得收益。尽管这种交易方式在法律上是合法的,但监管者对此表示关切,未来可能需要予以规制。
欺骗
欺骗交易策略是非法的。它包括发送无意执行的订单,只是为了让其他市场参与者对这些订单做出反应。他们可能会发送订单来达到这个价格水平。同时,初始订单被取消,并且欺骗者从市场剩余的其他订单中获利。
多德-弗兰克金融改革法案第 2010 年修订版具体针对这种做法,甚至在那之前,金融业监管局的规定就禁止这种旨在误导市场的订单行为。立法者于 2014 年披露的首起刑事"闪欺"案涉及一名芝加哥交易员被指操纵期货市场。
层叠
分层与欺骗是一样的,只是订单是在不同价位下下单,以营造某种证券有很大需求的假象。这一策略的结果与常规欺骗一样。由于技术的急速进步,大规模的市场操纵可能在几秒内就发生。分层与普通欺骗一样,通常都是非法的,在 FINRA 规则中被禁止。
即使这些策略现在被禁止,我们也需要记住,一些交易所的监管程度较低或没有监管。我们将在第 11 章"高频 FPGA 和加密货币"中了解到,这些策略仍然可以发挥作用。
摘要
我们在本章回顾了高频交易(HFT)的起源。我们分析了 HFT 相比一般交易有何独特之处。我们还讨论了任何 HFT 交易系统都能支持的不同策略类型。我们谈论了交易系统的历史。本章的目标是让您深入了解什么是 HFT 以及我们可以使用哪些交易策略。
在下一章中,我们将讨论交易系统的主要功能。我们将描述如何建立交易系统。
2
交易系统的关键组成部分
在上一章中,我们学习了如何创建高频交易(HFT)策略。在本章中,我们将研究如何将这些策略转换为实时软件,以连接交易所并实际应用您先前学习的理论。我们将描述一个能够交易资产的交易系统的功能。
在本章中,我们将涵盖以下主题:
理解交易系统
制作交易系统与交易所交易
订单管理
制定交易决策的策略
到本章结束时,您将能够设计一个交易系统,将交易系统连接到交易所,并构建限价单薄。
理解交易系统
为 HFT 交易设计交易系统不仅需要编程和交易知识,还需要其他更多技能。本书后续章节将深入描述这些部分,这将为您在设计 HFT 系统中带来优势。在本节中,我们将讨论交易系统设计的基础。设计系统最关键的部分之一是详细描述需求。交易系统的目标是支持您的交易想法。任何交易策略都始于获取数据,并最终根据这些数据做出决策。交易系统将监督收集市场数据(即价格更新)并向交易所发送订单。此外,它还将收集交易所有关订单的信息。这些市场更新可能代表订单的任何状态:已取消、已拒绝、已完成或部分完成。它还将计算衡量您投资组合绩效的指标(如利润和亏损、风险指标或交易系统不同过程的信息)。
在决定是否创建这种类型的软件时,我们需要记住以下几点:
资产类别:了解将在交易系统中使用的资产类别将改变该软件的数据结构。每个资产类别都是独特的,都有自己的特点。建立一个用于美国股票的交易系统与建立一个用于外汇(FX)的系统是不一样的。美国的股票主要在纽约证券交易所(NYSE)和 NASDAQ 两个交易所进行交易。这两个交易所共有大约 7,000 家上市公司(代码)。与股票不同,外汇包括 6 种主要货币对、6 种次要货币对和 6 种 exotic 货币对。我们可以添加更多货币对,但不超过 100 个。与美国股票市场只有两个主要交易所不同,外汇市场将有数百个交易所。符号数量和交易所数量的变化将改变交易系统的架构。
交易策略类型(高频,长期头寸):软件体系结构将受交易策略类型的影响。HFT 策略需要在非常短的时间内传输订单。对于美国股票而言,标准交易系统将决定在微秒内发送订单。芝加哥商品交易所(CME)交易系统的延迟在纳秒级别。根据这一发现,技术将在软件设计过程中发挥重要作用。如果我们只考虑编程语言,Python 不适合速度,我们会更喜欢选择 C++或 Java。如果我们希望采取长期头寸,例如持续数天的头寸,交易员比其他人更快获得流动性的速度无关紧要。
用户(或交易技术)数量:随着交易者人数的增加,交易策略的多样性也在增加。这表明订单数量将会增加。在向交易所提交订单之前,我们必须确保即将发送的订单是有效的;我们必须确保特定工具的总头寸尚未达到。
交易策略正受到交易行业不断增加的规则的调节。我们将测试我们希望发送的订单的合规性,以确保我们的交易策略符合法规。所有这些测试都将增加计算所需的时间。如果我们有大量订单,我们将不得不按顺序对一种工具执行所有这些验证。如果程序速度不够快,订单处理时间会更长。用户越多,交易系统就必须越具有可扩展性。
这些变量改变了您对即将创建的交易系统的思考方式。让我们在以下部分讨论一个简单的交易系统的设计。
交易系统架构
以下架构图表示交易系统架构。在该图左侧部分,我们可以看到交易场所。交易场所是一个更广泛的术语,用于任何为多方的证券和/或衍生产品匹配买卖订单的平台。换言之,交易场所可以是交易所、ECN、聚合器或银行。交易系统与交易场所进行通信,以从所有参与者那里收集价格更新信息并发送订单。为此,交易系统需要一个称为网关的软件组件,用于确保交易系统与交易场所之间的通信。账簿构建器将从网关收集的数据构建限价单薄。最后,策略将通过订单管理器将订单发送到交易场所。订单管理器负责收集来自系统策略的所有订单,并跟踪订单的生命周期。这些组件都是将订单发送到市场的关键路径的一部分。
图 2.1 - 交易系统架构设计 此外,我们还观察其他不太关键的服务,如命令和控制,负责启动系统的组件。在算法交易中,查看器非常关键,因为它们将为您提供系统所有组件、订单和交易以及您认为监控交易策略很重要的指标的状态。算法交易自动化了交易。因此,跟踪您的交易系统和交易策略的健康状况非常重要。在高频交易中,几微秒可能会造成巨大损失,这一点尤为重要需要明白。拥有能够有效报告警报的查看器和用户界面至关重要。
我们将更深入地讨论交易系统的关键组件。
连接贸易交易所的网关
网关是交易系统中与交易所和交易系统通信的组件。它们是至关重要的,因为它们在执行时间方面最贪心。按设计,它们必须从网络获取数据并将该数据提供给系统的其余部分。这种操作对系统资源和操作系统来说是一种需求。价格更新由交易系统收集,然后代您传输订单。为此,您必须首先编写所有您在没有交易系统的情况下进行交易时会执行的程序。如果您想通过低买高卖赚钱,您必须首先决定要交易的产品。在选择了这些产品后,您应该从其他商家那里获得订单。
其他交易商将通知您他们愿意交易金融资产的意愿,并确定规模、价格和数量。一旦收到足够的您想交易的产品的订单,您可以选择与之谈判交易的交易商。这种物品的价格将影响您的选择。如果您计划在未来转售这种物品,您将需要以低价获得它。当你达成价格协议时,告诉其他交易商你想以列出的价格购买。当交易完成时,你就拥有了这个产品。
数据收集
网关从您选择的交易场所(交易所、ECN 和暗池)收集价格更新。这个组件(在下图中显示为网关)是交易系统中最重要的组件之一。这个组件的任务是将交易所的账簿信息输入交易系统。这个组件将连接到网络,并能通过交易所接收和发送数据流进行通信。
贸易系统的大门位置如下图所示。它们是贸易系统的输入和输出。
图 2.2 - 负责收集价格更新和发送订单的网关 以下点在前述图中有描绘:
交易商、交易所、电子通讯网络和暗池由场所表示。
不同的协议可用于连接场地(它们用箭头表示)。
有线网络、无线网络、互联网、微波和光纤都是传输数据的选择。在速度、数据损失和带宽方面,这些网络媒体各有自己的特点。
价格更新和订单的箭头是双向的,因为我们可以发送数据到各场所/从各场所接收数据。
要开始接收价格更新,网关将与场所建立网络连接,验证自身,并订阅某个金融工具(我们将在下一节中解释这部分内容)。
订单处理网关也接收和发送通信。当下订单时,它通过网络转发给场地。
如果场所收到此订单,将发送确认。当此订单与匹配订单相符时,将向交易系统发出消息。如果场所未收到订单,则不会发送确认。由交易系统宣布订单超时。在这种情况下,交易员需要介入并检查系统中出现的问题。
制作交易系统与交易所交易
交易系统包含多个功能组件,负责交易和风险管理,以及监控一个或多个交易所的交易过程。一旦编码,交易策略就成为交易系统的一部分。作为输入,您需要价格数据,作为输出,您的订单。这将产生交易信号。我们需要网关来完成这个流程,因为它们是最重要的组件。
交易系统的功能组件、网关接口以及交易系统与外部世界的交互情况如下图所示:
图 2.3 - 交易系统的功能组件 网关根据定价和市场反应收集和发送订单。它们的主要功能是建立链接,并将从外部世界接收的数据转换为交易系统所需的数据结构。
以下点在前述图中有描绘:
这个交易计划将在您应用交易策略时存在于您的机器上。交易将在另一台计算机上进行。
因为这两个设备位于不同的位置,它们必须通过网络连接。
系统使用的通信方式可能会根据其位置而有所不同。
如果交易系统共处于同一设施(机器在同一场所),则将使用单根电线,这将最大限度地减少网络延迟。
采用云解决方案的话,互联网可能成为另一种通信模式。在这种情况下,与直接连接相比,通信将明显更慢。
查看以下图表,它显示了网关之间发生的通信
图 2.4 - 交易所与交易系统之间的通信
我们从前面的图表中理解以下几点:
当我们更仔细地检查由网关处理的通信时,我们可以看到这些场所可能使用各种不同的协议。
将协议转换为交易系统数据结构,网关需要能够处理各种协议。
我们学习了交易系统如何连接到交易所。我们现在将讨论如何进行通信以及我们使用哪种协议来接收市场更新和发送订单。
查看通信 API
通信协议
网络协议
用户数据报协议(UDP)和传输控制协议(TCP)
互联网协议(IP)
软件协议
通信应用程序接口(API)
交易
网络基础
网络负责允许计算机相互连接。要共享数据,网络需要物理层。要实现某一级别的速度、可靠性或甚至安全性,选择恰当的介质(通信层)至关重要。我们在贸易金融中使用以下术语:
电线
光纤:更多带宽。
微波: 它安装简单,带宽很大,但很容易受到暴风雨的影响。
根据您选择的交易技术类型,媒体将会发生变化。在开放系统互联(OSI)模型(在第 5 章"运动中的网络"中开发)中,选择适当的媒体是网络第一层的一部分。物理层就是这一层的名称。在此之上还有六个层,描述了通信的类型。
像大多数的通信一样,金融业也在使用 IP。这是 ISO 模型网络层的一部分。这个 IP 建立了网络分组路由的规则。传输层是我们将要讨论的最后一层。TCP 和 UDP 是银行业中最广为人知的两种协议。这两种过程是相互对立的。TCP 是一种允许两台机器相互通信的协议。最初发送的所有消息都将首先被传送。UDP 缺乏确定网络分组是否被网络接收的方法。所有的交互都将使用 TCP 或 UDP 作为它们的协议。
在第 5 章节,移动网络中,我们将深入研究这些协议。让我们在下一节学习订单簿管理。
订单管理
数据处理的主要目标是将限价单簿从交易所复制到您的交易系统。簿记员将负责收集定价并对其进行分类,以便将您获得的所有簿本整合到您的策略中。
定价变更由网关转换,然后传递给图书生成器,如下图所示。图书生成器将使用网关从场馆收到的图书,以及收集和排序任何定价变更。
图 2.5 - 图书建设者从网关接收价格更新
在以下图示中,我们使用某金融产品订单簿的示例。订单簿包含两部分,一部分为买单,另一部分为卖单。对于每一部分,我们将存储订单的场所、数量和价格。每个场所将发送其自身的订单簿。订单簿构建程序的目标是综合考虑三个场所的订单簿来创建一个订单簿。本图示中所表示的数据为人工生成的。
图 2.6 - 交易系统从三个不同的场所组成账簿 以下在图表中描述:
您可以看到这些书中每一行都有一个订单。
例如,在场地 1 的报价单上的交易员准备购买 1,000 股
$
1.21
$
1.21
$1.21 \$ 1.21 。另一方面,有一份急于出售的人员名单。
报价(或询价)价格几乎总是高于出价价格。确实,如果你可以以低于销售价格的价格购买,那将太简单了。
书籍建设者的工作是从三个地方收集三本书,这些地方是由大门收集的。书籍建设者组织并整理这三本书。
我们已经学习了交易系统如何获取价格更新以及如何建立限价订单簿。我们现在将详细解释订单簿的不同功能。
订单簿考虑
股票限价买卖委托簿收集所有价格更新(订单)并以方便交易策略工作的方式排列它们。交易所利用委托簿跟踪出价和报价。在交易时,我们从交易所接收委托簿以确定资产价格的指示,确定最佳价格,或仅仅了解市场状况。我们必须利用网络传达对交易所委托簿的变更,因为交易所位于另一个平台/服务器。我们有两种方法可以做到这一点:
以首次发送整本书的方式。发送整本书会消耗大量时间。事实上,如果我们有大型交易所(如纽约证券交易所或纳斯达克),一秒钟内会有数百万个订单被发送。如果每次交易所收到新订单时都发送整本书,网络将会饱和,价格更新需要花费太长时间。
本书是交易系统的关键部分,它将为交易策略提供信息以决定何时发送订单。订单簿包含当前在交易所的出价和订单。当价格更新发送到我们的交易系统时,其他市场参与者会同时收到相同的更新。所有其他市场参与者也可以决定在此价格更新后运行。当交易所收到许多订单时,首先收到的订单将首先执行。这就是为什么订单簿在延迟中起重要作用,必须优化订单簿的所有操作。
订单生命周期的以下操作需要处理:
插入:插入是一个将新订单添加到订单簿的簿记操作。这应该是一个快速的操作。由于我们必须对收到的价格更新进行报价和报价排序,因此我们选择用于此操作的方法和数据结构是至关重要的。要插入新的订单,我们需要使用具有
O
(
1
)
O
(
1
)
O(1) O(1) 或
O
(
log
n
)
O
(
log
n
)
O(log n) O(\log n) 复杂度的数据结构。
修改订单
取消:使用订单 ID,取消允许将订单从簿册中撤回。
所选数据结构及与之相关的方法对性能有重大影响。如果您正在创建一个 HFT 系统,您将需要做出适当的决策。我们在 HFT 中实施的订单簿称为基于订单的订单簿。由于这是系统中的关键组件,因此非常重要要考虑此订单簿执行的复杂性。
有效的数据结构来模拟订单簿必须确保以下几点:
不断的查找,快速的数量更新:订单簿为一种特定工具存储了大量的订单。大型交易所每秒可能有数百万个订单。由于订单越来越多,保持订单 ID 的查找时间恒定很重要。我们每秒需要查找数百万个订单 ID 来更新这些订单。此外,我们需要快速检索最佳价格的订单。按价格查找订单的复杂度不能是线性的。因此,我们将使用快速索引(以对数时间查找特定价格的订单)。
以价格顺序迭代:当购买或出售大量时,我们可能需要找到许多订单才能达到给定的交易量。在这种情况下,我们将从最优价格开始,然后转到次优价格,并将继续这样做。在这种情况下,达到下一个最优价格的执行速度也非常重要,需要非常低的复杂性。
以恒定时间检索最佳买入价和卖出价:由于我们主要处理最佳价格,因此我们需要拥有一种数据结构,能够返回买入订单和要约订单的最佳订单。
我们需要考虑以下几点:
组织订单标识符以在巨大的关联数组中订单信息(对于 C++,可以是 std::unordered_map 或 std::vector)。
订单元数据包括对订单簿和它所属的价格水平的引用,因此,在检查订单后,订单簿和价格水平数据结构只需一次解引用即可。在使用订单执行或订单减少操作时,如果有价格的引用,就可以进行
O
(
1
)
O
(
1
)
O(1) O(1) 减少。如果您希望跟踪时间优先级,可以保留指向队列中下一个和前一个订单的指针。
因为大多数变化发生在书籍内部,为每本书的价格水平使用向量将导致最快的平均价格查找。因为期望的价格通常只是从内部几个层次,而线性搜索在分支预测器、优化器和缓存上更简单,从向量末端线性搜索平均比二进制搜索更快。当然,病理性订单可能存在于书籍之外,攻击者可能理论上在书籍末端传输大量更新以降低您的实现速度。但是,在现实中,这通常会产生一种缓存友好的、几乎可以用于插入、查找、更新和删除(在最坏情况下使用内存复制)的实现。
这具有极低的常量插入、查找、删除和更新的最佳情况行为。不幸的是,由于缓存、TLB 和编译器友好性,您可能会以低概率实现最坏情况行为,但仍有非常出色的常量。在最佳出价和要约(BBO)更新方面,它也非常快速,几乎理想。
如何在高频交易中实施图书的实现。我们需要深入了解计算机操作系统和编程。在下一节中,我们将深入探讨使用这些组件来实现最佳性能。
制定交易决策的策略
交易策略就是系统的大脑。这里是我们将我们的交易概念算法付诸实施的地方。让我们来看看这个图表:
图 2.7 - 交易策略从订单簿获取数据,作出交易决策
这种策略的信号组件只专注于产生信号。但是,拥有意图(信号)并不能保证您会获得您感兴趣的流动性。例如,在高频交易中,很可能会由于交易速度而被拒绝您的订单。
执行策略的部分将负责处理来自市场的响应。这部分决定了对于市场的任何响应该采取什么行动。例如,当订单被拒绝时应该发生什么?您应该继续努力获得等同的流动性和另一个价格。
在这一节中,我们学习了交易策略;现在,我们将学习关于订单管理系统(OMS)的所有内容,这是交易系统中最关键的最后一个部分。
世界卫生组织
战略提交的订单由 OMS 收集。订单生命周期由 OMS 跟踪(创建、执行、修改、取消和拒绝)。OMS 收集交易策略订单。如果订单无效或格式错误,OMS 可能会拒绝(数量太大、方向错误、价格错误、未偿还头寸过多或交易所无法处理的订单类型)。当 OMS 中发现错误时,该订单不会离开交易系统。拒绝会更快发生。因此,交易策略可以比订单被交易所拒绝时更快做出反应。让我们看看下图,它描绘了 OMS 的关键特征:
图 2.8 - 订单管理器收集交易系统中的所有订单 让我们现在讨论交易系统的关键组成部分。
关键组件
交易系统的关键组件包括网关、簿记员、策略和 OMS。它们集合了您开始交易所需的所有功能。我们通过聚合所有重要组件的处理时间来计算交易系统的速度性能。当价格更新进入交易系统时,我们启动计时器,当由此价格更新生成的订单离开系统时,我们停止计时器。这个时间段称为 tick-to-trade 或 tick-to-order 期。
综合订单管理系统(OMS)收集策略提交的订单。订单生命周期由 OMS 跟踪(创建、执行、修改、取消和拒绝)。OMS 收集交易策略订单。如果订单无效或格式错误,OMS 可能会拒绝(数量过大、方向错误、价格错误、未结头寸过高,或交易所无法处理的订单类型)。当 OMS 发现错误时,订单不会离开交易系统。拒绝会更快发生。因此,交易策略可以比订单被交易所拒绝时更快地作出反应。
非关键组件
非关键组件是那些与提交订单的选择无直接关系的组件。它们更改设置、收集数据并报告这些数据。在设计策略时,例如,您将需要一组实时更改的参数。您需要一个可以将数据传输到交易策略组件的组件。我们将使用一个名为命令和控制的组件来处理这个。
指挥与控制
交易者与交易系统之间的联系被称为命令和控制。它可能是一个命令行系统或接受交易者订单并将其路由到必要组件的用户界面。请看以下图表:
图 2.9 - 贸易系统用户界面
我们覆盖了负责与所有交易系统组件交互的命令和控制服务。我们现在将看到交易系统的其余功能。
服务
可能会添加额外的组件到交易系统。我们将讨论以下组件(这不是一个详尽的列表):
此服务器保持跟踪所有交易。它更新所有交易金融资产的头寸。例如,如果以
$
1.2
$
1.2
$1.2 \$ 1.2 的价格进行了 100,000 EUR/USD 的交易,名义头寸将为
$
120
,
000
$
120
,
000
$120,000 \$ 120,000 。如果交易系统组件需要 EUR/USD 的头寸数量,它将订阅位置服务器以获取头寸更新。订单管理器或交易策略可能需要在允许订单出去之前了解此信息。如果我们想将某一资产的头寸限制在 200,000 美元以内,另一个获得 100,000 EUR/USD 的订单将被拒绝。
日志系统:这将从组件收集所有日志并编写文件或修改数据库。日志系统有助于调试、查明问题原因,并提供报告。
观众(只读用户界面视图):这些显示交易的视图(如头寸、订单、交易和任务监控)。
控制查看器(交互式用户界面):这些提供了一种修改参数和启动/停止交易系统组件的方法。
新闻服务器:这从许多新闻公司(如彭博社、路透社和 Ravenpack)收集新闻,并实时或按需向交易系统提供这些新闻。
这个部分涵盖了交易系统的关键和非关键组件。我们现在将总结我们所学到的内容来结束这一章。
摘要
我们在本章学习了如何创建交易系统。我们创建的交易系统包括您设计交易系统并开始交易所需的所有必要组件。
学习如何构建交易系统需要多年时间。由于资产类别之间存在差异,您更有可能成为一个资产类别的专家,而不是另一个。我们创建了交易系统应该具备的最基本特征。我们必须学习如何将这个组件链接到交易系统,使其完全发挥作用。
在下面的章节中,我们将详细解释交易系统应如何实施,尤其是与操作系统和硬件相关的内容。在下一章中,我们还有更多知识要学习关于交易交易所。
3
理解交易交换动力
在之前的一章中,我们学习了如何创建高频交易(HFT)系统。我们非常集中地研究了交易系统的关键组成部分。我们还详细回顾了如何创建订单簿,这基本上是对交易参与者提供的所有内容的复制。在这一章中,我们将研究交易所的运作方式。 我们将描述交易所的功能组件,并深入关注匹配引擎。了解交易所的匹配引擎的工作原理是您在创建高频交易策略时必须完成的最重要任务之一。
本章将涵盖以下主题:
在第 2 章《交易系统的关键组件》中,我们对如何设计交易系统有了一个不错的想法。我们详细介绍了如何设计账本、创建交易信号以及接收市场反馈。在本章中,我们将深入解释交易所的运作方式。
构建大规模交易所以处理订单
现有所有者可以在证券交易所与潜在买家进行交易。交易所不是主要市场:它们可以是二级或三级市场。在证券交易所交易的公司并非每天都购买和出售自己的资产。他们可能在必要时回购股票或发行新股。在证券交易所,我们从另一名股东那里购买股票。当我们出售股票时,我们将其卖给另一名投资者。
交易所历史
在 16 世纪和 17 世纪,第一批证券交易所在欧洲出现,主要位于安特卫普、阿姆斯特丹和伦敦等港口城市或商业中心。然而,由于少数公司没有发行股票,这些早期的股票市场更类似于债券交易所。大多数早期公司被视为半公共企业,因为政府必须允许它们进行商业活动。
纽约证券交易所(NYSE),允许进行股票交易,最初出现在 18 世纪末的美国。费城证券交易所(PHLX)被认为是美国第一个证券交易所。1792 年签署《纽约证券交易所法》后,纽约证券交易所诞生。
随着当代股票市场的引入,监管和专业化的新时代开始了,确保股票买家和卖家能够相信他们的交易将以可接受的价格和合理的时间框架内完成。如今,美国和全世界有几个股票市场,其中许多电子互联。因此,市场变得更加高效和流动。当然,股票是最著名的交易资产类别;然而,外汇、固定收益、期货、期权、加密货币以及许多其他类型的资产类别也在交易。
股票交易所的股票价格可以通过各种方法确定。进行拍卖是最常见的做法,买家和卖家出价购买或出售。报价(或问价)是某人希望购买某物的价格,而出价是他们希望出售某物的价格。当出价和报价相等时,就会进行交易。
了解交易的特点
证券交易所(交易所)具有多种不同的特征。交易所是一个市场,将各种市场参与者聚集在一起,以简化交易、降低风险并有助于价格发现。交易所由几个组成部分组成。以下是一般的主要系统:
这些是市场参与者在交易所交易的公司。它们基本上是经过首次公开募股程序成为公众公司的私营企业。估值、流动性和合规费用都是选择上市交易所时需要考虑的重要因素。
撮合引擎:这将类似于旧的矿坑,经纪人站在附近对彼此大声叫喊指令。现在它已完全自动化为一个撮合引擎算法,负责处理交易。在市场上,引擎会发布订单簿(待成交订单)并正确进行撮合。这些交易被撮合和完成的速度有所不同,以纳秒为单位来计量。交易引擎确定价格的方式在不同交易所略有不同。在一般订单簿和撮合引擎部分,我们将更深入地解释它。
交易后:付款和结算,以及交易对账都是这个过程的一部分,以确保所有订单都正确匹配和完成。本质上,这是繁琐(但必要)的后端工作。
市场数据:交易所处理大量数据。它被出售给各种市场参与者。交易价格、交易量、公司公告/文件等都是这种情况的例子。我们在第 1 章"高频交易系统基础"中定义的共同位置也由于高频交易变得很普遍。因此,数据的访问速度也成为了一种营销对象。
市场参与者:结算会员和交易会员是市场参与者。每个参与者都有自己的一套资格要求,结算会员的要求更为严格。
交易所成员还会存入抵押品,以保护自身免受成员破产的影响。交易涉及两方,如果一方违约,交易所会与另一方完成交易。因此,交易所需要抵押品来对违约方提出索赔,同时维护市场稳定。经纪商和自营交易商是最常见的交易成员。清算会员是协助交易清算的重要参与者。
根据资产类别,不同的监管政策也不尽相同。不同的交易所将根据管辖区域制定不同的监管政策。这样做是为了防止洗钱和市场操纵,如内幕交易和操纵市场。 交易所也可以监控公司公告,以确保所有必要的披露都得到满足,从而促进透明的市场。除了管理市场参与者,交易所还必须处理内部合规和政府当局。 我们已经学习了交易所必须具备的特征;现在我们将详细讨论交易所的架构。
交换体系结构
交易平台负责执行从买方投资组合管理人处收到的订单,在执行过程中管理和监控订单,并提供对多个场所的电子访问。在卖方,需要支持处理客户订单和维护交易头寸。
交易架构提供买卖交易功能,并必须满足以下业务需求:
支持前台、中台和后台交易能力,以及基本和复杂的基于规则和算法的交易技术。
支持对前述策略在开发生命周期中进行回测和实时执行。
显示交易和出入账单用户界面(桌面应用程序、基于 Web/移动应用程序)。
支持以服务(TaaS)商业模式提供公用事业,并通过开放 API 进行交付。我们在前一章中谈到了使用 FIX 协议与交易系统和交易所进行 API 集成。
支持与广泛的外部各方进行全球一体化。
支持广泛的金融产品。
应该高度可扩展。
我们在下图中展示了一个交易所的主要功能(我们表示了三家公司的三个队列:特斯拉、微软和苹果)
交易交易架构 在这个图中,我们可以看到一个交易系统 T1 连接到交易所。正如我们在第 2 章解释的那样,交易系统的关键组件包括与交易所的价格更新和订单两个连接。当一个订单被发送到交易所时,它将遵循以下步骤:
根据资产类别和工具,它将被路由到队列。每个队列都是为一个给定的价格和一个给定的符号而创建的。
撮合引擎一次处理一个订单。
如果委托簿发生变化(由撮合引擎处理),该变化将通知交易员,并提供给所有市场参与者(如发生交易,每次更新将发送至清算/交易后处理)。
快速交易中交易员与交易所之间的通信必须高速进行。因此,用于传递消息的协议选择至关重要。基于字符串的协议(如 FIX 协议)是不够的。可以在微秒内进行交易的大多数交易所使用二进制协议。交易系统设计用于快速向交易策略提供数据。对交易所而言,目标是向撮合引擎提供数据。我们将在下一节深入描述撮合引擎算法。
交易明细册和撮合引擎
数百万投资者和交易者构成了整个市场,他们对某只股票的价值有不同的看法,因此出价购买或出售也不尽相同。在交易日中,这些投资者和交易者通过买入和/或卖出股票把意图变成行动,产生了分分钟的波动。
证券交易所为买卖者提供交易平台。普通人需要券商代理才能进入这些市场。券商充当买卖双方的中间人。
最初,在交易所上股票买卖双方的匹配是手动完成的,但现在更频繁地使用计算机化的交易系统。呼喊交易系统是一种手动交易形式,交易商利用语言和手势交流在交易场或交易所地板上购买和销售大量股票。这种交易形式已被电子交易平台所取代。这些技术可以比人类更有效率和更快地匹配买卖双方,从而带来包括交易成本更低和交易执行更快速等主要优势。
买家和卖家之间交易的意图保存在我们所谓的订单簿中。这个订单簿与我们之前描述的交易系统中的订单簿是相同的。它包含所有市场参与者的出价和报价。将匹配买家和卖家的过程由匹配引擎处理。这种算法将买单和卖单配对以执行证券交易。匹配引擎有不同的算法来描述订单如何匹配和填充的顺序,这取决于交易路由的位置。
匹配引擎算法在图 3.2 中描述。输入是来自交易员的订单(1)和订单簿(2)(其中包含已在交易所下单的订单)。该算法将返回交易列表(3)和剩余订单列表(4)。每个进入系统的订单都将逐一处理。
图 3.2 - 具有输入和输出的匹配引擎算法 当使用高频交易策略时,纳秒对于获得利润很重要。在这本书中,我们将详细学习如何优化交易系统以获得最佳性能。与此同时,对交易所的理解是必要的。正如我们之前所描述的,交易所是一台服务器,接受来自交易系统的连接并运行匹配引擎算法,该算法在订单簿上运行,订单簿是收集所有订单的结构。由于所有交易所都有自己的匹配算法,因此了解您在交易时将遇到的基本情况很重要。
在所有以下场景中,我们将解释订单进入交易所与订单簿之间的关系发生的情况。我们首先将学习最基本的情况,即以最佳价格进行匹配。
最优价格方案
默认情况下,匹配引擎会始终尝试为给定订单找到最佳价格。
根据图 3.3 中所示,匹配引擎算法寻找可用的最佳价格。在此图中,我们可以看到订单#1 进入交易所。该订单将与订单#3 匹配,因为订单价格对买家更有利。事实上,买家想以
$
1
0
0
$
1
0
0
$100 \mathbf{\$ 1 0 0} 的价格购买某项资产。交易所有这项资产以
$
9
9
$
9
9
$99 \mathbf{\$ 9 9} 和
$
1
0
0
$
1
0
0
$100 \mathbf{\$ 1 0 0} 的价格供应。匹配引擎将与可用的最佳价格
$
9
9
$
9
9
$99 \mathbf{\$ 9 9} 进行匹配。
图 3.3 - 最佳价格情景 在此上下文中,该算法的结果将是在
$
9
9
$
9
9
$99 \mathbf{\$ 9 9} 之间进行交易,涉及订单
#
1
#
1
#1 \boldsymbol{\# 1} 和#3。订单#2 将保持不变。
在这个示例中,数量为 100。我们需要了解当两个匹配订单的数量不同时会发生什么情况。
部分填充场景
在图 3.4 中的示例中,我们有订单#1 数量为
4
4
4 \mathbf{4} 以及订单#3 数量为
1
1
1 \mathbf{1} 。在这种情况下,为了填补订单#1,我们需要再有三份股票。这个交易所的订单簿中没有足够的数量来满足这笔交易。因此,订单#3 和订单#2 将被填满,剩余数量
1
1
1 \mathbf{1} 来自订单#
1
1
1 \mathbf{1} 将保留在交易所。这就是为什么在这种情况下算法的输出是两个已填满的订单和一个剩余的订单。
图 3.4 - 部分填充情景 在前两个例子中,我们有匹配的流动性。事实上,对于要求的价格,我们有一个与该价格相匹配的流动性。现在我们需要研究当流动性无法与另一个流动性相匹配时会发生什么。
没有匹配的情况
在图 3.5 所示的情况下,我们有订单#1 进入系统,订单簿有两个订单,#2 和#3。由于买入价格为 98 美元,远低于参与者准备出售的价格,订单匹配引擎将不会匹配任何订单。订单#1 将留在交易所:
图 3.5 - 无匹配情况
在前一个场景中,我们在书本中有不同的价格水平。我们需要研究如果流动性的价格相同会发生什么。
多个订单,价格相同
在图 3.6 中描述的场景中,我们有两个价格相同的订单和一个价格相同的新订单。订单的成交方式取决于撮合引擎的配置。
图 3.6-订单簿中具有相同价格的多个订单 匹配引擎的算法在决定我们想要在交易中鼓励什么样的行为方面至关重要。接下来的章节将讨论这些算法最流行的两种实现。
让我们讨论不同类型的算法。
先进先出
时间/价格优先,也称先进先出(FIFO)是最广泛使用的算法。从图 3.1 所示的交易架构可以看出,订单是按价位存储在队列中的。一旦订单进入撮合引擎,它们会被贴上进入系统的时间戳。因此,不会有两个订单拥有相同的时间戳。使用 FIFO 算法时,我们会将新订单与时间戳较早的订单进行撮合。在这种情况下,订单#3 在市场上停留的时间比订单#2 长,因此订单#3 会先与新订单#1 进行撮合。任何对订单的修改都会导致其在执行顺序中丢失优先级。根据不同交易所的规则,改变某个订单的数量可能会使其失去优先级。但对于所有交易所来说,如果价格发生变化,订单都会失去优先级,因为需要重新排入 FIFO 队列。
图 3.7 - FIFO 算法 即使 FIFO 算法是使用最广泛的算法,也有许多其他算法可以使用。我们将讨论的最后一种算法是纯比例算法。
纯比例制
订单使用按比例算法填充,考虑定价、订单批量和时间。市场参与者的订单会按数量平均分配到匹配的对手单。
图 3.8 - 纯比例
图 3.8 显示,以价格
$
1
0
0
$
1
0
0
$100 \mathbf{\$ 1 0 0} 购买的订单将与两个同价订单成交,不论其时间戳如何。交易所使用这种算法来鼓励参与者下单,即使这些参与者没有最快的参与者那么快。
为了鼓励交易,pro-rata 算法经常与其他算法一起使用。它通常用于激励市场参与者采取特定行为。
按比例分配
图 3.9 - 按比例算法变体 图 3.9 解释了比例算法变体。在图 3.8 中,订单簿中的所有订单都以相同的数量填满。在这种变体中,我们在填写订单时更多地考虑了订单簿中更早的订单。通过这种方法,交易所仍将鼓励参与者进行交易,即使他们反应不够快,但反应更快的参与者将获得更多的交易量。
任何异国配置都可以添加到此算法中。例如,如果我们想鼓励更大的订单,可以通过用更大的数量填充订单来引入权重。
让我们结束对匹配引擎可能遇到的不同场景的报道。我们现在将通过总结我们讨论的内容来结束这一部分。
摘要
正如之前所述,一纳秒可以在高频交易中创造一条边缘。通过了解交易所的微观结构(包括优先队列和匹配引擎),您将有助于设计交易策略。您现在知道,修改订单价格会导致订单在队列中丢失优先级。我们还了解到,根据交易所的不同,修改订单数量也可能产生相同的结果。这一章向您展示了如何设计交易所。我们深入了解了匹配引擎的工作原理。在下一章中,我们将解释硬件和操作系统如何在高频交易系统和交易所中运作。
如何设计高频交易系统
这部分旨在为您提供高频交易(HFT)系统的基础知识。本书提供了一步一步的指南,优化代码和操作系统(OS),以创建超低延迟软件。它将描述获得交易系统、操作系统和硬件协同工作的主要优化。
这部分包含以下章节:
第 4 章,高频交易系统基础 - 从硬件到操作系统
第 5 章,移动网络
第 6 章, HFT 优化 - 架构和操作系统
第 7 章,HFT 优化 - 日志记录、性能和网络
4
高频交易系统基础 - 从硬件到操作系统
在上一章中,我们学习了交易所如何运作。我们回顾了交易所的功能组件和匹配引擎。本章将解释高频交易(HFT)系统的基本硬件和操作系统(OS)。
本章将涵盖以下主题:
高频交易计算机
使用操作系统进行高频交易
编译器的作用
我们将在后续章节中了解,高频率是相对于交易策略和交易资产的类型以及您交易所的功能而言的。实现 100 微秒的交易延迟需要仔细的编程和对底层硬件的深入理解。您需要编写最佳代码来充分利用 CPU 和内存架构,并最大限度地减少 I/O 操作的开销。本章重点介绍如何获得基线(我们应该拥有的硬件和操作系统),以建立一个能够实现良好性能的自动交易系统。后续章节将帮助我们完善这一点,应用不同的优化技术来提高交易系统的延迟,甚至达到 10 微秒以下的延迟。
假设你想深入了解现代计算机系统架构的工作原理。在这种情况下,约翰·亨尼西和大卫·帕特森合著的经典著作《计算机架构:定量方法》对此进行了详细解释,并开发了统计模型来帮助理解性能权衡。在本章中,我们将关注高频交易系统需要的组件。以下部分将介绍这种系统所使用的硬件。
高频交易计算机
对于任何低延迟交易策略,很容易想象您可能需要某些专门的计算机硬件。事实并非如此-大多数硬件都是普通的现成硬件。对于大多数情况,如何配置硬件更为重要。图 4.1 显示了一个主要 CPU,代表了 HFT 系统开发人员如何看待 CPU 的架构。
图 4.1 - 主 CPU
正如我们在前几章中讨论的,在高频交易系统中,服务器的目的是处理基线交易功能:接收市场数据、执行算法模型和向交易所发送订单。这个系统有一个网络接口,可以向业务发送和接收数据,或与公司内部其他交易系统进行通信。第 5 章"运动中的网络"聚焦于此。一旦数据包脱离网线,中央处理器(CPU)就要做最繁重的工作。数据包将从网络接口进入主机内存,然后 CPU 会将数据包的内容提取到缓存中,以便执行核心进行解码和处理。
为了实现低延迟,您需要考虑您的软件在 CPU 中的执行方式,以及数据如何从各种硬件组件流向您的交易系统和算法进行处理。在以下几节中,我们将研究 CPU 的工作原理以及影响您软件性能的一些 CPU 微结构细节。
CPU、从多处理器到多核心
中央处理器是一个或多个处理器内核的集合,它们拉取并执行程序指令。这些指令可以作用于存储在内存中的数据,或与连接的设备进行交互。这些设备通常被称为输入/输出 (I/O) 设备,通过某种扩展总线(如 PCI Express (PCIe))连接到 CPU。过去,要实现多处理,需要在单个计算机中使用多个物理芯片。在过去的十年里,为了应对摩尔定律带来的缩放限制,大多数出货的 CPU 都在单个硅芯片上集成了多个内核。随着硅特性(如晶体管)的不断缩小,在制造过程中 fully functional 的芯片产出(收益)也成为一个问题,因此正在向多个芯片(有时称为晶元)集成在单个封装中的方向转变。
中央处理器核心擅长执行许多小型逻辑操作。例如,中央处理器可执行基本算术运算(加、减、乘、除)和逻辑运算(与、或、非、异或、位移)。更专门的操作,如 CRC32、高级加密标准(AES)算法的步骤,以及无进位乘法(如 PCLMUQDQ),也被直接实现在某些中央处理器核心上。中央处理器还可以处理从内存加载或从输入设备读取的信息。中央处理器还可以根据它计算或从其他地方读取的信息改变其执行路径。这些控制流指令是高级语言构造(如条件语句或循环)的基础。
当市场数据到达网络接口时,CPU 会处理它。这意味着解析通过网络发送的数据、管理交易系统不同功能部分的这些市场数据,并可能根据这些市场数据向交易所发送一个已触发的订单。在第 2 章"交易系统的关键组件"中,我们描述了基本元素。我们讨论了网关、订单簿和交易策略都是一起工作的组件,以触发一个订单。使用单个 CPU 执行核心,这些操作每一个都必须按顺序进行,这意味着一次只能处理一个数据包。这意味着数据包可能会排队等待前一个数据包完成处理;这会增加消息等待时间,然后交易系统才能向交易策略提供这些新数据。为了降低延迟,我们希望有许多处理单元并行工作,尽快处理已处理的市场数据,然后转移到刚刚到达的下一条消息。并行计算系统从计算起源就一直存在,尽管在早期主要用于高度专门的科学计算应用。在 1990 年代,多插槽服务器开始普及,在同一主板上有两个或更多 CPU。由于单 CPU 核心无法由于摩尔定律的限制而扩展性能,CPU 供应商开始在单个芯片上添加多个处理核心。现代服务器可以有多个 CPU 插槽,每个插槽都有多个 CPU 核心,在单台机器上实现了相当大的并行性。
图 4.2 描绘了一个现代多插座系统架构。内存或 I/O 设备直接连接到特定的 CPU 插座。它们被称为是与 CPU 本地的。其他 CPU 可以通过互联连接(如英特尔的 Ultra Path Interconnect 或 AMD 的 Infinity Fabric)连接到单一系统。假设一个 CPU 试图访问连接到不同 CPU 的内存或 I/O 设备,这被称为访问远程资源。当我们比较一个 CPU 访问其本地资源与通过互联连接访问远程 CPU 所需的时间时,我们发现互联连接要慢得多,仅访问本地内存。我们称这种访问时间为非均匀的,并将这些架构称为非统一内存访问(NUMA)。cache-coherent NUMA 或 ccNUMA 一词指的是,即使另一个 CPU 核心已修改了数据,CPU 核心也能保证对内存有正确的视图。NUMA 架构可以扩展到大量的核心。可以将每个 CPU 视为一个单独的计算机系统,通过网络互相连接。
图 4.2 - 一个四路 NUMA 体系结构。注意在此配置中 CPU 形成一个完全连通的图。 图 4,2 还代表了一些其他组件。PCIe 是一个连接其他设备的总线,如网络接口卡(NIC)。在 NUMA 体系结构中存在多个 CPU 时,额外的 CPU 可以通过在互连总线上请求数据来共享数据。
超线程和同时多线程
同时多线程,在英特尔 CPU 上称为超线程,是一种技巧,其中 CPU 跟踪多个并行执行状态(在超线程的情况下为两个执行状态)。当一个执行状态需要等待高延迟事件(如从更高级缓存或 RAM 获取数据)时,CPU 会切换到另一个执行状态,以等待获取完成;这是一种由 CPU 自身管理的自动线程,使每个物理核心显示为多个虚拟核心。
使用超线程(Hyper-threading)可以将物理核心数量翻倍,但这会引入难以控制的延迟,表现为上下文切换。
图 4.3 描绘了在一个多线程核心中使用超线程的情况。我们可以观察到,如果一个任务需要等待访问内存段而同时运行另一个任务,硬件可以模拟并发执行。如果一个系统调用(或中断)需要访问内核,所有任务都将暂停。
图 4.3 - 超线程 超线程的主要问题是它消除了任务切换(在软件层面)的控制,这可能导致更高的抖动和更高的延迟。
主随机存取存储器
主内存是一个大型的、非持久性的存储器,用于存储程序指令和数据。主内存是从 I/O 设备(如网卡或存储设备)读取数据的第一个目标。现代主内存可以以高吞吐量返回数据突发,但在请求某地址的数据并使数据可用时需要承受延迟的代价。
在典型的 NUMA 架构中,每个 CPU 都有一些本地 RAM。许多配置将有相同数量的 RAM 连接到每个 NUMA 节点,但这并非硬性要求。对 RAM 的访问延迟,特别是在远程 NUMA 节点上,可能相当高。因此,我们需要其他方法来隐藏这种延迟或缓冲数据,靠近执行某些代码的 CPU。这就是缓存发挥作用的地方。
缓存
现代处理器,具有许多个核心,拥有针对每个核心的本地缓存和针对单个插座上所有核心共享的缓存。这些缓存旨在利用程序通常在特定时间窗口内操作同一内存区域的数据的事实。这种数据访问的空间和时间局部性为 CPU 隐藏访问 RAM 的延迟提供了机会。
图 4.4 显示了一个现代多核 CPU 的典型缓存层次结构。L1 缓存分为两部分:数据缓存和指令缓存。L2 和 L3 缓存将自由混合指令和数据,就像主存储器一样。
图 4.4 - 缓存系统 我们现在将讨论缓存系统的结构。
缓存结构
不是一次从主存储器中读取单个单词或字节,而是每个缓存条目通常存储特定数量的单词,称为缓存行。整个行同时被读取和缓存。当读取一个缓存行时,需要驱逐另一个行以腾出空间。被驱逐的行通常是最近最少使用的,但也存在其他方案。不同级别的缓存有不同的缓存行大小,这是 CPU 设计本身的特性。为了提高缓存命中率,主要是在访问许多相关数据结构时,有许多细节需要考虑如何将数据结构对齐到缓存行大小。
一级缓存
一级缓存(L1 缓存)是计算机系统中最快的可用内存,它置于 CPU 执行单元附近。一级缓存包含 CPU 最近访问和加载到寄存器中的数据。CPU 供应商决定一级缓存的大小。
一级缓存被分为数据缓存和指令缓存。指令缓存存储 CPU 必须完成的操作信息,而数据缓存存储将要执行的过程中的数据。
二级缓存
二级缓存(L2)比一级缓存(L1)慢但更大。现代 L2 内存缓存以兆字节(MB)为单位进行测量,而 L1 缓存则以千字节(KB)为单位进行测量。L2 存储容量的大小取决于 CPU。然而,它通常在 256 KB 和 8 MB 之间。大多数现有 CPU 的 L2 缓存都大于 256 KB,这现已被视为较小的容量。目前最强大的 CPU 拥有超过 8 MB 的 L2 内存缓存。L2 缓存在性能方面落后于 L1 缓存,但仍远快于系统 RAM。L1 缓存通常比 RAM 快 100 倍,而 L2 缓存则比 RAM 快约 25 倍。
三级缓存
第三级缓存是最大的,但也是最慢的。第三级缓存包含在现代 CPU 中。第三级缓存更类似于一个全局内存池,整个芯片可以利用它,而 L1 和 L2 缓存专属于芯片上的每个核心。第三级缓存是我们所谓的受害者缓存:从某个核心的 L1 和 L2 缓存中驱逐的任何缓存行都将传送到第三级缓存,然后再送到主内存。它是一个通常完全关联的缓存,位于 CPU 缓存的填充路径中,存储从该级缓存中驱逐的所有块。所有核心都共享现代 CPU 上的第三级缓存。
共享内存
今天的大多数计算机系统,特别是那些带有多个插座的系统,创造了一个单一设计的幻觉,拥有一个主内存池。我们将它们称为共享内存系统,其中在任何 CPU 上运行的程序都可以访问连接到另一 CPU 的任何内存,就像它是运行代码的 CPU 的本地内存一样。
今天,有两种共享内存模型:统一内存访问(UMA)和非统一内存访问(NUMA)。UMA 使用单一内存控制器,所有 CPU 通过这个单一内存控制器与系统内存通信。在大多数情况下,内存控制器是一个独立芯片,所有 CPU 直接连接到该芯片。在 NUMA 架构中,存在多个内存控制器,内存被物理连接到特定的插槽。NUMA 架构相比 UMA 的主要优势是,NUMA 系统可以更快地扩展到更多 CPU,因为互连 NUMA 节点比连接多个 CPU 到单一系统内存池更简单。
在 UMA 的情况下,随着更多微处理器的加入,共享总线变得拥挤,成为性能瓶颈。这严重限制了 UMA 系统扩展可用 CPU 数量的能力,并增加了每个 CPU 核心等待主内存请求得到服务的时间。
所有现代多插槽服务器都采用 NUMA 架构。每个 CPU 插槽都有一个物理连接的内存池。由于每个 CPU 都有多级缓存,因此 CPU 可能会缓存另一个 CPU 内存中的旧版本数据(甚至另一个远程 CPU 可能已修改了本地 CPU 的内存)。为了解决这些情况,我们需要缓存一致性协议。这些协议使 CPU 能够确定它是唯一拥有者、共享者还是拥有本地修改版本的特定内存区域,并在其他 CPU 试图访问相同的内存位置时与之共享信息。理想情况下,应用程序应编写为很少需要使用这些协议,特别是在延迟和吞吐量很重要的地方,因为同步这种所有权的成本很高。
面向高频交易系统的 SMP 和 NUMA 系统通常被应用,在该系统中,处理可以在单个内存位置中分布在多个处理器上进行。在设计用于在交易系统组件之间传递消息的数据结构和系统时,必须考虑这一点。
输入/输出设备
计算机连接有许多不同类型的输入/输出设备,如硬盘驱动器、打印机、键盘、�老鼠、网卡等。我们在高频交易中应该考虑的主要设备是第 5 章"网络运动"中描述的网卡。大多数输入/输出设备通过外围组件互连快速通信(PCIe)连接到 CPU。PCIe 设备直接与 NUMA 基础设施中的特定 CPU 相关。在构建交易系统时,您需要考虑您的网络代码(如行情数据网关)是否保持在与网络设备连接的 CPU 上,以最小化延迟。
我们总是试图限制使用的设备是硬盘。访问硬盘上的数据成本很高,在高频交易系统中很少使用。但是,在回测交易策略时,信息会存储在磁盘上。我们需要以特定的方式存储数据,以确保快速访问。我们不会在本书中讨论这一部分,因为它不是特定于高频交易系统的内容。
使用操作系统进行高频交易系统
高频交易(HFT)软件运行在操作系统之上。操作系统是对硬件的一种抽象,隐藏了启动可执行文件、管理内存和访问设备的细节。减少延迟的一种技术是在适当的地方打破这种抽象,直接与硬件进行交互。这些应用程序充当用户(程序员)和硬件之间的接口。
操作系统具有若干主要功能,包括以下:
抽象访问硬件资源
进程调度
内存管理
存储和访问数据的方式
与其他计算机通信的方式
干扰管理
对于高频交易系统而言,主要的关键功能是流程安排。我们将在以下章节中详细描述任务安排的过程。
用户空间和内核空间
操作系统的核心是它的内核。内核是一个高度特权的代码块,位于应用程序和硬件之间。内核通常提供许多服务,从管理网络和通信的协议栈到在设备驱动程序的形式上为硬件设备提供抽象。内核高度特权,可以控制系统的工作方式,包括从任意物理内存地址读写,创建和销毁进程,甚至在向系统上运行的应用程序提供数据之前修改数据。必须小心保护内核,只有可信的代码应该在内核上下文中运行,也称为内核空间。
用户空间是应用程序运行的地方。用户空间进程是一个独立的虚拟内存空间,具有多个线程。用户空间进程往往具有较低的权限,需要内核提供特殊支持才能访问设备、分配物理内存或修改机器状态。交易系统运行在用户空间,但构建低延迟交易系统的一个挑战是最小化硬件和交易系统之间的抽象层数。毕竟,执行更多代码来转换数据格式、切换上下文到内核或其他进程来传递消息,或处理硬件状态的不必要变化,都会浪费时间,而不是运行关键的交易系统代码。
地址空间的分离是一个重要的概念。这部分与操作系统如何分配内存以及 CPU 如何理解内存有关,同时也是一个安全和稳定性的特征。未经明确许可,一个进程不应该能够影响内核或其他进程。没有共享内存或类似的通信技术,用户空间中的进程很难直接相互交互。这同样适用于内核,进程很难直接与内核交互。内核被设计用来谨慎地保护其敏感资源和数据结构。
进程调度和 CPU 资源管理
任何软件都是先编译并存储在耐用的长期存储设备(如固态硬盘或机械硬盘)上。当我们想要启动交易系统(或任何软件)时,我们调用存储在磁盘上的一个或多个可执行文件。这会导致操作系统创建一个或多个进程。
操作系统将软件加载到主内存中,创建虚拟内存空间,并启动一个线程来执行刚加载的代码。这个包括软件运行、虚拟内存空间和一个或多个线程的组合称为进程。加载完成后,操作系统最终会调度进程的主线程。调度程序负责确定与进程相关的线程何时何地执行。调度程序可以管理跨多个执行核心的线程执行,这些线程可以在多个物理 CPU 插槽上并行调度。正如前一节中描述的现代计算机系统,调度程序是对这些 CPU 核心的抽象。
当系统中的进程数量超过可用的执行核心数量时,调度器可以限制线程的执行时间,然后切换到另一个等待的线程。这种方式称为多任务处理。从一个进程切换到另一个进程的过程称为上下文切换。
上下文切换是一项昂贵的操作。操作系统保存被切换出的进程的执行环境,并恢复被恢复进程的环境。如前所述,交易系统利用多核来实现实时并行。物理执行核心越多,并行运行的线程越多,通常一个线程对应一个执行核心。
在现代操作系统中,有两种传统的进程调度方法:
抢占式多任务处理:Linux 和大多数操作系统实现了抢占式多任务方法。抢占式多任务处理旨在确保一个进程不能垄断整个系统。每个进程被分配一段特定的运行时间,这段时间称为时间片。一旦时间片用完,调度程序就会停止该进程的运行。除了防止进程占用过多时间外,这种方法还允许调度程序做出全局处理决策。许多抢占式多任务调度程序都试图了解 NUMA 拓扑结构,并尽可能将线程执行在靠近其资源的地方,但实现这一点通常很困难。
协作式多任务处理:这与其他方式有所不同,主要是因为它允许一个进程在自愿停止运行之前一直运行。我们称自愿停止运行的过程为交出控制权。这种方法通常用于实时操作系统,因为工程师不希望对延迟敏感的代码受到调度程序或其他正在运行的任务的干扰。您可以想象,如果某个关键安全过程的实时控制系统出现问题,或者某个订单延迟到达市场而被别人抢先,这将是灾难性的。像 Linux 这样的操作系统提供了一种形式的协作式多任务处理,如果谨慎使用,这对于延迟敏感的代码非常有用。通常,这是为了支持使用 Linux 的实时应用程序。
几乎所有任务调度程序实现都提供了多种机制来调整调度程序的行为。这可以包括针对每个进程的指导,如优先级、NUMA 和执行单元关联性、关于内存使用的提示、I/O 优先级规则等。Linux 允许将多个调度规则应用于正在运行的进程,使某些任务组可以使用实时调度规则。这些设置在设计低延迟系统时很有帮助,但需要谨慎使用;优先级设置错误可能导致优先级翻转或其他死锁情况。
调度程序在其默认配置中始终使用相同的公平性来处理所有资源和进程。这可以保证从一组请求中满足每个请求,并在预定的时间内完成,即使调度请求原语是不公平或随机的。在第 6 章"高频交易优化 - 架构和操作系统"中,我们将解释如何通过限制上下文切换次数来为高频交易系统专门设计进程调度。
内存管理
为了执行,软件需要将其指令和数据可用于内存中。操作系统指示 CPU 哪些内存属于哪些进程。
操作系统必须跟踪已分配的内存区域、将内存映射到每个进程、并指定要为给定进程分配多少内存。
内存管理单元访问的地址空间称为物理地址空间。这是您计算机上可用的物理内存。CPU 将为执行的进程分配此空间的某些部分。这些细分的空间称为虚拟地址空间。内存管理单元的工作是实时将该空间从物理映射到逻辑,以便 CPU 能够快速确定虚拟地址对应的物理地址。
页式内存和页表
现代操作系统不知道进程访问或存储的对象或数据。相反,操作系统关注基本的系统级内存单元。操作系统管理的最基本的内存单元是页。页是物理内存中大小统一且对齐的区域,其大小通常由 CPU 体系结构决定。使用嵌入在 CPU 中的称为内存管理单元(MMU)的硬件,可以将页映射到特定的虚拟地址。通过将分散的物理页重新映射到连续的虚拟地址范围,应用程序开发人员不必考虑硬件如何管理内存或页面在物理内存中的位置。操作系统执行的每个进程都将有其页面映射,称为页表。
图 4.5 表示使用页面的过程。任何物理页面都可以存在于多组页面映射中。这意味着不同的线程,可能在不同的 CPU 核心上运行,可以在其地址空间内访问同一个内存页面。
图 4.5 - 页面和进程
将物理和虚拟地址相互转换是由 CPU 内部的硬件自动完成的。因此,如果被转换的信息位于离 CPU 很近的快速位置,转换性能就会得到改善。事实上,用于存储这些信息的页表通常位于 CPU 内部的专用寄存器中,但这只有在页表很小的情况下才可能。CPU 内部还有一个专门用于页表的高速缓存,称为转译旁路缓冲区(TLB)。由于页表是一种存储在内存中的数据结构,如果某个进程的地址空间太大而无法完全容纳在 TLB 中,大多数 CPU 都会从其他 CPU 的缓存甚至主存中自动拉取相关的页表数据到 TLB 中。
页码调度可能会降低进程的性能。当在 TLB 中发生缓存失误时,操作系统必须从内存的其他地方加载数据。在高频交易(HFT)系统中,我们有时通过增加页面大小来最小化 TLB 缓存失误的影响。大于标准基页大小 4KB 的虚拟内存页称为巨页。对于大型数据集上的频繁访问模式,巨页可以提高内存速度。巨页也有成本 - 跟踪巨页的 TLB 有时可能比管理标准页的 TLB 小数个数量级,这意味着如果你有很多巨页映射,可能需要更频繁地访问内存。因此,必须谨慎使用巨页。
系统调用
系统调用意味着用户空间应用程序请求操作系统内核提供服务。系统调用是应用程序与操作系统沟通的方式。系统调用是软件向操作系统内核发出请求,以执行一些敏感的操作,如操纵硬件状态。现代操作系统上的一些关键系统调用,用于处理进程的创建和终止、管理磁盘上的文件、管理输入输出设备,以及与外部世界进行通信。
当系统调用被请求时,如果请求被允许,内核将执行该操作。对于许多系统调用,如果调用成功完成,应用程序将收到来自内核的某些响应。一旦系统调用完成,如果请求任务在其时间片内还有剩余时间,或者没有更高优先级的任务等待 CPU 时间,调度器就可以安排该任务恢复执行。内核在过程完成后,将结果提供给应用程序,并从内核空间向用户空间传输数据。
某些特定的系统调用,如获取系统日期和时间,可能需要几纳秒才能完成。一个更长的系统调用,如连接到网络设备或与磁盘上的文件交互,可能需要几秒钟。大多数操作系统为每个系统调用启动一个单独的内核线程,以最小化瓶颈。多线程操作系统可以同时处理多个系统调用。高频交易系统将大量使用并发执行的概念,例如使用线程。
现代 Linux 版本提供了虚拟动态共享对象 (vDSO),将一些特殊的内核空间函数导出到用户空间,特别是那些与检索当前系统时间有关的函数。vDSO 的威力在于这些函数在内核的控制下执行,因此了解硬件的具体情况,直接在用户空间进程中运行。与需要整个内核调用 (因此需要完全的上下文切换) 的 open 和 read 系统调用不同,像 clock_gettime (至少在 CLOCK_MONOTONIC 的情况下) 这样的函数调用开销很低,因为调用是在 vDSO 中进行的。
线程
任何流程中工作的最基本分工是一个线程。通过在许多线程上完成工作,可以实现并行。单个进程内的所有线程共享一个公共的虚拟内存空间。每个进程,由一个或多个线程组成,都有自己独特的内存空间。交易系统的主要活动是在不同的功能(潜在的进程)之间共享数据,以决定发送订单。在优化并发功能之间的通信时,将考虑使用线程或进程。这也会影响您在线程和进程之间传递数据的方式。在线程之间传递的数据可以利用内存分配的并发性,允许您只需给另一个线程一个指向数据结构中消息的指针即可传递数据。在进程之间传递数据,要么需要两个进程映射的共享内存池,要么需要将消息序列化到某个队列中,如第六章"高频交易优化 - 架构和操作系统"中所讨论的那样。
除了能共享内存外,线程的响应时间比进程更快。如果一个进程被分成多个线程,其中一个线程的输出可能会在完成执行时立即返回。它们的上下文切换时间也比进程更短。
因为系统调用是任何高频交易系统所需要的,所以抵消这一成本是至关重要的。我们将在第 6 章"高频交易优化架构和操作系统"中看到如何从线程和进程中获益。
干扰管理
外围设备如何提醒 CPU 发生了什么事情。CPU 会暂停一个处理核心,并切换为分配给该设备的中断处理程序的上下文。限制能够创建上下文切换的中断的数量;我们也将在第 6 章中回到这个问题,HFT 优化 - 架构和操作系统。
图 4.6 展示了在单核模型中使用中断(或系统调用)对 CPU 执行任务的影响。我们可以观察到调度器会在当前运行的任务和内核中的中断上下文之间切换。内核花费更多时间处理中断请求,这就减少了可用于运行用户任务的 CPU 时间。
图 4.6 - 任务调度中的中断或系统调用的影响 图 4.7 显示了两个 CPU 核心的好处,这两个任务不需要共享时间。这个例子表明,如果我们将任务固定在给定的内核上,我们将减少上下文切换的次数,并减轻内核中断的影响。这个例子还假设中断请求只由一个核心提供服务。因此,只有任务 1 会被打断来为硬件服务。
双 CPU 核心的优势
第 6 章,HFT 优化 - 架构和操作系统,详细介绍了将任务固定到指定核心的任务调度。
在第一和第二部分中,我们了解了硬件、操作系统以及它们在高频交易系统中的作用。现在我们将解决最后一个部分:编译和库,它们也是高频交易系统不可或缺的一部分。
编译器的作用
编译器将人类可读的源代码翻译成另一种语言,通常是机器专用语言,但也可以是虚拟机语言。它们将高级语言翻译成较低级别的语言。它们可以生成中间代码、汇编语言、目标代码或机器代码。它们还在加快软件运行时方面发挥了重要作用。编译器通过改进抽象和硬件高效执行开发人员所需表达的内容而变得越来越智能。新的编程范例被添加以改善软件工程。在 20 世纪 90 年代,Python 和 Java 使面向对象编程为每个人所用。我们建议读者查看由 Aho、Lam、Sethi 和 Ullman 撰写的编译器:原理、技术和工具(也称为龙书)一书,这本书将深入解释编译器的设计方式。
在高频交易系统中,编译器可以帮助优化我们花费大部分时间的代码部分:循环。Steven Muchnick 编写的《高级编译器设计与实现》描述了编译器可以执行的循环优化。我们必须谨记,高频交易系统的关键部分是时空权衡(增加内存使用和缓存利用,同时减少执行时间)。我们可以谈谈使用这种范式进行优化的一些示例:
循环展开是这种权衡的一个例子。因为循环展开时迭代次数减少,退出检查的开销也减少了。此外,分支指令更少,这可能会根据架构的不同而产生开销。对于完全展开的循环,没有退出测试。循环展开可能会导致编译器进行进一步的优化(例如,在上述完全展开的版本中,所有数组偏移量都是常量,这是编译器可能能够利用的)。
函数内联可以将函数调用替换为该函数本身的汇编代码,从而为更多的汇编代码优化提供机会。
表和计算。编译器可以帮助创建数据结构以避免重新计算。他们将保持已计算值的值。
编译器的主要功能是生成可由操作系统运行的可执行文件。我们现在将讨论可执行文件格式。
编译器和链接器将高级程序转换为适合目标操作系统的可执行文件格式。操作系统解析可执行文件以确定如何加载和运行程序。在 Windows 上,这是一个可移植的可执行 (PE) 文件,而在 Linux 上,这是一个可执行和可链接的格式 (ELF) 文件。每个操作系统都有一个加载器。加载器确定将程序的哪些块从磁盘加载到内存。加载器分配可执行文件将使用的虚拟地址范围。然后,它将从入口点开始执行(以 C 语言为例,即 _start 函数),该函数然后调用程序员定义的主函数。就内存而言,重要的是要记住,操作系统通过使用虚拟内存来保护进程之间的隔离,正如我们在讨论虚拟内存和分页时所描述的。每个可执行文件都在自己的虚拟地址空间内运行。
静态链接与动态链接
现代系统上许多可执行程序依赖于外部代码库,通常由第三方提供,例如操作系统供应商。为了处理这些外部依赖关系,程序可以通过两种方式集成该代码。第一种是静态链接所有代码,构建一个独立的二进制文件。第二种是动态链接外部代码,要求操作系统检查可执行文件,确定运行程序所需的库,并将其单独加载。
链接器将应用程序代码和依赖项编排为一个单一的二进制对象,并采用静态链接。由于此二进制对象包含所有依赖项,因此没有机会让程序利用同一库被多个程序重复使用,从而需要在运行时单独加载所有代码。例如,在 Linux 上,许多程序都使用 glibc 库。如果这些程序进行了静态链接,它们将浪费大量内存来重复存储相同的依赖库。静态链接有一个重要优势:编译器和链接器可以协作来优化所有函数调用,即使是从外部库中获取的对象也是如此。
动态链接允许链接器创建一个更小的二进制文件,其中依赖库的位置已被存根替换。动态链接器将在应用程序启动时从磁盘加载适当的共享对象来加载该库。只有当需要该依赖项时,它才会被加载到内存中。如果多个正在运行的进程使用同一个库,该库的代码内存可以在多个进程中共享。然而,这种效率是以成本为代价的:通过过程链接表(PLT)调用库函数时会间接引用。这种间接方式可能会带来额外开销,特别是当频繁调用库中的短函数时。典型的 HFT 系统将尽可能使用静态链接来避免这种开销。
摘要
在这一章中,我们开发了一个概念性模型,解释电脑如何工作以及如何考虑各组件对整体性能的影响。硬件和软件的各个部分必须以理想的方式协作,为交易系统服务。这通常需要了解硬件和软件之间的交互方式,从而避免低效算法或交互带来的负面影响,并进行优化。
我们正在使用本章中开发的基本原理作为基础。接下来的章节将致力于优化操作系统、内核和面向高频交易系统的应用程序。这将包括减少上下文切换的影响、安全访问共享数据结构的技术,以及其他降低底层硬件和软件中低效组件的方法。
下一章将重点讨论网络。我们将解释网络卡在高频交易系统中的作用,以及如何优化与交易所的通信以降低延迟。
动态网络
在前一章中,我们深入讨论了硬件和操作系统。任何交易系统都必须从交易所收集数据,并根据这些数据做出决策。为此,通信在高频交易(HFT)系统的性能中至关重要。在本章中,我们将深入探讨交易系统如何进行通信,如何在 HFT 系统中使用网络,以及如何监控网络延迟。
在本章中,我们将涵盖以下主题:
高频交易系统中的网络理解
高频交易系统之间的网络通信
重要的协议概念
为高频交易交易所设计金融协议
内部网络与外部网络
理解数据包的生命周期
监控网络
时间分配的价值
以下部分将介绍网络基础知识;我们将学习我们稍后要优化的基本知识。
高频交易系统中的网络理解
交易系统接收市场数据并向交易所发送订单。交易系统内的众多流程分布在不同的机器上,需要彼此进行通信-例如,负责跟踪一种工具头寸的流程需要向所有组件发送有关给定资产头寸的信息。网络定义了设备如何互相连接。网络是为了将数据从一台机器传输到另一台机器(延伸到交易所)所需的。 所有高频交易系统的基础都是网络,必须像仔细考虑软件系统的设计决策一样仔细考虑网络。
网络接口卡(NIC)
学习关于网络概念模型
开放系统互联(OSI)模型无疑是现代网络环境中计算机相互通信方式的最常见描述。OSI 模型是一个概念性框架,用于描述网络系统的功能。以下屏幕截图描绘了 OSI 模型的完整七层以及每层通常涉及的相关操作:
7
应用程序
高级 API
6
演示
应用程序和会话层之间的翻译;编码、压缩、加密。
5
会话
管理与其他端点的通信,例如重传。
4
运输
确保数据段在端点之间的可靠传输。
1
π
∑
0
2
0
π
1
1
1
π
∑
0
2
0
π
1
1
{:[(1)/(pi)],[sum_(0)^(2)],[(0)/(pi)],[(1)/(1)]:} \begin{aligned}
& \frac{1}{\pi} \\
& \sum_{0}^{2} \\
& \frac{0}{\pi} \\
& \frac{1}{1}
\end{aligned}
3
网络
地址管理、交通控制、路由。
2
数据链路
可靠的数据帧传输在物理角度来看
1
物理的
从原始位到适合于介质的任何形式的转换。
https://cdn.mathpix.com/cropped/2024_11_08_c298ff4244b140b858afg-095.jpg?height=140&width=44&top_left_y=1569&top_left_x=404 7 Application High-level APIs
6 Presentation Translates between Application and Session layers; encoding, compression, cryptography.
5 Session Manages the communication with the other endpoint such as retransmission.
4 Transport Ensures reliable transmission of data segments between endpoints.
"(1)/(pi)
sum_(0)^(2)
(0)/(pi)
(1)/(1)" 3 Network Addressing, traffic control, routing.
2 Data Link Reliable data frame transmission between endpoints from a physical point of view.
1 Physical Conversion from raw bits to whatever is appropriate for the medium. | ![](https://cdn.mathpix.com/cropped/2024_11_08_c298ff4244b140b858afg-095.jpg?height=140&width=44&top_left_y=1569&top_left_x=404) | 7 | Application | High-level APIs |
| :---: | :---: | :---: | :---: |
| | 6 | Presentation | Translates between Application and Session layers; encoding, compression, cryptography. |
| | 5 | Session | Manages the communication with the other endpoint such as retransmission. |
| | 4 | Transport | Ensures reliable transmission of data segments between endpoints. |
| $\begin{aligned} & \frac{1}{\pi} \\ & \sum_{0}^{2} \\ & \frac{0}{\pi} \\ & \frac{1}{1} \end{aligned}$ | 3 | Network | Addressing, traffic control, routing. |
| | 2 | Data Link | Reliable data frame transmission between endpoints from a physical point of view. |
| | 1 | Physical | Conversion from raw bits to whatever is appropriate for the medium. |
图 5.1 - 七层 OSI 模型
这个模型分为七个独立的层,每个层都有特定的功能,只与相邻的层进行通信,不与所有其他层进行通信。这些层的详细说明在此处描述。
会话层、演示层和应用层:这三层可以重新组合(简化)因为这些是我们将在软件级别使用的层。在高频交易系统中,我们关注以下四层,因为它们提供了高级优化机会。
传输层:它管理交付并包含数据包中的错误。网络层负责序列化、数据包大小和系统之间的数据传输。在金融领域,我们主要使用两种协议:传输控制协议(TCP)和用户数据报协议(UDP)。
网络层:这一层从数据链路层接收帧,并使用逻辑地址将它们传递到预定的目的地。我们将使用称为互联网协议(IP)的寻址协议。与 IP 版本 6(IPv6)不同,IP 版本 4(IPv4)是一种轻量级且用户友好的协议,是金融行业中最广泛使用的协议。
数据链路层:该层通过使用奇偶校验或循环冗余校验(CRC)等技术检测错误,从而纠正可能在物理层发生的错误。
物理层:这是两台机器用来通信的媒体,包括光纤、铜缆和卫星。所有这些媒体都有不同的特性(延迟、带宽和衰减)。根据我们想要构建的应用程序类型,我们将使用其中一个。这个物理层被认为是 OSI 模型中最低层。它负责在发送方的物理层和接收方的物理层之间传递原始的非结构化数据位,无论是电子还是光学方式。网络集线器、布线、中继器、网络适配器和调制解调器都是物理层中找到的物理资源。
正如您在图 5.2 中看到的那样,我们经常同时提到几个图层。例如,我们可以将第 5-7 层称为软件层,将第 1-3 层称为硬件层,第 4 层则在两者之间。这种情况非常普遍,因此使用一个简化的模型来整合软件、传输和硬件层是很常见的,它看起来像这样:
应用程序
应用层、表示层、会话层
TCP/IP
网络层-传输层
物理的
开放系统互联模型第一层至第二层
Application OSI Layers 5-7
TCP/IP OSI Layers 3-4
Physical OSI Layers 1-2 | Application | OSI Layers 5-7 |
| :--- | :--- |
| TCP/IP | OSI Layers 3-4 |
| Physical | OSI Layers 1-2 |
图 5.2 - 简化 OSI 模型
现在,我们已经讨论了数据包在两台通信计算机上的网络堆栈中必须经历的高级分层路径,我们将讨论如何为 HFT 设计网络。
高频交易系统之间的网络通信
当设计师为高频交易系统构建网络时,他们关注不同的通信模式。因为微秒很重要,他们必须考虑使用微波网络或思科交换机而不是其他交换机的优势。
网络创新有潜力带来巨大差异,影响贸易。 以下图表描述了网络的抽象模型。当两个设备通信时,需要一个介质来传输数据。它们通过连接到网络设备(如交换机)的物理连接进行通信。交换机负责将数据包从网络的一个部分移动到另一个部分,在那里我们可以找到数据发送方发送的收件人。
图 5.3 - 网络的抽象模型 每个网络组件对网络延迟至关重要。这些都是造成延迟的原因:
网卡将计算机的信号转换为网络信号,反之亦然。网卡处理数据的时间可忽略不计,但并非零。网卡被选中用于低延迟数据路径以及其他功能,例如以下功能:
总线:总线将数据从计算机的一个组件传输到另一个组件。我们可以找到三种主要类型的总线:外围组件互连(PCI)、PCI 扩展(PCI-X)和 PCI Express (PCIe)。它们都有不同的速度。在 2017-2018 年,行业开始使用 PCIe 5.0,工作速率为 63 吉字节每秒(GB/s)。虽然 PCIe 6 已于 2019 年发布,但 PCIe 5.0 仍是 NIC 最快的总线。
网口数量:网卡可以有不同数量的网口:一个、两个、四个或六个。它可以让机器同时访问多个网络。但是,同一台机器上也可以有多个网卡。
网口类型:网卡可以有不同类型的连接。 Registered Jack-45 (RJ-45)端口是一种端口类型。 它使用名为 Category 5 (Cat5)或 Category 6 (Cat6)的双绞线电缆。 我们还可以使用同轴电缆,它连接到 Bayonet Neill-Concelman (BNC)端口。 最后一个是光纤端口,使用光纤电缆。
网络速度:标准支持的网络速度为单车道 100 千兆位每秒(Gbps),25 Gbps 和 10 Gbps 信号。其他任何东西(即 400 Gbps,
50
Gbps
,
40
Gbps
50
Gbps
,
40
Gbps
50Gbps,40Gbps 50 \mathrm{Gbps}, 40 \mathrm{Gbps} 等)都包括多个并行车道。10 Gbps 和 25 Gbps 以太网每天都在数据中心和金融应用程序中使用。
应用特定集成电路(ASIC):集成了与主机 PC 通过 PCIe 和网络本身进行接口的功能。
集线器
交换机:交换机在数据链路层(第 2 层)和有时网络层(第 3 层)工作;因此,它可以支持任何数据包协议。它的主要作用是过滤和转发数据包跨越局域网。
路由器:路由器至少连接两个网络,并促进一个网络上的主机向另一个网络上的主机传送数据包。在高频交易系统中,路由器位于交易系统的网关(第 2 章《交易系统的关键组件》中提到)。路由器能找到最佳方式将数据包从一个主机转发到另一个主机。
主要组件(如路由器、网卡和交换机)将在高频交易系统中引入延迟。
理解开关的工作原理
主交换机是高频交易网络中通信的主要支持。
图 5.4 - 开关的抽象模型 图 5.4 表示交换机的抽象模型。"入口"和"出口"是业界用来表示任何网络设备的输入和输出(I/O)的词语。交换机工作于网络第 2 层。它的主要功能是根据转发规则,将数据包从输入转发到输出,这可以在前面的图中看到,即入口接口和出口接口。交换机处理两种类型的操作,如下所述:
配置数据包转发:对于简单的交换机,模型仅仅是观察端口上的媒体访问控制(MAC)地址,并将流量切换到该端口。更复杂的交换机(即支持第 3/4 层)将允许对其他匹配模式(即 IP 地址或端口)执行操作。
正转/过滤决策:根据读取的配置表转发数据包,必要时删除数据包。
启动后一次性设置好开关,根据需要动态生成转发表,例如路由表更新时。
解析器是第一个处理新数据包的(数据包主体独立缓冲,无法匹配)。解析器定义交换机的协议,识别并提取头部信息。
以下提取的标头字段发送到匹配-动作表(将标头字段与要执行的动作相匹配的组件)。入口和出口在匹配-动作表中分开。入口匹配-动作决定出口端口(s)和数据包被路由到的队列,同时这两者都可能修改数据包标头。数据包可能会被转发、复制、丢弃或由入口处理触发控制流。出口匹配-动作根据实例修改数据包标头(例如,对于多播副本)。为了跟踪帧到帧的状态,可以将动作表(计数器、速率限制器等)链接到流。
元数据,被视为类似于数据包头字段,可以被数据包在各个阶段携带。所有元数据实例都是入口端口、传输目的地和队列,以及从表到表移动的数据,而无需修改数据包的已解析表示。
网络结构之外,网络指标的关键部分是速度。我们将在以下部分定义一些速度指标。
带宽、吞吐量和数据包速率/大小
带宽是两个主机之间交换的理论数据包数量。通信达到预定目的地的速度称为吞吐量。两者的主要区别在于吞吐量衡量实际数据包传输,而不是理论传输。通过查看平均数据吞吐量,您可以看到有多少数据包到达目的地。数据包必须有效地到达目的地才能提供高性能服务。不丢失任何数据包非常重要。例如,如果我们想通过增量更新建立订单簿,丢失一个数据包意味着订单簿失去一致性。
在评估和测量网络性能时,数据包大小和数据包速率是两个关键标准。网络性能取决于这些参数的设置。吞吐量随数据包大小的增加而增加,然后降至饱和值。增加数据包大小会增加发送的数据量,从而提高吞吐量。
下面的截图说明了网络吞吐量(以千位每秒(Kbps)为单位)与数据包速率(以字节为单位的每秒数据包数)的关系:
图 5.5-不同数据包大小的吞吐量和数据包速率 图 5.5 中所示的两行分别对应不同的数据包大小(512 字节和 1,024 字节)。数据包速率增加时,网络吞吐量会提高,因为提高数据包速率意味着增加数据量,从而提高吞吐量。此外,图表显示,随着数据包数量的增加,吞吐量会下降,直到接近饱和点。较大数据包的吞吐量增加速度快于较小的数据包,1,024 字节数据包的吞吐量峰值在 50 个数据包时达到。 当一个接口达到最大吞吐量时,多个入口接口试图向同一出口接口提交出站数据包可能会导致缓冲。
切换队列
交换机的主要功能是将数据包路由至正确的接收者。当有大量数据流入时,处理数据的时间可能超过数据进入交换机的时间。为避免数据丢失,关键是要有缓冲区。这个缓冲区将存储等待处理的数据。交换机的主要作用是在输入端口接收数据包,查找目的地以获取输出端口,然后将数据包置于输出端口队列中。大量数据流向特定输出端口可能会使输出端口队列饱和。如果队列中积累太多数据,将导致严重的延迟。如果缓冲区已满,数据也可能丢失(数据包丢弃)。如果市场数据包丢失,将无法建立订单簿,从而中断交易。下图描述了交换机的队列情况:
开关队列 队首阻塞(Head-of-line, HOL)是一个重要问题。这个问题发生在当许多数据包被一个即将离开队列的数据包阻挡在队列中时,可能会增加时延或数据包乱序。如果许多数据包被阻塞在一个队列中,交换机会继续处理其他流向另一个输出的数据包,这会导致数据包不按顺序被接收。
我们了解到排队会影响数据包交付;现在,我们将讨论两种主要的交换模式。
切换模式 - 存储转发与直通
开关必须根据交换机机制接收和审查各种字节,然后处理数据包并转发到正确的出口端口。这里详细说明了两种交换模式:
贯通式切换模式有两种形式,如下所示:
无缝切换
快速转换
商店和转发切换模式
根据以太网帧目的地 MAC 地址作出转发决策。它们解析以太网报头中的源 MAC 地址位;它们记录 MAC 地址并创建 MAC 表。交换机在帧可通过出口端口传输之前必须接收和审查的帧数据量因交换类型而有所不同,如以下屏幕截图所示:
7 字节
1 字节
6 字节
2 字节
46
−
1500
46
−
1500
46-1500 46-1500 字节
前言
SFD
目标 MAC 地址
源 MAC 地址
类型
帧负载
FCS
7 bytes 1 byte 6 bytes 2 bytes 46-1500 bytes
Preamble SFD Destination MAC Source MAC Type Frame Load FCS | 7 bytes | 1 byte | 6 bytes | | 2 bytes | | $46-1500$ bytes |
| :---: | :---: | :---: | :---: | :---: | :---: | :---: |
| Preamble | SFD | Destination MAC | Source MAC | Type | Frame Load | FCS |
穿透
收到的字节
…
…
dots \ldots
接收的字节
穿透
收到的字节
Cut-Through
Bytes Received dots
Bytes Received
Cut-Through
Bytes Received | Cut-Through | |
| :---: | :---: |
| Bytes Received | $\ldots$ |
| Bytes Received | |
| Cut-Through | |
| Bytes Received | |
整个框架(最多 9200 字节) 图 5.7 - 根据收到的帧字节切换模式
图 5.7 展示了三种模式,并代表了应该接收多少信息。我们将在下面详细学习这些。
商店和转发模式:在转发帧之前,交换机必须完全接收该帧。基于目的地 MAC 地址查找来决定是否转发该帧。为了确认数据的完整性和准确性,交换机使用帧校验序列(FCS)字段。如果 CRC 值不匹配,该帧将被视为无效并丢弃。在传输帧之前,检查目的地和源 MAC 地址是否匹配。
默认情况下,接受大小在 64 字节到 1,518 字节之间的任何帧,其他大小的帧将被丢弃,导致比其他三种方法更高的延迟。
切通交换模式:此模式允许以太网交换机在接收到帧的前几个字节时做出转发选择。该模式有两种类型,如下所述:
无碎片切换:此模式要求在转发帧之前解析前 64 个字节。
快速转发开关:当交换机接收到帧的目的 MAC 地址时,仅需要前 6 个字节即可转发该帧。
我们看到了两种主要的交换模式;我们现在将描述交换机可以执行数据包转发的不同层。
第 1 层交换
物理层开关,也称为第 1 层开关,是 OSI 模型物理层的一部分。第 1 层开关可能是电子和可编程补丁面板。它所做的不过是在端口之间建立物理连接。链接是通过软件指令建立的,允许自动或远程配置测试拓扑。第 1 层开关不读取、修改或使用数据包/帧头来路由数据。这些开关对数据完全透明,延迟非常低。在测试环境中,端口之间的透明连接很关键,因为它们可以确保测试结果与直接使用连接线的一样准确。Arista/Cisco 是第 1 层开关的一个例子。
二层交换(或多端口桥接)
分层 2 交换机有两种功能,如下所述:
在第 1 层(物理层)传输数据
检查任何接收和发送的帧的错误
这种类型的交换机需要 MAC 地址来转发帧到正确的收件人。所有收到的 MAC 地址都会保存在转发表中。这个表允许交换机以非常高效的方式转发数据。与更高层级的交换机(高于 3 层)可以根据 IP 地址传输数据包不同,2 层交换机不能使用 IP 地址且没有优先级机制。
三层交换
第 3 层交换机是以下设备:
根据源地址和目标地址分析和路由数据包的智能 IP 路由的路由器
交换机
我们现在将讨论一个能够使用公共地址从许多私有 IP 地址路由数据的系统。
网络地址转换
将私有 IP 地址转换为公共地址的过程称为网络地址转换(NAT)。大多数路由器使用 NAT 允许多个设备共享单个 IP 地址。当机器与交换机通信时,它会寻找交换机的方向。这个请求被发送为一个包从机器到路由器,转发给企业。路由器必须首先将源 IP 地址从私有本地地址转换为公共地址。如果数据包包含私有地址,接收服务器将无法知道将信息返回到何处。由于 NAT,信息将使用路由器的公共地址而不是笔记本电脑的私有地址返回到笔记本电脑。
网络地址转换(NAT)是一种耗资源密集的操作,对于任何使用它的设备来说都是如此。这是因为 NAT 需要读取和写入每个 IP 数据包的报头和负载信息来完成地址转换,这是一个耗时的过程。它会增加中央处理器(CPU)和内存的消耗,可能会降低吞吐量并增加数据包延迟。因此,在实时网络中安装 NAT 时,了解 NAT 对网络设备(特别是路由器)的性能影响变得至关重要,尤其对于高频交易(HFT)来说。大多数现代交换机可以在 ASIC 中至少执行静态 NAT,但越来越多的交换机也可以执行动态 NAT,只有轻微的性能损失。
我们详细研究了如何传输数据包。我们现在将描述设定数据包转发规则的协议。
重要的协议概念
当两个设备需要通信时,一旦它们有了从发送方到接收方传输信号的方法,我们就需要有制定通信规则的协议。协议就像两个组件在系统中同意使用的语言;它设定了通信的规则。下图代表了交换和交易系统的网络基础设施:
图 5.8 - 交易交易所和交易服务器的交易网络基础设施
在第 2 章,交易系统的关键组件,以及第 3 章,了解交易交易动态,我们看到交易交易所、市场数据馈送处理程序和市场参与者是传统交易系统的三个主要组件。
通过网关服务器,报价撮合系统从市场参与者那里收到订单。数据处理程序从交易所获取数据,并以最短的延迟传送给关注的市场参与者。我们使用 FIX Adapted for STreaming (FAST)协议(在 FAST 协议一节中有详细介绍)来传输市场数据。
我们现在将讨论高频交易中的以太网协议。
以太网用于高频交易通信
以太网是用于连接有线局域网(LAN)或广域网(WAN)设备的最常用协议。该协议规定了设备之间的通信规则。
以太网规定网络设备如何构建和发送数据,以便其他设备在同一 LAN 或公司网络上识别、接收和处理该数据。这种协议高度可靠(抗噪音)、快速和安全,由 1983 年 IEEE 802.3 工作组设计。该技术一直在不断改进,以获得更好的速度。
100BASE-T,即快速以太网,至今仍在使用。
使用 IPv4 作为网络层
互联网协议在 OSI 模型的网络层运行,而 TCP 和 UDP 模型在互联网层运行。因此,此协议负责根据主机的逻辑地址识别主机,并通过底层网络在它们之间路由数据。
互联网协议寻址系统提供了一种唯一识别主机的技术。IP 采用尽力而为的交付方式,这意味着它无法保证数据包能发送到预期的主机,但它会尽最大努力去实现。IPv4 的逻辑地址是 32 位。
当使用 IPv4 协议时,我们可以使用三种不同的寻址模式,如下所述。
单播模式
只有一个指定的主机以这种方式接收数据。目标主机的 32 位 IP 地址存储在目标地址字段中。在这种情况下,客户端将数据传输到所需的服务器,如下图所示:
图 5.9 - 单播模式 如图所示,机器 A 向机器 C 发送信息。
广播模式
在此模式下,该数据包是发送到网段内的所有主机。目的地址字段包含特定的广播地址 255.255.255.255。当网络上出现此数据包时,主机有义务对其进行处理。在这种情况下,客户端发送了一个被所有服务器收到的数据包。由于几乎无法控制哪些机器会收到流量,并可能产生不必要的开销,因此广播很少用于高频交易(HFT)系统。您可以在以下示意图中看到广播模式的说明:
图 5.10 - 广播模式 正如先前图表所示,机器 A 将信息发送给所有机器。
多播模式
这种模式是前两种模式的混合,数据包并非发送给单个主机,也不是发送给该分段上的所有主机。该数据包的目标地址字段有一个独特的地址,以 224.x.x.x 开头,可由多个主机服务。主机将订阅特定的多播源。使用互联网组管理协议(IGMP),主机进行通信以通知上游服务它想订阅特定的源。许多交换机都有监控主机 IGMP 流量并窥探订阅源的逻辑。这使交换机能够确定应将多播流量复制给哪些主机。不实现 IGMP 窥探的交换机将多播流量视为广播流量。以下图表所示即为多播模式的示意图:
图 5.11 - 多播模式:机器 A 向机器 B 和 C 发送信息 在这一部分,我们回顾了网络层及其组件。现在我们将讨论传输层以及 UDP 和 TCP 协议。
UDP 和 TCP 用于传输层
基于以太网的 TCP/IP 或 UDP 是证券交易所和其他市场参与者使用的最常见的通信协议。非关键数据,如市场数据源,通常使用 UDP 传输以降低延迟和开销。TCP 和 UDP 协议族中最重要的协议之一是 IP。诸如订单等关键数据是使用 TCP/IP 协议传输。
传输控制协议(TCP)指定计算机如何连接到另一台机器,以及如何在它们之间传输数据。该协议是可靠的,并提供端到端(E2E)字节流网络传输。
数据报方向协议(UDP)用于广播和多播类型的网络传输。与 TCP 不同,UDP 不保证数据包传递。
主要差异概述如下:
传输控制协议是一种面向连接的协议,而用户数据报协议是一种无连接协议。
因为 UDP 没有任何机制来检查错误,所以 UDP 比 TCP 更快。
传输控制协议需要进行握手才能开始通信,而用户数据报协议不需要。
传输控制协议(TCP)检查错误并进行错误恢复,而用户数据报协议(UDP)检查错误并在出现问题时丢弃数据包。
用户数据报协议(UDP)没有传输控制协议(TCP)的会话、排序和交付保证特性。UDP 在延迟很重要的情况下使用,因为数据是以数据报的形式传递的。市场数据通常出于以下两个原因使用 UDP,如此处所述:
面向数据报的传递可以具有更低的延迟(但是如果有什么丢失,恢复会更复杂)。
多播不支持面向连接的协议(因为流量是多对多的通信类型)。
这通常通过应用层协议中的序列号以及提供带外机制来请求重传缺失的序列号来解决。如今,有一种趋势是使用 UDP 进行订单传输(UFO),这使我们能够更快地发送订单。
为高频交易交易所设计金融协议
让我们回到第 2 章"交易系统的关键组件"中介绍的以下图表。理解交易系统和交易所之间的通信机制很重要。
图 5.12 - 交易所与交易系统之间的通信 两个实体必须说同一种语言才能互相交流。为了实现这一点,他们使用网络中使用的协议。该协议被用于各种交易场所(有时称为交易场所)的交易。视交易场所而定,可能会有各种各样的协议。如果一个给定的交易场所和您的交易系统使用的协议相同,连接就可能实现。视交易场所的数量而定,一个场所通常会使用某种特定的协议,而另一个场所则使用不同的协议。交易系统需要建立在对其他协议的理解之上。尽管各个交易场所的协议存在差异,但它们建立连接并开始交易的过程是相似的,正如这里所概述的那样:
他们建立一个登录信息,指明了交易发起人、接收人以及连接将如何持续存在。
他们接下来询问他们从各公司期望什么,如订阅交易或接收价格更新。
他们也会收到订单以及价格变动。
他们然后发送心跳来维持连接。
最后,他们道别了。
金融信息交换(FIX)协议
修复协议
交易中最常用的协议是金融信息交换(FIX)协议,我们将在本章中讨论这一协议。它于 1992 年成立,目的是处理 Fidelity Investments 和 Salomon Brothers 之间的国际即时交易证券。其中包括外汇(FX)、固定收益(FI)、衍生工具和结算。这是一种基于字符串的协议,意味着人们可以阅读它。它是平台无关的,开放的,并有多种变体。
这里有两种不同的消息,如下所述:
行政通知,不包含任何财务信息
程序发送的消息以获取价格变动和订单
明文内容是一个键值对列表,类似于字典或映射。预定义的标签作为键;每个标签都是一个对应特定特征的数字。值可以是数值或文本值,与这些标签相关联。考虑以下场景:
我们希望发送一个订单的
$
1.23
$
1.23
$1.23 \$ 1.23 ,让我们想象价格标签上有 44 这个数字。因此,
44
=
1.23
44
=
1.23
44=1.23 44=1.23 将在订单消息中。
字符 1 分隔所有的对。这表示,如果我们使用在我们之前的示例中的 FIX 消息定义中对应于数量的标签 38 添加 100,000 的数量,我们将获得
44
=
1.23
∣
38
=
100000
44
=
1.23
∣
38
=
100000
44=1.23∣38=100000 44=1.23 \mid 38=100000