ChainHopper is a trading service that performs arbitrage across multiple exchanges with no user input. Although the technique works on any tradeable security, cryptocurrency exchanges offer significant price differences and minimal bureaucracy; all real-world use has been focused on moving funds between blockchains at opportune moments.

Because trades are performed automatically, the live front-end is quite minimal; most user-driven operations are performed on historical data to experiment with new strategies. ChainHopper only operates on a single pair of currencies at a time (e.g. Bitcoin and Etherium). The bar at the top contains a summary of current assets in each currency, and their approximate fiat equivalent. The columns below show three sets of data:

Exchange status

Activity dot, exchange logo, bid/ask spread, and current account balances.

The activity dot is green or blue to indicate whether the exchange is actively auto-trading. All dots fade to red to indicate connectivity timeouts. Reaching full red removes the exchange from the set of active trading exchanges.

Bid/ask ratio

A pair of exchanges and the multiplier produced by accepting the lowest ask on the first exchange and the highest bid on the second exchange, less any fees at each exchange.

Actionable trades

Maximum possible profit from a single order pair, taking into account the bid/ask quantities already on the order books, fees, and the balance of funds immediately available. Parenthesis contain the order quantity and bid/ask ratio.

Basic Technique

ChainHopper uses a variety of strategies, but the basic principle behind all of them is arbitrage. Arbitrage is the act of simultaneously buying and selling on difference exchanges to take advantage of price differences. Price differences between exchanges occur naturally as different people trade at each exchange.

A simplified example of a trading day using 1 Canadian Dollar (CAD) and 20 Mexican Pesos (MXN):

Time Exchange A Quote Exchange B Quote Action Total Assets
09:00 1 CAD = 14 MXN 1 CAD = 14 MXN None 1 CAD, 20 MXN
11:00 1 CAD = 16 MXN 1 CAD = 14 MXN Sell 1 CAD on A for 16 MXN
Buy 1 CAD on B for 14 MXN
- 1 CAD, + 16 MXN
+ 1 CAD, - 14 MXN
1 CAD, 22 MXN
13:00 1 CAD = 16 MXN 1 CAD = 16 MXN None 1 CAD, 22 MXN
15:00 1 CAD = 15 MXN 1 CAD = 16 MXN Buy 1 CAD on A for 15 MXN
Sell 1 CAD on B for 16 MXN
+1 CAD, -15 MXN
-1 CAD, +16 MXN
1 CAD 23 MXN
17:00 1 CAD = 15 MXN 1 CAD = 15 MXN None 1 CAD 23 MXN

The trading day started with 1 CAD and 20 MXN, and ended with 1 CAD and 23 MXN. This profit was gained with minimal market risk, as arbitrage doesn’t require hope that a price will move up or down in the future; trade orders are only issued when a price difference is already established on the exchanges and orders are on the books.

Because ChainHopper only accepts existing orders on the exchange, the only trading risk is if one order of the pair is accepted while the other is not. The most common way this occurs is if another user of the exchange accepts the order a fraction of a second before ChainHopper. There also is a small chance connectivity to one exchange fails just as the pair of orders are being accepted, but ChainHopper aggressively disables exchanges that don't consistently respond within a given timeout.

A more advanced system could determine a new price and place new orders on the books. This not only offers more trading opportunities, but also receives lower fees; exchanges often offer very low (sometimes even negative) fees for completed orders that set a new price (i.e. a "market maker", whereas ChainHopper always operates as a "market taker").

Experimental Techniques

Because ChainHopper's trades are entirely controlled by what orders other users place, all strategy is implemented in non-trading activities:

Timezone shifting

Even though exchanges serve customers globally, they are still closely tied to a region through the choice of language, which laws it adheres to, and which fiat currencies it accepts. Exchanges naturally oscillate between higher and lower levels of activity as the people in that region wake up and fall asleep.

Trades within an exchange occur instantaneously, but moving funds between exchanges can take hours or days. Measuring the regional activity patterns lets ChainHopper optimize the distribution of funds in anticipation of these volume swings. In general, it's best to have a balance of active exchanges (where prices move with the market) and inactive exchanges (where prices sit still for a while after the market moves).

Tiered arbitrage

Because small exchanges have such low volume, ChainHopper frequently consumes all profitable bids/asks on the books, effectively bringing the exchanges into sync with each other (selling on the high-priced exchange and buying on the low-priced exchange until the difference in price is equal to the trading fees).

Given an exponentially larger number of exchanges (4 instead of 2 being the simplest), the trades can be carried out in stages. Given high-priced exchanges A and B, and low-priced exchanges Y and Z, the obvious move is to sell on A and B and buy on Y and Z. Instead, if A is slightly higher than B, and Z is slightly lower than Y, more profit can be attained by first selling on A and buying on B, while selling on Y and buying on Z. This effectively brings A and B together in price, and Y and Z together in price. Only after this has happened will trades between A/B and Y/Z start.

In isolation, this doesn't yield substantially higher profits. In practice, the increased activity at the high prices at A and B causes traders to place more orders on the books near that high price on A and B. Similarly, the increased volume at low prices on Y and Z causes traders to place more low-priced orders on Y and Z. This tends to produce a larger volume of orders waiting on the books when the time comes to bring A/B in sync with Y/Z.