Recently, I start looking for more opportunities to make money with cryptocurrencies beyond trading.
I'm a professional programmer, so I started, as I usually do, by thinking how I can automate something for a profit. Most exchanges offer at least a half-decent API, so I began thinking of ideas.
Given how new they are, I assumed cryptocurrency markets would be inefficient and I knew that one way to take advantage of market inefficiencies was arbitrage.
Arbitrage opportunities occur when the price of an asset (a coin or token in our case) is trading at a different price on different exchanges.
Not a member yet?
As an example, if Bitcoin is trading at $15,000 on GDAX and $15,050 on Gemini, you could simultaneously buy on GDAX and sell on Gemini, resulting in a $50 profit.
You could then transfer your funds between the exchanges and repeat the process.
Since I don't have a verified account on GDAX (that's a separate story), and I'm not eligible for a Gemini account, I continued looking around.
I found Blackbird which advertises itself as an open-source "C++ trading system that does automatic long/short arbitrage between Bitcoin exchanges".
Blackbird says it looks for a price difference, then buys (long) on one exchange and short sells on another. It then waits for the price gap to close and exits these positions.
That's nice, but I started feeling suspicious at this point. Not because I thought the developer had written some bot that was going to steal all my coins, but because, personally, I wouldn't have made this code public if it worked.
Logically, this bot is supposed to exploit market inefficiencies, which removes those inefficiencies as a result. The more people running the bot, the less profit there would be.
So I decided not to run Blackbird and do some further investigation.
I didn't want to deal with multiple exchanges or short selling, so I did a bit of reading about a particular kind of arbitrage I'd read about before called triangular arbitrage.
Triangular arbitrage is when you start with one currency, use it to buy a second, trade the second for a third, and lastly, trade the third back to the first. As a more concrete example, you could start with BTC, use it to buy ETH, use that ETH to buy LTC, then sell the LTC for BTC.
If there is a significant market inefficiency, this will result in profit.
I use Bittrex often, so I started exploring their API. Their documentation is pathetic, but the API is functional. It has an endpoint which provides details of all of Bittrex's markets (271 at the time of writing) including the Bid and Ask prices.
Triangular arbitrage crypto bot
These details were all I needed, so I wrote some C# code in LINQPad, my goto IDE for this sort of trial and error work.
The code parsed the data into a graph. I'm talking about the kind of graph you could imagine as a bunch of circles (nodes) linked together by lines. The graph consists of a node for each currency, with links between the nodes representing Bittrex markets which could be used to get from one currency to the other, and the current prices of that market.
Bittrex has three base currencies; BTC, ETH, and USDT.
I wrote a final piece of code which starts at each of these nodes in the graph and finds a triangular path back to where it started.
For example, beginning at the BTC node, we could move to the XRP node, then to the USDT node, then back to the BTC node. The code takes Bittrex's 0.25% trade fee into consideration and outputs all of the triangular arbitrage opportunities which would make a profit.
The result at this point? There are many times when the market is inefficient to theoretically make a profit. Below is some sample of the output from right now:
We can see that at 22:47:18, trading BTC for ANT, ANT for ETH, then ETH for BTC would have yielded a 0.56% net profit after subtracting trading fees.
The output was quite noisy, and I'm not interested in a 0.01% profit, so I chose to filter out anything below 1%, which reduced it down to about one opportunity every minute or two, give or take.
The average profit I'm seeing is approximately 1.5%, and the highest I've seen has been 14.55%, which was available for 3.044 seconds.
In this post, I've only written about the very first iteration of the program. Over the past week, I've improved it quite a bit which resulted in a strategy change to what I'm calling linear arbitrage.
Are you interested in hearing more about this project?
Let me know!