高频交易

高频交易是指从那些人们无法利用的极为短暂的市场变化中寻求获利的计算机化交易,比如,某种证券买入价和卖出价差价的微小变化,或者某只股票在不同交易所之间的微小价差。在高频交易中,自动化应用程序每天处理几亿个市场信号,在全球各地的交易所发送上千万个订单。为了保持业务竞争力,响应时间必须始终保持在微秒级,尤其是在黑天鹅异常事件等高峰期。

高频交易系统的典型系统结构一般是这样:金融交易信号将转换成内部市场数据格式(交易使用TCP、UDP等各种协议)和多种格式(如二进制、SBE、JSON、FIX等)。然后,这些标准化的消息被发送到算法服务器、统计引擎、UI、Log Server和各种数据库(缓存、文件或分布式数据库)。任何延迟都会带来都会带来高成本的结果。例如,根据根据旧的价格进行决策或下单太迟。为了获得微秒级的优势,大部分交易参与者都会投入高价硬件:一个超频液冷CPU的服务器池(2020年可以买56核、5.6GHz、1TB内存的服务器),组装在主交换数据中心、高端纳秒级网络交换机、专用跨洋线,甚至是微波网络。

常见的高频交易系统使用高度定制的Linux内核,并且带有操作系统旁路,这样数据就可以直接从网卡 "跳转" 到应用程序、基于IPC 进程间通信,甚至使用FPGA(可编程单用途芯片)。至于编程语言,一般首先想到的就是C++,事实上也确实是这个领域的天然选择。C++的最大优势就是运行速度快,最接近机器代码,而且是直接根据目标平台进行编译,具有高效稳定的特点。

使用Java代替C++

我们做了一个不同的选择。在过去14年里,我们在外汇算法交易领域用Java进行开发,并使用廉价的硬件代替昂贵的高端设备。

在一个团队小,资源有限以及熟练开发人员欠缺的工作环境,Java意味着我们可以快速进行软件迭代,因为Java生态系统比C系列具有更快的开发效率。可以在早上讨论改进措施,并在下午在生产中实施、测试和发布。

与需要几周甚至几个月软件更新时间的大型公司相比,这是一个关键优势。在这个领域,一个错误可以在几秒钟内抹去一整年的利润,因此不能在质量上妥协。我们使用了许多开源库和项目,实现了严格的敏捷开发环境,包括使用Jenkins、Maven、单元测试、夜间构建和Jira。通过Java,开发人员可以专注于业务逻辑,而不是像C++那样调试内存Coredump或跟指针打交道。而且,由于Java强大的内存管理,初级程序员也可以立即参与开发代码,并且风险可控。

只要有良好的设计模式和干净的编码习惯,就可以用Java达到C++的延迟。我们都知道,使Java成为软件开发强大和方便语言的原因,同时也是它的缺点的最主要的原因,那就是Java虚拟机(JVM)。

Java即时编译代码(Just in Time 编译器),意味着第一次遇到一些代码时,也可能产生编译延迟。Java管理内存的方式是通过在堆空间中分配内存块。每隔一段时间,它就会清理这个空间,删除旧的对象,为新的对象腾出空间。主要问题是,为了进行准确的统计,应用程序线程需要被瞬间 "冻结"。这个过程被称为垃圾收集(GC)。GC是低延迟应用程序开发人员放弃 Java 的主要原因。

市场上Java 虚拟机最常见和标准的是 Oracle Hotspot JVM,它在 Java 社区中被广泛使用,主要是出于历史原因。对于要求非常高的应用程序,Azul Systems 提供了一个很棒的替代方案,称为 Zing。Zing是Oracle Hotspot JVM一个强大的替代品。Zing解决了GC暂停和JIT编译问题。

让我们来研究使用Java的固有问题和可能的解决方案。

理解Java即时编译器

像C++这样的语言被称为编译语言,因为交付的代码完全是二进制的,可以直接在CPU上执行。PHP或Perl 被称为解释语言,因为解释器(安装在目标机器上)会边运行边编译每一行代码。

Java介于两者之间;它将代码编译成所谓的 Java 字节码,而字节码又可以在它认为合适的时候被编译成二进制。Java之所以不在启动时编译代码,与长期的性能优化有关。通过观察应用程序的运行情况,分析实时的方法调用和类的初始化,Java 会编译经常调用的部分代码。它甚至可能会根据经验做出一些假设(这部分代码永远不会被调用,或者这个对象永远是一个 String)。

因此,实际编译后的代码速度非常快,但依然有3个缺点。

1、一个方法需要被调用一定的次数来达到编译阈值,然后才能被优化和编译(这个限制是可以配置,但通常是10000 次左右的调用)。在此之前,未经优化的代码并没有以 "全速" 运行。Java在更快的编译和高质量的编译之间做了一个取舍(如果假设不对,会有重新编译的代价)。

2、当Java应用程序重启时,又回到了原点,必须等待再次达到这个阈值。

