I’ve recently started trading bitcoins algorithmically on the new Coinbase exchange. After reading about high-frequency trading in the book Flash Boys by Michael Lewis, I decided I’d give it a shot myself, albeit in a clumsier, more amateurish way.
The experience has been fascinating, both on a technical level, and in a strategic sense. Writing logic that controls money itself is a strange thing. Setting it loose for the first time, knowing that any bug could literally throw away cash, was terrifying.
Bitcoin is an incredibly open system that is particularly friendly to no-name developers. The exchanges have open API’s that allow anyone, literally anyone, to trade. There’s no premium access, no expensive trading floor credentials. It’s totally open – I love that.
Shark infested waters
As I’ve designed my trading bot, I’ve come to realize how much strategic depth there is to these sorts of games. The exchanges are already rife with trading bots; these are shark infested waters. Bots dance around each other in a chaotic swirl. They employ so many diverse strategies. It’s like so many microbes competing in the primordial ooze.
Entering into this environment, I had to be immediately cognizant of other bots.
Algorithmic traders need to occupy a particular niche. They profit from market inefficiencies. In a perfect market, what they do would not be profitable.
It is precisely because markets, in their native state, are not ideally smooth, continuous, and well functioning, that algorithmic traders may extract any value. In rectifying the little mistakes, the little instances of slippage that occur in markets, one may eke out small profits.
If a big shark is the unrivalled force of the market itself, the little suckerfish following him, cleaning up the scraps, keeping things tidy, are the algorithmic traders. They too have their place.
Another paradox is that I cannot reveal my trading strategy without also compromising it.
To a small extent, explaining my strategy would be an invitation to competitors, for whom the marginal cost of setting up the software is very low. Much more threateningly, however, if my bot’s exact strategy were known, it could be depredated.
If you could always predict its every step, you could trick it into giving up money again and again. This is something else that keeps my paranoia alive, the fear that someone out there will observe my bot, and in the to and fro of its orders, figure out its strategy.
I imagine myself coming back to my bot, seeing its balance empty, because some mastermind gamed it algorithmically, draining pennies with each cycle.
Market making 101
On the other hand, my bot’s strategy is exceedingly conservative, and would be difficult to game. It is basically a sophisticated market maker. It provides liquidity to the Coinbase exchange. This means that it looks at the order book and observes where the orders are thin. Perhaps there is very little order depth on the buy side.
It can place limit orders, like little traps, at varying depths on the buy and sell sides. It varies the exact way it does this based on recent market conditions. If a large trade is then suddenly executed, it may overwhelm the availability of offers at the best price. Such a large offer may then trigger one of my offers, lying in wait, at a more advantageous price.
This is market-making 101. It’s pretty much the least opinionated strategy out there, although I have tempered my own implementation with some additional price-prediction logic. On the whole it’s an exceedingly boring strategy.
Market-making also delivers real social utility. The deeper the liquidity provided by market makers, the more difficult it is to cause erratic spikes in price. Market makers also reduce the bid-ask spread, a concept most people aren’t even aware of: a testament to successful practitioners on Wall Street.
Other bot strategies
Other bots employ widely varying strategies. Some rectify the spread between separate exchanges, a strategy completely dependent on speed. If someone drops 1,000 BTC on Bitfinex, the price on Coinbase plunges in synchrony because someone raced to execute a market order.
Other strategies revolve around tricking other bots, for which there are endless tactics. They often involve elaborate posturing, fooling others’ logics into fatal missteps. Still others are designed to intimidate human beings with massive buy or sell orders. I’m sure still others abound of which I have no idea.
On a practical level, my bot must be very quick. If it is delayed even by a few seconds between cancelling and placing orders, market conditions can cause the new orders to become inappropriate.
The orders I place follow a sound logic assuming that the bot has a correct understanding of the state of the order book. This assumption does not hold for long. Within a second, a flurry of significant orders could have skewed the actual order book, such that the new orders I’ve devised are now plain wrong.
I must also be on the lookout for hostile bots, who may place and quickly remove large orderswith the intention of tricking other bots. The faster my bot can maintain awareness of the order book, the less susceptible it will be to such tactics. My bot even has additional logic to prevent it from being tricked by fake volume walls from other bots.
Human speed vs bot speed
In the pursuit of speed, I’ve had to think about technical details I was not very familiar with. I’ve had to parallelize a lot of mundane, boring functions. I can’t cancel obsolete orders in serial, it would take too long for my JSON requests to go back and forth across the Internet.
Because Coinbase does not offer a single API endpoint to cancel all orders simultaneously,something I’ve been asking for, I cancel them with many separate requests in parallel. Similarly, Coinbase lacks an endpoint for creating multiple orders at once. So I must issue multiple requests simultaneously. A synchronous solution would take several seconds, which is far too long.
It’s funny how a human sense of time is wholly inappropriate to that of bots. Even a fraction of a second can be hopelessly long. Trying half as hard, or moving half as fast, don’t guarantee half the profits; they yield zero (or worse). Delving into algorithmic trading, one must inhabit the lifecycle of a bot, stretching one’s own concept of time to milliseconds. It is on this scale that I still see my bot as dumb and slow.
At least the bot’s awareness of the order book is very fast. It streams a websocket feed of new orders. Each item is a permutation of the order book, so I must maintain the book’s state and make little changes as they arrive.
This process is also parallelized. It’s actually amazing how fast this is, there are about 20 order permutations per second.
So my bot mainly provides liquidity. It earns a small but steady amount from this. It holds roughly equal amounts of bitcoins and dollars, so abrupt price changes can leave it with losses in a given denomination. But on the whole it is making decent profits compared to a 50/50 basket of bitcoins/USD.
“Delving into algorithmic trading, one must inhabit the lifecycle of a bot, stretching one’s own concept of time to milliseconds.”
My bot performs best when volume is high, but price swings are low. As a provider of liquidity, it smoothes the erratic undulations that would otherwise occur without market makers. In this it is providing a useful function, thus high volume periods are the most lucrative. In some cases, sharp swings, back and forth, can cause my bot to persist in holding the wrong asset. Thus it is possible to lose money.
I’ve found that low-volume regimes are the most dangerous. My bot seeks to estimate the trading rate and moderate the depth of its orders accordingly. This limits the risk of being caught in large swings, at the cost of having its orders executed less often.
I’ve also found that there is a significant amount of noise around my balance. As the price oscillates, my bot periodically loses money. It may be losing money 45% of the time. But if it is gaining in the other 55%, it will win massively over the long run.
Given these odds, measuring the bot on a frequent basis would lead one to observe more instances of loss versus infrequent observations.
It’s like checking on your stock portfolio. If you had a guaranteed strategy returning 10% per year, but with a normal amount of noise, you’d observe losses almost 50% of the time if you observed your balance often enough, even as you employed a successful strategy. The law of large numbers only works … over longer timescales.
While at first this bot was merely a distraction, I’ve come to realize that what it does, albeit simplistically, is really necessary. One of the biggest problems with bitcoin is the way it is traded. The illiquidity of exchanges is a huge problem.
Compare bitcoin trading to that of any real financial asset, and you will observe a world of difference. Financial folks extract tremendous value in the maintenance of efficient markets in other assets.
This does not just happen magically. Bitcoin needs better functioning markets if it is to attract serious players. It’s also a profit opportunity.
Even at current trading volumes, a lot of value can be captured by smoothing out market fluctuations. If bitcoin were to grow, the need for liquidity would also increase. I’ve learned that infrastructure isn’t just servers and github repos. It’s also financial middlemen who make markets work. The mere fact that I could dabble in this, as nobody, illustrates the wonderful openness of bitcoin.