Design Lessons From My First Crypto Trading Bot
By: Jason Bowling
Tags: Cryptocurrency, Python, Bots, Bitcoin, Investing

There are some subtle gotchas… save yourself some time!

Image courtesy of Pixabay

I recently wrote my first cryptocurrency trading bot. I started by playing with historical prices for Bitcoin at ten minute intervals — I loaded them into Python Pandas dataframes and ran some simulations, buying low and selling high. It looked great! The code was simple, too — I figured it wouldn’t take more than a few hours to bolt on some robin_stock functions and go to town. I was wrong. Here’s what I learned as I went — perhaps it will save you some time.

Trading in simulation is simpler than trading in real life

When you simulate trades, you are probably making some assumptions. Your program decides to buy or sell at the price at that moment in time, and it succeeds, every time. Your simulation racks up the profit!

Reality isn’t quite as easy. Actual trades take a little time, and the price is changing. When your bot is trading live, sometimes only part of your order will complete before the price shifts significantly. It may not even complete any of the order. I refer to this as a “swing and miss”. Your bot needs to handle these situations gracefully. I opted to save the order transaction number and check the results every so often — if, after a hour, it didn’t result in a buy of coin, the bot cancelled the buy order and tried again.

In simulation, all your orders complete — in real life, you need to check for partial completion or missing the order entirely.

Limit buys and sells are your friend

When you trade live, you need to issue your buys and sells as either a limit order or market order. With a market order, the transaction will be completed at whatever the going rate is. That’s bad. Be careful with that, because that price can MOVE in a matter of seconds. That’s why you have a bot in the first place! I chose to place my orders as limit transactions, so that if the price moved dramatically, it wouldn’t buy or sell at a different price than I had intended.

You need to be careful with precision

In retrospect this is obvious, but it bit me the first time my code tried a live transaction. In simulation, it’s fine to issue a buy for (cash_on_hand/coin_price). Sure, the simulation might store that you bough 12.2342348998729384797 ETH, but who cares?

Try to do that in real life, and it will likely fail. The trading platform will have limits on the amount of precision you can specify for both the amount purchased and the price, and it varies by coin. This makes perfect sense when you think about it — DOGE is currently selling at a fraction of a cent, and BTC is currently selling over $19,000. You can’t reasonably buy small fractions of DOGE the way you can with BTC.

My bot built lookup tables for the maximum precision of both price and amount purchased for each coin, and used them to compute buy order amounts. Do it wrong, and you’ll likely get an error back from the server.

Image courtesy of Pixabay

You can’t assume the server will always respond as you expect

This is just good programming practice, but it gets driven home pretty quickly if you don’t write it in from the beginning. Every time you issue a call that talks to the server — getting prices, issuing an order, checking status — check for exceptions. Every. Single. Time.

Your simulation doesn’t have maintenance windows. Your simulation doesn’t have server failures or badly written calls to a library you didn’t write. Real life has all these things…. and furthermore….

Assume your internet connection will fail, and the power will go off

You have to deal with losing power, losing internet, and program crashes. If you are computing values like moving averages or RSI, or looking at candlestick patterns, you need to be very sure that your data is sequential and hasn’t had a break. If it does, your program could make bad calls. You need to save state, and check date stamps of data. If a break in data is found during the period of time you are computing indicators against, you need to pause execution until you have the full range of data that you are calculating against.

Be absolutely sure you match the correct coin to the sale price

It is entirely possible to have an error that results in your bot trying to sell a coin at the price of another. You have to do something really dumb — and I did. Due to a poor design decision on my part, an early version of my bot tried to sell some BTC at the current cost of some BCH, which was an order of magnitude lower.

The only reason it didn’t make me very, very sad was because the prices were so far apart that the trading service flagged it as an error. Had it been merely off by, say, a factor of four, it would have let me do it, and it would have cost me a lot.

Be very, very careful.

It’s very useful to have the bot text you

Most cell phone companies have a way to send emails that will arrive at your cell as a text message. This makes it easy for your bot to keep you up to date on what it’s doing in real time when you are off doing other things. If it is victorious, you want to know. If it does something stupid, you _really_ want to know.

I configured mine to tell me when it bought or sold, and also to send the results from each transaction order. That way, I could tell if it was issuing successful orders or not.

Make sure you can trade with less than all of your money

There will come a time when you make some changes that you want to test with small transactions. Build this capability into your bot from the beginning — you don’t want to be testing live with all the cash in your account.

Static Analysis Reduces Development Time

This is also good programming practice. In Python, some errors won’t be seen until a branch of code is executed. If this is in a function that doesn’t get run terribly often, like your buy() or sell() functions, you may not catch it for hours.

Using tools like PyLint and PyFlakes, you can catch some of these errors quickly. I highly recommend them, to save yourself some time.

Be careful, and have fun!

Please note that none of this should be considered financial advice, and I’m a rookie anyway. Any risk you take in investing is yours, and yours alone. Writing a program to spend your money is an even riskier thing to do than manually trading cryptocurrencies, and that’s saying something!