Search icon
Arrow left icon
All Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Newsletters
Free Learning
Arrow right icon
Developing High-Frequency Trading Systems

You're reading from  Developing High-Frequency Trading Systems

Product type Book
Published in Jun 2022
Publisher Packt
ISBN-13 9781803242811
Pages 320 pages
Edition 1st Edition
Languages
Authors (3):
Sebastien Donadio Sebastien Donadio
Profile icon Sebastien Donadio
Sourav Ghosh Sourav Ghosh
Profile icon Sourav Ghosh
Romain Rossier Romain Rossier
Profile icon Romain Rossier
View More author details

Table of Contents (16) Chapters

Preface Part 1: Trading Strategies, Trading Systems, and Exchanges
Chapter 1: Fundamentals of a High-Frequency Trading System Chapter 2: The Critical Components of a Trading System Chapter 3: Understanding the Trading Exchange Dynamics Part 2: How to Architect a High-Frequency Trading System
Chapter 4: HFT System Foundations – From Hardware to OS Chapter 5: Networking in Motion Chapter 6: HFT Optimization – Architecture and Operating System Chapter 7: HFT Optimization – Logging, Performance, and Networking Part 3: Implementation of a High-Frequency Trading System
Chapter 8: C++ – The Quest for Microsecond Latency Chapter 9: Java and JVM for Low-Latency Systems Chapter 10: Python – Interpreted but Open to High Performance Chapter 11: High-Frequency FPGA and Crypto Other Books You May Enjoy

Chapter 9: Java and JVM for Low-Latency Systems

When people think about high-frequency trading (HFT), Java does not often come to mind. The Java virtual machine (JVM) warm-up, the fact that it is running on a virtual machine, and the infamous garbage collector have been big deterrents for programmers. However, if you smartly understand those limitations and code, Java can be used in a low-latency environment. You will then be able to benefit from all the advantages that come with Java:

  • A very active and deep offering of free third-party libraries.
  • Write it once, and compile and run it everywhere.
  • Greater stability, avoiding the infamous segmentation fault due to bad memory management.

In this chapter, you will learn how to tune Java for HFT. The performance at runtime is largely based on the performance of the JVM. We will explain in depth how to optimize this critical component.

We will cover the following topics:

  • Garbage collection
  • JVM warm...

Introducing the basics of Java

Java was created by Sun Microsystems in 1991. The first public version was released 5 years later. The main purpose of Java was to be portable and highly performant in internet applications. Unlike C++, Java is platform independent. The JVM ensures any architecture and operating system's portability.

Figure 9.1 shows the compilation chain for Java. We can observe that the Java compiler doesn't produce an executable but a bytecode. JVM will run this bytecode to run the software.

Figure 9.1 – Java compilation chain

We recommend reading the Packt book Java Programming for Beginners, written by Mark Lassof, to learn the characteristics of this language in detail. In this chapter, we will talk about the factors that will affect the performance of HFT. As we described for C++, one critical component is the memory management structure. Unlike C++, where the developer must handle memory manually, Java has a garbage...

Reducing the impact of the GC

When Java was released in 1996, one of the big promises was the end of the dreadful segFault error, so familiar to all C/C++ developers. Java decided to remove all the objects and pointer life cycle out of the hands of the developer and entrust the logic to the JVM. This gave birth to the GC.

There is not a single type of garbage collection. There have been multiple versions developed; all have different specifications to offer either low-latency pauses, predictability, or high throughput.

One of the biggest parts of tuning Java is to find the most appropriate GC for your application as well as the best parameters for it. The main GC algorithms are as follows:

  • Serial GC: Recommended for the small dataset or single-threaded with no pause time requirements.
  • Parallel/throughput collector: Recommended for peak performance and not pause time requirements.
  • Concurrent Mark Sweep collector: Recommended for minimum GC pause time.
  • G1 GC...

Warming up the JVM

Compileable languages, such as C++, are so named because the provided code is entirely binary and can be executed directly on the CPU. Because the interpreter (loaded on the destination machine) compiles each line of code as it runs, Python and Perl are referred to as interpreted languages. In Figure 9.1, we showed that Java is in the middle; it compiles the code into Java bytecode, which can then be turned into binary when necessary.

