What is High Frequency Trading and building High Performance Trading systems in C++ with low latency
What is Algo Trading or HFT ?
It is any software that follows a predefined algorithm to place trading instructions. Algo Trading is something that is not done manually or without manual intervention. It is characterized by a high trading rate and a short investment horizon that is if human traders buy, sell and hold for days, months or years an HFT Algo does these on the same day, in hours, minutes, seconds or microseconds.
HFT Algorithms don't try to make long-term predictions of the market they are more about reacting to market events and making very short-term predictions and reacting quickly.
HFT Algo's profitability is dependent on its ability to perform trading actions at critical points in time in an extremely latency-sensitive manner.
Main Development approaches
We have to avoid context switching, queuing and data transfer between threads as much as possible because these are slow operations and can cause losses.
Deterministic, static code flow which makes as many decisions as possible in compilation time.
Minimize cache misses and wrong branch predictions.
Use custom-tailored data structures for specific uses.
Branching Minimizations
Every decision that is taken on runtime has a performance penalty or causes CPU cycles. This is worsened by the fact in case of branch mispredictions which means wasted CPU cycles.
So we aim to minimize branching to get more static and more predictive flow so that we can go in the right direction and do not waste CPU cycles as it reduces the efficiency of the algorithm and results in losses.
Warming up the Cache
Cache misses are very expensive and are one of the highest overheads for a low-latency code as getting something into the cache costs a lot of time as we have to complete our real-time flow in a few microseconds.
In a multithreaded environment, there is a constant fight for a place in the cache and it gets much worse because most critical flows are sometimes extremely rare.
To avoid Cache misses we can generate a dummy order and then we can execute it also obviously, it is not an actual trade but it is sent through the same pipeline as the actual trade. So in this way, the entire flow remains in the cache and during the actual trade, there will be no conflict misses and saves time.
The logic of generating a dummy order and running it takes CPU cycles so technically we are delaying our real-time flow for some dummy action so it is not a good idea to do it every time.
Template Metaprogramming in C++ for Low Latency
When we can write programs that can do the computation in compile time instead of run time then those programs are called template metaprograms and we can achieve this by using templates.
Templates in C++ is a feature where we write code once and then use it for any data type including user-defined data types.
It allows you to define the generic classes and generic functions and thus provides support for generic programming. Generic programming is a technique where generic types are used as parameters in algorithms so that they can work for a variety of data types.
Templates can be represented in two ways
1) Function Templates
2) Class Templates
Function Templates
We can define a template for a function. For example, if we have an add() function, we can create versions of the add function for adding the int, float or double type values.
Function templates allow the programmer to write a generic function that is independent of data type.
Using function templates we can reduce the size of the code and makes the maintenance code easy.
A Generic function is created by using the keyword template. The template defines what the function will do.
Generic functions use the concept of a function template. Generic functions define a set of operations that can be applied to various types of data.
The type of data that the function will operate on depends on the type of data passed as a parameter.
template < class Ttype> ret_type func_name(parameter_list)
{
// body of function.
}
Class Templates
Class Template can also be defined similarly to the Function Template. When a class uses the concept of a Template, then the class is known as a generic class.
template<class Ttype>
class class_name
{
.
.
}
Type is a placeholder name that will be determined when the class is instantiated. We can define more than one generic data type using a comma-separated list.
Example -
#include <iostream>
using namespace std;
template<class T>
class A
{
public:
T num1 = 5;
T num2 = 6;
void add()
{
std::cout << "Addition of num1 and num2 : " << num1+num2<<std::endl;
}
- };
int main()
{
A<int\> d;
d.add();
return 0;
}
The ability of C++ to perform compile-time computations to create a more generic and optimized code is known as Template Metaprogramming (TMP).
TMP can be thought of as an embedded language that sits on a layer above the standard C++, is interpreted by a C++ compiler’s template system, and outputs the standard C++ code that is compiled normally. It allows the performance of general-purpose computations with types, templates, functions, constant variables, and literals as objects.
TMP helps in developing low latency and ultra low latency systems whose end to end latency is just a few microseconds or nanoseconds.
Subscribe to my newsletter
Read articles from Ashish Bajpayee directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by