Speed, Speed, Speed: the Heart of High Frequency Trading

Photo by toine G on Unsplash

High-frequency trading, also known as HFT, is a method of trading that uses powerful computer programs to transact a large number of orders in fractions of a second. It uses complex algorithms to analyze multiple markets and execute orders based on market conditions. Typically, the traders with the fastest execution speeds are more profitable than traders with slower execution speeds.

This short article is focused on performance tuning of HFT programs and is tailored for an audience of retail programmatic traders. The techniques mentioned below are broadly applicable to any programs that touch C++ in one way or another. We know that in the crypto community there is an established phenomenon that there are plenty of programmatic traders relying on Python-based programs to perform HFT. For example trading bots like gryphon and hummingbot are largely written in Python but do depend on Cython to generate CPython extension modules for performance improvements and therefore ultimately rely on C++ for speed-critical tasks. Regardless of the details of different technologies used by various frameworks, C++ performance tuning is a directly relevant topic for these “Python” users as long as the technology itself relies on C++ as one of its key components. Therefore even if you aren’t a user of us (https://github.com/crypto-chassis/ccapi), the following performance tuning discussions may turn out to be surprisingly useful to you. :)

  1. In production environment when compiling a C++ program we should turn on appropriate compiler optimization flags. For cmake build, this can be as simple as invoking the command line like cmake -DCMAKE_BUILD_TYPE=Release .... In terms of compiler flags this usually translates to `-O3 -DNDEBUG`. For the specific operating system, compiler version, and hardware specification that you use in production, you may also consider experimenting with other flags such as gcc’s -march=native. If you use a Cython-dependent project, it’s important to know that Cython defaults to using -O2 when compiling using setup.py, and therefore you may consider modifying it to use -O3 which may result in a big performance difference.
  2. In production environment when linking a C++ program we should enable link time optimization. With link time optimization, the compiler can apply various forms of optimization to the whole program, allowing for deeper analysis, more optimization, and ultimately better program performance: https://en.wikipedia.org/wiki/Interprocedural_optimization. Notice that usually link time optimization isn’t enabled by default. For cmake build, CMakeLists.txt need a simple line of set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE). Based on our experience this optimization technique does improve the execution speed of the resulting program quite a lot, though at the expense of increased program linking time (but hey it’s only time spent at building stage!). Link time optimization only affects static linking and isn’t applicable to dynamic linking.
  3. In production environment we should look for macro overrides that we can use to tweak the behavior of the program. Whether you are building a new market data pipeline from the ground up or tuning an existing trading bot from an open source project, more often than not there are macro knobs that can be used to better fit the program towards your need. For example, a macro may be used to let you completely discard the parts of a program that isn’t needed by you at all (e.g. you only need code relevant to a single exchange) and therefore significantly shrink the size of the compiled binary. A macro may be used to let you change the size of some internal buffer so that you can tune it based on your machine’s specific CPU and memory conditions. A macro may be used to let you hold a hand on the number of threads to be used in some multi-threaded context. … In one word, macros are really useful things and we should leverage them for performance boosting.

Cool. If your program touches C++ directly or indirectly in one way or another, try the above tips if you haven’t done so yet and we hope that they can give you some good surprises. These things can sometimes be accidentally overlooked although they are critically important with respect to program performances. Simple but really useful! Remember that “Typically, the traders with the fastest execution speeds are more profitable than traders with slower execution speeds.”, thus if you do care a lot about the execution speed of your program perhaps spend some good amount of time and dig deeper in performance tuning: the sweat of your efforts will pay off, and pay off “in high-frequency”. Join us on Discord https://discord.gg/b5EKcp9s8T. 🏎



Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store