It's for long-term performance optimization that Java doesn't compile the code upon startup. Java builds frequently called code by watching the program run and analyzing real-time method invocations and class initializations. It might even make some educated guesses based on past experience. As a result, the compiled code is extremely quick. The main caveat for having an optimal execution time is to call the function many times.

Before a method can be optimized and compiled, it must be called a particular number of...

Measuring the performance of a Java software

JMH is a toolkit that assists you in appropriately implementing Java microbenchmarks. Let's now discuss them in detail.

Why are Java microbenchmarks difficult to create?

It's difficult to create benchmarks that accurately assess the performance of a tiny area of a bigger program. When the benchmark runs your component in isolation, the JVM or underlying hardware may apply a variety of optimizations to it. When the component is operating as part of a bigger application, certain optimizations may not be available. As a result, poorly designed microbenchmarks may lead you to assume that your component's performance is better than it actually is.

Writing a good Java microbenchmark often requires avoiding JVM and hardware optimizations that would not have been done in a genuine production system during microbenchmark execution. That's exactly what it is about. Benchmarks that correctly measure the performance of a...

Java threading

Threads are the basic unit of concurrency in Java. Threads provide the advantage of reducing program execution time by allowing your program to either execute multiple tasks in parallel or execute on one portion of the job while another waits for something to happen (typically input/output (I/O)).

HFT architecture heavily uses threads to increase the throughput, as we mentioned in Chapter 7, HFT Optimization – Logging, Performance, and Networking. Multiple threads are created to do tasks in parallel. Adding threads to a program that is completely CPU bound can only slow it down. Adding threads may assist if it's totally or partially I/O bound, but there's a trade-off to consider between the overhead of adding threads and the increased work that will be done. We know that the underlying hardware (CPU and memory resource) will limit this throughput. If we increase the number of threads beyond a certain limit (such as the number of cores or the number...

High-performance task queue

To achieve performance, any trading system must have processes and threads working in parallel. Processing many operations at the same time is a way to save time. The communication between processes is very challenging in terms of speed and complexity. As we saw in Chapter 6, HFT Optimization - Architecture and Operating System, it is easy to create a segment of shared memory and share data between them. As we know, there is a problem with the synchronization of the access to the data because shared memory doesn't have any synchronization mechanism. The temptation of using a lock is high but performance will be affected by this kind of object.

In this section, we are going to review the different Java data structures that we use in HFT. The first one is the simplest: the queue.

Queues

Queues generally have a write contention on the head and tail and have variable sizes. They are either full or empty but never operate on the middle ground where...

Logging and DB access

As we explained in Chapter 7, HFT Optimization – Logging, Performance, and Networking, logging is critical for any trading system. It enables users to debug strategies, improve the return, compare theoretical and actual profit and loss, and store information in databases. It always requires a costly input/output. Therefore, logging cannot be done on the critical path. Like C++, a specific technique is needed to achieve performance in Java.

When creating a log, it can store trades in a database or build a string in a flat file. When generating a string to be pushed in the logging system, creating a string is a very time-consuming construction. It is essential to consider the speed of the system and the object's reaction. For instance, log4j zeroGC is a zero object creation logging framework, but it will generate the log message before putting it on the logger thread queue (in this case, the disruptor from LMAX). Your main application thread will...

Summary

This chapter showed that JVM eases software developers' lives but impedes a trading system's performance. We demonstrated that by understanding how the JVM behaves under the hood, following good coding practice, and tuning the JVM, we could use Java as a serious programming language candidate for HFT. We studied in detail how to measure performance with Java. We know that measuring the execution time is the only evidence that code performs better after optimization. As we did with C++, we introduced high-performance data structures helping to get a performant code. We combined these data structures with the use of threads and thread pools. We concluded by discussing logging and database access, which are vital in HFT.

C++ and Java are the most used languages in HFT. The next chapter will talk about another programming language: Python. We will see how Python can be used in HFT and run fast using external libraries.

lock icon The rest of the chapter is locked
You have been reading a chapter from
Developing High-Frequency Trading Systems
Published in: Jun 2022 Publisher: Packt ISBN-13: 9781803242811
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $15.99/month. Cancel anytime}