Data science /

Predicting Bitcoin prices with AI

May 31 2021/8 min read

What do I, a 19-year-old kid who struggles with making his bed every morning, have in common with Wall Street quant firms? We both know which way Bitcoin will go.

You need not have deep pockets or talented engineers to predict Bitcoin prices. Just use Python to download publicly available data and the Peltarion platform to train an AI on it. How hard can it be? As it turns out, it is not hard at all. I have done exactly this, and below I will guide you through my journey from a complete AI novice to someone who may or may not be feared by Wall Street.

Disclaimer: This blog post is provided by a third party as described herein. The content is provided for informational purposes only, you should not construe any such information as investment, financial, trading or other advice. We accept no liability whatsoever for any loss or damage howsoever arising.

02/ TL;DR

I used the historical price data of Bitcoin to train an AI model that predicts if Bitcoin would go up or go down the next minute. I tested it for 7 hours in total and it managed to guess correctly 55% of the time. I knew very little about AI when starting in this project, and this blog will show you my complete learning journey.

03/ The data

You can’t train an AI model on bad data, but that didn’t stop me from trying. I know there are tons of libraries and APIs for Python for data collection, but I’m lazy so I tried to find an easier way to get my hands on it. After searching for “Bitcoin price history” I found out that you can export the all-time price history of Bitcoin from CoinDesk, in daily candles (big mistake). This gave me a 173 kB CSV file with 2775 rows of Bitcoin prices in the OHLC (Open, High, Low and Close) format since October 2010. 2775 rows is not that much compared to what we will have later (in the 1 million range), but at the time this was all I had.

Using Excel, I added some moving averages. I also added an RSI (Relative Strength Index) indicator which is common when analysing stocks and crypto. Lastly, I added the column which the model will try to predict; whether the next day is positive or not (TRUE or FALSE).

The very first CSV file. Before uploading this as a dataset, I cleaned it using the Data Cleaner Tool.

04/ The model

At this point I dove into the Peltarion platform headfirst and hoped for the best. I uploaded the data, saved it and used it in a new experiment. I selected everything but the date as the input and the “Next day positive” as the target. The only thing in the modelling view which I understood at the time was the “Patience (epochs)” parameter which was set to 5, so I bumped it up to 20 to let my model run a bit longer.  

To my surprise, the model was able to achieve a roughly 52% accuracy in predicting the price the next day. But fear not, I did not manage to get the model right the first time. The reason for this high accuracy is because 53.9% of the total days were positive, so the model actually performed worse than only guessing TRUE every day. 

At this point (and a lot of points going forward) I noticed that the model wasn’t really learning anything. My limited knowledge about ML told me that a graph like this should look like a log(x) graph: steep in the beginning, and then flattening out after a while. My graph was going sideways the whole way. It looked as if it was just blindly guessing until it got something right.

So, I started testing some theories that I had for improving my model. My first theory was that the model could not handle that many inputs, but that turned out to be false, and the model performed worse with fewer inputs. My second theory was that I was using the wrong problem type, so I changed it from tabular classification to tabular regression. I wasn’t quite sure how this affected my model, since I couldn’t see any obvious changes in the modelling view, but the model performed better this time. It managed to get an accuracy of 54.2%, which is better than guessing true every time.

From here on I played with different settings, trying to learn what they all did. I discovered the dropout ratio, and it turned out that my model got better with a lower value. I discovered overfitting and underfitting. I discovered class weights, which I should have been using all along since my target class is not evenly split. None of these tweaks resulted in any substantial improvement in the model, and it still looked fundamentally flawed since it wasn’t really learning anything, the flat curve was just moving a bit higher or a bit lower on the Y-axis and getting random higher peaks.

My very first try, with default settings. It does not look to be learning a lot.

05/ The breakthrough

It was time for a complete overhaul, and after searching for a long time and not finding any solutions to my problem, my colleague unknowingly gave me my solution. He suggested I should use minute candles instead of daily. This solves the biggest problem of my model: it removes most of the external factors from the price action. Usually, the price of a stock or cryptocurrency is determined by the market sentiment and not the historical price (which I am basing my model on). But if the time period is lower, there will be fewer external events during that time, and any patterns in the historical data will be easier to spot. So using Python with Binance’s API I downloaded 3 million minutes of Bitcoin OHLC data, 2 million of which didn’t fit in Excel. 

This alone didn’t improve the model that much, but then my other colleague told me to normalize the data (dividing the OHLC data by the open price makes the numbers represent % values up or down from the open price (0.123% gain, 0.123% loss etc), instead of having absolute prices like $45 173 or $45 174. This makes it harder for the model, which is a good thing). Lastly, he told me to add some of the previous candles (also normalized) in each row, so I added 5 Close / Close values for n-k minutes, k = {1, ..., 5} and the same for Open / Close. These three factors in combination made my model look like a real AI model. It was learning, and the graph looked like a log(x) graph. It also performed very well. With an almost exactly 50/50 split in the dataset between TRUE and FALSE values for Next day (minute) positive, this model managed to get a staggering 55.6% accuracy. 

The model is getting better with time. Yay!

06/ Here comes the money!

