Most automatic cryptocurrency trading algorithms, especially high-frequency ones like triangular arbitrage and cross-market arbitrage, are sensitive to network latency because they are used by many people simultaneously, and lowering the latency can give you significant competitive advantage. This article gives you a list of tactics.

Use a computer near the exchange

You cannot make your trading bot's latency lower than the network latency. Therefore, it is best to put your trading bot near the exchange's server, i.e. the so-called colocation hosting.

For exchanges that are only using one API server, you can use the ping command to check the round-trip-time (RTT), but this may not work if the exchange is using Cloudflare. The most reliable way is to simply test the response time of an API request to see how fast the connection is like the following.

import requests
import time
start = time.time()
total_times = 10
for i in range(total_times):
end = time.time()
print (end-start) / total_times

Some exchanges use multiple API servers at different places all over the world, then the connection between your bot and the API server is one part of the latency, and the other latency source can come from the connection between the exchange's API server and their core server that handles order matching. For this case, testing the RTT between your bot and the API server will not be enough, and you need to test the actual order execution time to determine the optimal place to put your bot.

Use WebSocket instead of REST APIs.

Many exchanges provide both. WebSocket has much less latency because it shares the same TCP connection across different requests while using REST APIs on HTTP/1.0 requires establishing a TCP connection for every request.

Another reason of using WebSocket is that the server can proactively push data to the trading bot, which makes it very efficient for streaming updates like order book updates, balance changes, or recent trades from the exchange to the bot. Using HTTP will require the trading bot to make a request every time when it wants to get an update from the server.

Use HTTP/1.1

If you have to use REST instead of WebSocket, use HTTP/1.1. It makes the same TCP connection used across different requests.

If you are using Python, switching to HTTP/1.1 can be easily achieved by using the requests package shown in the following two examples.

The first one is using HTTP/1.0, where each request builds a new TCP connection.

import requests
for i in range(10):
    r = requests.get('').json()
    print r

The second one is using HTTP/1.1, and the same TCP connection is shared between multiple requests.

import requests

s = requests.Session()
for i in range(10):
    r = s.get('').json()
    print r

As you can see from the following results, the second one runs much faster.

Latency comparison between HTTP/1.0 and HTTP/1.1

Use a faster programming language

Python or nodejs is convenient for writing trading algorithms. However, they are scripting languages and thus much slower than compiled languages like Golang, Java, or C/C++ for computation-intensive tasks. If you are using a sophisticated pricing model (e.g. Monte Carlo simulation) that requires heavy numerical computing, you can either rely on libraries written in C/C++ for your scripting language like numpy for python, or write the computation-intensive part using C/C++ as a library and then plug in your python/nodejs code, or switching completely from python/nodejs to a compiled language.

Another disadvantage of using python/nodejs is that it is inconvenient to take advantage of multiple-core CPUs as the interpreter of the two languages are only single-threaded. If multi-threading is required for your task, avoid using scripting languages at the beginning.