3、有些应用程序(比如我们的场景)有一些不频繁但很关键的方法,这些方法只会被调用少数几次,但当它们被调用时,需要极快的速度(想想看,一个风险或止损函数只有在紧急情况下才会被调用)。

Azul Zing通过让其JVM将编译后的方法和类的状态 "保存" 在它所谓的配置文件中来解决这些问题。这种名为 ReadyNow! 的独特功能,意味着Java应用程序始终以最佳速度运行,即使在重新启动后也是如此。当使用现有的配置文件重新启动应用程序时,Azul JVM会立即调用其先前的结果并直接编译标注的的方法,从而解决了 Java 预热问题。

此外,可以在开发环境中建立一个配置文件,以模拟生产行为。然后,优化后的配置文件可以部署在生产环境中,因为所有的关键路径都被编译和优化了。Zing的延迟随着时间的推移保持相当稳定。百分位数分布表明,1%的时间里,Hotspot JVM产生的延迟是 Zing JVM的16倍。

解决垃圾收集(GC)暂停的问题

在垃圾收集过程中,整个应用程序可能会冻结几毫秒到几秒不等(延迟随着代码复杂度和堆大小而增加),更糟糕的是,你无法控制这种情况何时发生。虽然暂停一个应用程序几毫秒甚至几秒钟对于许多Java应用程序来说可能是可以接受的,但对于低延迟应用程序来说却是一场灾难,无论是汽车、航空航天、医疗还是金融领域。

GC的影响在Java开发者中是一个很大的话题;一个完整的垃圾收集通常被称为 "stop-the-world",因为它会冻结整个应用程序。

多年来,许多GC算法都试图在吞吐量(多少CPU用于实际的应用逻辑而不是垃圾收集)与 GC暂停之间做一个取舍。

自Java 9以来,G1 收集器一直是默认 GC,其主要思想是根据用户提供的时间目标来划分GC暂停时间。它通常提供较短的暂停时间,但代价是较低的吞吐量。此外,暂停时间会随着堆的大小而增加。Java提供了大量的设置来调整其垃圾收集(以及 JVM),从堆大小到收集算法,以及分配给GC的线程数。所以,看到Java应用程序配置了大量的自定义选项是很常见的。

很多开发者已经转向各种技术来完全避免GC。主要思路是,如果创建的对象少了,需要清除的对象就会变少。一个古老的技术是使用可重用对象的对象池。例如,一个数据库连接池将持有10个已打开的连接的引用,准备在需要时使用。

多线程通常需要锁,这会导致同步延迟和暂停(特别是当它们共享资源时)。一个流行的设计是一个环形缓冲队列系统,在一个无锁的设置中,有许多线程写和读。一些专家甚至选择完全自己实现 Java 内存管理,自己管理内存分配,虽然解决了一个问题,但却带来了更多的复杂性和风险。在这种情况下,显然应该考虑其他 JVM,于是我们决定尝试 Azul Zing JVM。很快,我们就实现了非常高的吞吐量,停顿可以忽略不计。

这是因为Zing使用了一个独特的收集器,叫做C4(Continuurrentously Concurrent Compacting Collector),它允许无暂停地收集垃圾,而不关心Java堆的大小(最高可达8TB)。这是通过在应用程序仍在运行时,并发映射和压缩内存来实现。此外,它不需要修改任何代码,延迟和速度的提升都是开箱即见,无需冗长的配置。在这种情况下,Java程序员可以享受到两全其美的好处,既可以享受到 Java 的简单性(无需偏执于创建新对象),又可以享受到Zing的底层性能,使整个系统的延迟高度可预测。

多亏了GC easy,一个通用的GC日志分析器,我们可以在真实的自动交易应用中(在模拟环境中)快速比较两种JVM。在高频交易的应用中,使用Zing的GC比使用标准的 Oracle Hotspot JVM 小 180 倍左右。更令人印象深刻的是,GC暂停通常与实际应用暂停时间相对应,而Zing智能GC通常是在最小或没有实际暂停的情况下平行发生的。

总结

Java在享受简单性和面向业务的特性同时,仍然可以实现高性能和低延迟。虽然C++ 仍然可用于特定的底层组件,如驱动程序、数据库、编译器和操作系统,但大多数现实中都可以用Java来开发,包括象高频交易这样要求苛刻的应用。

java jdk 下载 来自 嗖嗖下载