By now I had a model that was working well, so naturally I started to think about how many motors I wanted in my new Cybertruck. But first I needed to release this beast into the wild and bring home the bacon. I wrote a simple Python program with the CCXT package that fetches the last fifty-two minutes of Bitcoin prices (Because of how the 50-minute average is calculated, it needs to go back fifty one candles to calculate the average up to the current (52nd) candle). Then I wrote some for-loops that calculated the rest of the data (Close / Previous Close etc). So now the data is ready, but how do you use the Peltarion model on it and get an output more or less instantly, you may ask? The answer is Zapier. Without having to write a single line of code, I can use my almighty oracle AI model on the data in real-time and type out what it thinks the future holds to a Google Sheet. So no messing around with the Peltarion Python API to get the prediction or a Google Drive API to write to a Sheet (I did try the Google Drive API and it was quite a headache). All of this takes about two seconds, so by collecting and evaluating the data just before a minute candle closes, I have a fresh prediction for the next candle, and can act on it. 

The way I did all this was by sending a webhook with the data to Zapier, which was just one line of code in Python. I made my program do this once every minute. Here is a link to the Python code I wrote. The webhook consists of JSON data which conveniently has the same formatting as the Python dictionary I used to store all the data. Then I selected the Peltarion evaluation as the action, fed it everything it had just received, and used that evaluation in another action to write a new row in my Google Sheet. I also wrote the previous Close / Close value, so that I can evaluate if the previous prediction was right or wrong. Now, before throwing in the next month’s rent for this amazing and certainly profitable AI Bitcoin Bot to use, I let it run for about two hours without taking any action on the predictions, to see how it did.

It is also worth noting that you could do this without writing any code at all. There are apps in Zapier that can get you hourly and daily candles (unfortunately no minute candles) of Bitcoin prices, so if you trained your model on that then you could get something half decent in a fraction of the time and without touching any code. 

Real time testing using Zapier.

07/ No bacon for me

Obviously 120 candles as data isn’t that much, but what I saw did put a spoke in my wheel. It managed a similar result to the training data, coming in at about 55% correct guesses in total (it was correct almost 60% of the time in the first hour). Which is impressive. But trading isn’t free, so I did a little more analysis on these two hours to see how it would turn out if I had traded on it. When leverage trading on Binance (COIN-M Futures), the fee will be about 0.1% of the traded amount, per completed trade (0.05% to open it, 0.05% to close it). And when looking at all the guesses, the price went up by an average of 0.018% when the model said it would go up, and by an average of -0.014% when the model said it would go down (this data did not fit in the screenshot. The “avg up” and “avg down” in the picture is not related to what the model predicted). So even when being correct >50% of the time on where the price is going, you’re losing money even on the candles you do get right because of the fees. And no, you can’t just use a higher leverage (or none at all) to combat this, since the fee is going to grow by the same amount. So it looks like my white bread and water breakfast isn’t changing anytime soon.  

The two leftmost columns were written by the Zapier deployment. Everything else was done manually to analyse the results.

08/ What I would have done differently

Since I have limited time and resources, a lot of compromises and shortcuts were made in this project. There are a ton of things that I would do to improve this project if I were to do it again. Both in the modelling itself, and in the way I would use this. 

  • In the modelling you could change the target class to be something other than “Next day positive”, which is a pretty bad target class, since a 0.0001% gain will count just as true just as a 0.4% gain would. Instead, you could go for something similar to the fee amount, but then even if you’re right 60% of the time, you will need to make enough money those times to combat the fees + realised loss on the 40% of the time you were wrong. 
  • Ideally you would deploy the model on a similar market to the one you trained it on. Maybe making one bull model and one bear model. I did not take this into consideration at all during this project.
  • If you don’t want to make a sentiment analysis model (maybe integrate them together?), you might change this one so that it deactivates for an hour if Elon Musk tweets, or something similar to that. The model probably performs terribly at times like that, whether it is a celebrity tweeting about it or a superpower banning it. You could also try to train the model on a time period where there are few external events. 
  • One more easy fix is to try to lower the fees, which you can do in several ways. For instance, if you were a taker in the trade instead of being the maker like I was, your fees would be one fifth of what I wrote earlier. And while you’re at it you might as well put in a stop-loss so that your average profit gets a bit higher. And maybe a well-placed take-profit is helpful as well.
  • It is entirely possible that I have messed up something in my final calculations about the average gains and losses, or the Python calculations when manipulating the real time data. There are a lot of sources of error in this project.
  • And I’m sure you know lots of more ways to improve this that I haven’t thought of!

09/ Conclusion

So as you know by now it is definitely possible and not that hard to predict which way the price of Bitcoin will go. Unfortunately, it looks like the profit margins are lower than the fees you need to pay if you decide to trade on this. But as previously mentioned, I’m sure with some tweaking of the model and optimization of the way you use it could get you closer to actually making a profit. And if you ever manage to get something profitable, it would be interesting to see how that compares to just holding the underlying asset. But nevertheless, it has certainly been a very interesting project, and I would love to revisit it sometime in the future. Maybe with a new take on it, like basing it on sentiment analysis.

  • Alexander Gusev

    Alexander Gusev

    Computer Science student

    Alexander studies Computer Science in Linköping, and when he is not wasting his time on his computer, he likes to sit in the sun or try to keep his plants alive.

02/ More on Data science