A bot that traded cryptocurrencies using an arbitrage strategy in order to make a profit.
I've been interested in crypto since my friend introduced me to Ethereum in 2016. Near the end of 2017, the price of most cryptocurrencies began to skyrocket in what later became known as the "Oh My God, We're All Going To Be Crypto Millionaires!" bull run of 2018. It was a topic of frequent discussion between myself and a couple of colleagues who were also interested in cryptocurrencies. One day, someone threw out the idea of building a trading bot. We looked at each other and shrugged. Why not?
Luckily, one of my colleagues had experience in fintech and knew a thing or two about algo-trading. After some discussion, we settled on using arbitrage as our strategy.
Investopedia defines arbitrage
as the simultaneous purchase and sale of an asset to profit from an imbalance in the price.
Let's take an example. Imagine the price of a gallon of milk is $2 in Boston but just $1.50 across the river in Cambridge (I don't drink milk, so if that's way off, take it up with the cows). I could buy 40 gallons of milk with $60 in Cambridge, transport my milk to Boston and sell the 40 gallons for $80, netting a nice $20 for myself. In real life, you'd have to factor in the cost of transporting and keeping the milk chilled, but you get the idea.
If you kept doing this, the price of milk would gradually converge in both cities. This is because we'd be moving supply from Cambridge to Boston. Less supply in Cambridge would drive prices up, and more supply in Boston would drive prices down. In this way, arbitrage is a positive force in markets since it eliminates arbitrary price differences for consumers.
It's the same idea with cryptocurrencies. There are many different exchanges where people can buy or sell cryptocurrencies, such as Kraken or Gdax. The price of a particular cryptocurrency at one of these exchanges is determined solely by what people are willing to pay for it. Since the people at Gdax are not the same as the people at Kraken, there will be differences in the price from time to time. If you can buy a coin cheaply at one exchange and sell it for more at another exchange, you turn a profit.
The situation becomes a little more complicated in practice. The price of these coins fluctuates at intervals of a fraction of a second, and actionable price differences rarely last longer than a single trading interval. This is because many other bots are taking advantage of arbitrage opportunities. This means there is not enough time to buy at one exchange, move it to the other exchange, and sell it there. To overcome this, our strategy was to have crypto deposits at each exchange. If we saw an actionable price difference, we'd immediately buy and sell at both exchanges.
Using the milk example, let's assume the price of milk is usually the same in Cambridge and Boston but occasionally diverges. We keep 100 gallons of milk in each location. Let's assume that the price goes up in Cambridge by 10 cents. We would sell 10 gallons of milk in Cambridge at the higher price, and buy 10 gallons of milk in Boston at the lower price. Overall we still have 200 gallons of milk combined. But we've now gained 10 gallons * 10 cents = $1 of profit.
We built the application using Ruby. Here is a rough overview of how the code worked.
- Retrieve buy and sell orders from both exchanges.
- Sort buy orders from most expensive to least expensive, and vice versa for sell orders.
- Compare buy orders from one exchange with sell orders from the other exchange. If the trade would yield a positive revenue delta after factoring in fees, add it to a queue of possible trades. Do this for both sets of buy/sell order lists.
- Fill all possible trades for which we have enough units of the particular coin at each exchange.
Since there was going to be real money on the line, we wanted confidence that our solution would work as expected. To facilitate this, we added a test mode, where the application would use fake money and make fake trades. We even simulated trade failures at different probability levels to account for things like failed network requests or trying to make a trade that was no longer available.
The bot ran for a month in total. In that time, it executed over one hundred trades, of which 75% were successful. However, the remaining 25% of trades failed due to network failures or the trade no longer being available. The 25% of failures proved too costly and almost completely zeroed out any gains we made from our successful trades. We decided that our profit margins were too thin to compensate for the risk, and we turned off the bot.
But hey, now I can say I built a cryptocurrency trading bot that made me money. Pretty cool!