Java才是世界上最好的语言,Java在高频交易中替代C++的更多相关文章

  1. 如何看待Java是世界上最好的语言?

    Java出现二十多年以来,一直都是主流的开发语言,Java创建于 1995 年,在 20多年的发展历程中,Java 已经证明自己是用于自定义软件开发的顶级通用编程语言. Java 广泛应用于科学教育. ...

  2. 我用爬虫一天时间“偷了”知乎一百万用户,只为证明PHP是世界上最好的语言

    我用爬虫一天时间“偷了”知乎一百万用户,只为证明PHP是世界上最好的语言 2015-08-06 猿圈 我用爬虫一天时间“偷了”知乎一百万用户 只为证明PHP是世界上最好的语言 看了不少朋友圈里推荐的P ...

  3. 用Visual Studio Code Debug世界上最好的语言(Mac篇)

    用Visual Studio Code Debug世界上最好的语言(Mac篇) 首先,你要有台Macbook Pro,接着才继续看这个教程. PS:Windows用户看这里用Visual Studio ...

  4. 用Visual Studio Code Debug世界上最好的语言

    前言 这阵子因缘巧合接手了一个辣鸡项目,是用世界上最好的拍黄片写的,项目基本是另一个小伙伴在撸码,我就兼职打杂和发布做点运维的工作. 然后昨天项目上了测试版之后,一用起来Error满天飞了.让小伙伴查 ...

  5. 世界上最好的语言搭建短链接及统计功能(附API代码)

    前言 在这个营销的时代,短链接和二维码是企业进行营销中非常重要的工具,不仅仅是缩短了链接,而且还可以通过扩展获得更多的数据,诸如点击数.下载量.来源以及时间等等. 网上搜寻了一下比较有名有U.NU和0 ...

  6. php果然是世界上最好的语言

    这两天参加Hackathon,作为一个什么都半吊子的家伙,两人小队伍被逼上岗,于是我不得不着手写代码.由此,我体验到了php的魔力-- 首先,我深刻地意识到了更新版本的重要性. 偷懒不想搭Apache ...

  7. java模拟表单上传文件,java通过模拟post方式提交表单实现图片上传功能实例

    java模拟表单上传文件,java通过模拟post方式提交表单实现图片上传功能实例HttpClient 测试类,提供get post方法实例 package com.zdz.httpclient; i ...

  8. JavaScript 是世界上最好的语言?

    2016年1月中旬,Stack Overflow发起本年度的开发者调查,调查结果于近日公布.本文盘点 JS 开发者应该会关心的部分数据. Stack Overflow 技术排行榜: 在2015年6月, ...

  9. SQL才是世界上最牛逼的语言!

    身处互联网行业,SQL 可能是你需要掌握的核心技能之一. 最早的时候,SQL 作为一门查询数据库的语言,是程序员的必备技能,运维.开发.Web 以及数据等从业人员都需要用到 SQL,毕竟只有查询到正确 ...

随机推荐

  1. spark-4-文件读写

    hdfs文件读写报错: AccessControlException: Permission denied: user=root, access=WRITE, inode="/user/ch ...

  2. Ubuntu通过Nginx安装Webdav

    使用KeePass保存密码,在个人服务器上安装WebDav协议. # nginx nginx-extras apache2-utils sudo aptitude install nginx ngin ...

  3. 字节码暴力破解censum(老版本)

    声明 事先声明,本文仅提供破解方法以供个人及读者们学习Java字节码,不提倡破解程序. 本文是个人学习掘金小册张师傅的<JVM字节码从入门到精通>后,作为一个实践的记录,并无恶意. 关于c ...

  4. HttpReports 2.0 发布了 !!!

    前言介绍 HttpReports 是基于.Net Core 开发的APM监控系统,使用MIT开源协议,主要功能包括,统计, 分析, 可视化, 监控,追踪等,适合在微服务环境中使用. Github地址: ...

  5. Redis 中 HyperLogLog 的使用场景

    什么是基数估算 HyperLogLog 是一种基数估算算法.所谓基数估算,就是估算在一批数据中,不重复元素的个数有多少. 从数学上来说,基数估计这个问题的详细描述是:对于一个数据流 {x1,x2,.. ...

  6. MeteoInfoLab脚本示例:TOMS HDF数据

    TOMS (Total Ozone Mapping Spectrometer)数据是全球臭氧观测.脚本程序: #Add data file folder = 'D:/Temp/hdf/' fns = ...

  7. 发布MeteoInfo 1.2.3

    提升了对GeoTiff格式数据的读取能力(多个tiles).当然还有MeteoInfoLab功能的提升.下载地址:http://yun.baidu.com/share/link?shareid=669 ...

  8. day26 Pyhton 复习re模块和序列化模块

    # re # 正则表达式 # 元字符 # 量词 # 贪婪匹配与惰性匹配 # 元字符量词 # 元字符量词? 在量词规范内,遇到一个x就停下来 # .*?x (.如果是第一个元素,那么它一定会从第一个元素 ...

  9. .NetCore 异步编程 - async/await

    前言: 这段时间开始用.netcore做公司项目,发现前辈搭的框架通篇运用了异步编程方式,也就是async/await方式,作为一个刚接触的小白,自然不太明白其中原理,最重要的是,这个玩意如果不明白基 ...

  10. python 爬取链家

    import json import requests from lxml import etree from time import sleep url = "https://sz.lia ...