Obtaining historical and real-time crypto data with very simple web programming | by LucianoSphere | Towards Data Science

While learning about cryptocurrencies, I desperately needed data that I could manipulate myself to do my own plots and analyses. Here I show you how to easily get real-time and historical crypto data right in your web browser with minimal programming skills. Source code, links, and some basic plots and analyses included.
Disclaimer: You will not find any financial advice here and I’m no expert in cryptocurrency, cryptoart, NFTs, their trading, etc. I only give away free HTML+JavaScript code to get data through API calls to CryptoCompare.com; and I display some plots derived from that data with some of my own subjective opinions.
And... If you need any ad hoc job such as a web app tailored for your problem, just contact me!
I recently got interested in cryptocurrencies, cryptoart, NFTs, etc. Naturally, as a scientist working with data all the time, one of the first things I wanted to do was to play with cryptocurrency data myself. I saw plots everywhere in websites, news, and apps; but how could I get my hands on actual data to play with it and do my own plots and investigations? And especially, how could I be sure it was up to date every time I requested it?
Specifically, the first thing I wanted to put my hands on were the exchange rates between various crypto and Fiat currencies. I found that the website CryptoCompare.com offers a nice API, free for small numbers of calls, that allows programmatic access to data from its base. I also found online various pieces of JavaScript code that I put together into two very simple web apps: one to get updates of BTC-USD exchange rates every 10 seconds; and another to retrieve historical BTC-USD exchange rates every minute, hour, or day throughout the whole history of Bitcoin. Feel free to copy the code I present and to adapt it to your own goals.
Of course, you could open any cryptocurrency website or app and get this number from there, but suppose that you want to have it always at hand and refreshing automatically, or perhaps you want to have it fed automatically to a calculation system you are developing.
Simple access to this link at CryptoCompare’s API returns the exchange rate of Bitcoin (BTC) in USD right at the moment you make the call:
https://min-api.cryptocompare.com/data/price?fsym=BTC&tsyms=USD
Likewise, this other example gives you the exchange rate of Ethereum (ETH) in EUR at the moment of the call:
https://min-api.cryptocompare.com/data/price?fsym=ETH&tsyms=EUR
Easy, isn’t it? Well, building on that, the following code returns whatever conversion you ask for (in this example BTC in USD) every 10 seconds, in a small web page that you can make private to follow your favorite rates in your own website:
<html><head>    <title>Get crypto data in real time</title></head><body>    <p id='info'></p>    <p id='infotime'></p></body><script>const getBtcData = async () => {   fetch('https://min-api.cryptocompare.com/data/price?fsym=BTC&tsyms=USD')  .then(response => response.json())  .then(data => {    console.log(data);    document.getElementById("info").innerHTML = '<b>1 BTC = ' + data.USD + ' USD</b>'  });}getBtcData();tcount=setInterval(function(){  tcount++  if (tcount==10) {getBtcData(); tcount=0}  document.getElementById("infotime").innerHTML = 'Next update in ' + (10-tcount) + ' seconds'},1000);</script></html>
You can copy-paste this code into a .html file and then load it with your browser, to see it running. Or if you feel lazy, just open this demo example at my site:
https://lucianoabriata.altervista.org/tests/cryptogames/getBTC-realtime.html
You could easily develop that further into a web app that constantly keeps track of any exchange rates, even store it in a plot for visualization on the go or in a variable for download.
But what if you want to get data before the web page is started? Well, you could go to specialized websites and download these data; however, I found that easy-to-use websites only provide partial data. For example, BTC data at Yahoo Finances starts on September 17, 2014 and its records are monthly, weekly, or daily, but not say hourly or per minute. Besides, if you are developing a system that needs to be automatically updated, manual data download is out of discussion... you need programmatic access.
Fortunately, CryptoCompare’s API includes ways to retrieve historical data timed in minutes, hours, or days. Not only exchange rates but also other metrics such as exchange volumes. To know more about the API see its documentation and read the following.
An API call like in this example will get you data for the last 20 hours, hour by hour:
https://min-api.cryptocompare.com/data/v2/histohour?fsym=ETH&tsym=USD&limit=20&toTs=-1&api_key=YOURKEYHERE
The output is parsable in JSON format. It looks like this:
Points to notice in the URL for the API call (that we’ll next use inside a fetch() javascript function):
toTs=-1 means that you want data up to the moment the call is executed.limit is the number of lines you want.You need to provide an API key.
toTs=-1 means that you want data up to the moment the call is executed.
limit is the number of lines you want.
You need to provide an API key.
With the free API key (get it at the documentation page; and yes, you can purchase keys with more advanced features) you are limited in the total number of calls you can do, and each call will give you only up to 2000 entries. So for example if you ask for, say, the hourly exchange rates for BTC in USD, the maximum you will get is 2000 minutes backward from the prompted time, which means around 33 hours, i.e. just over a day. Or if you ask for hourly data, you will get at most data for 83.33 consecutive days, just under 3 months. However, this isn’t really a big problem, because you can repeat the API backward in time as many times as you need to cover the time gap you are interested in. For example, to get daily BTC data back until its origins you need slightly over 4000 points (days) as of August 2021 when this story was written. This means you need only 3 consecutive calls. And if you want hourly data for the same period, you are after around 98400 points, which are covered by 50 consecutive calls.
Let me show you this web app, with which you can ask for daily historical data for any exchange rate to USD:
<html><head><title>Get historical crypto data</title></head><body>  <h2>Crypto data in your web browser:</h2>  <table width=80%><tr><td valign=top width=40%>    <button onclick='getBtcData()'>Get latest data</button>    <p><br>    <b>From:</b>    <input id='fromTime' value='XXXX' size=10></input>    <p id='fromInfo'></p>    <br>    <b>To:</b>    <input id='toTime' value='XXXX' size=10></input>    <p id='toInfo'></p>    <br>    <button onclick='getBtcDataPrevious()'>Get previous period</button>    <p>    <hr>    <p>    <button onclick='document.getElementById("txtout").value = ""; getBtcData()'>Restart with:</button>    <input id='cryptoCurr' value='BTC' size=5></input> (in USD)  </td><td width=60%>    <textarea id="txtout" cols=60 rows=20></textarea>  </td></tr></table></body><script>const getBtcData = async () => {  const response = await fetch('https://min-api.cryptocompare.com/data/v2/histohour?fsym=' + document.getElementById('cryptoCurr').value + '&tsym=USD&limit=2000&toTs=-1&api_key=YOURAPIKEY');  const json = await response.json();  const data = json.Data.Data  const times = data.map(obj => obj.time)  const prices = data.map(obj => obj.high)  var txt=""  for (var i=0;i<times.length;i++)  {    txt = txt + times[i] + "\t" + serialDateToNiceDate(times[i]/3600/24).toString().substr(0,24) + "\t" + prices[i] + "\n"  }  document.getElementById("txtout").value = txt  document.getElementById("fromTime").value = times[0]  document.getElementById("toTime").value = times[times.length-1]  document.getElementById("fromInfo").innerHTML = "<i>(" + serialDateToNiceDate(times[0]/3600/24).toString().substr(0,24) + ")</i>"  document.getElementById("toInfo").innerHTML = "<i>(" + serialDateToNiceDate(times[times.length-1]/3600/24).toString().substr(0,24)+ ")</i>"}const getBtcDataPrevious = async () => {  const response = await fetch('https://min-api.cryptocompare.com/data/v2/histohour?fsym=' + document.getElementById('cryptoCurr').value + '&tsym=USD&limit=2000&toTs=' + document.getElementById('fromTime').value + '&api_key=YOURAPIKEY');  const json = await response.json();  const data = json.Data.Data  const times = data.map(obj => obj.time)  const prices = data.map(obj => obj.high)  var txt=""  for (var i=0;i<times.length;i++)  {    txt = txt + times[i] + "\t" + serialDateToNiceDate(times[i]/3600/24).toString().substr(0,24) + "\t" + prices[i] + "\n"  }  tmp=document.getElementById("txtout").value  document.getElementById("txtout").value = txt + tmp  document.getElementById("fromTime").value = times[0]  document.getElementById("toTime").value = times[times.length-1]  document.getElementById("fromInfo").innerHTML = "<i>(" + serialDateToNiceDate(times[0]/3600/24).toString().substr(0,24) + ")</i>"  document.getElementById("toInfo").innerHTML = "<i>(" + serialDateToNiceDate(times[times.length-1]/3600/24).toString().substr(0,24)+ ")</i>"}getBtcData()function serialDateToNiceDate(date) {  return new Date(Math.round((date)*86400*1000));}</script></html>
The code may look a little bit complicated, but it could be much simpler. The thing here is that I created a whole interface to let the user chose in what time range to get the data, and then concatenates the results from subsequent calls in a text box for easy copying:
Note that you have to call the API twice: once inside the function that calls for a list of data entries up to the moment of execution (getBtcData, run when the user clicks “Get latest data” and also automatically on load) and another for the function that returns data before a given time (getBtcDataPrevious). Notice too that the functions automatically update the From and To times, which are displayed in raw serial format and also converted to human-readable form by the function serialDateToNiceDate.
After loading the page, or clicking “Get latest data” the text box on the right gets populated with the last 2000 hourly entries, and the From and To times are updated. You can then subsequently request 2000 line blocks of data from the preceding periods by clicking on “Get previous period”. The incoming lines will be added to the text box, keeping the historical order.
Looking at some historical data
As I said in the introduction, I was very eager to get data about the time evolution of BTC:USD exchanges since the creation of Bitcoin. With a small edit to the web app shown above (simply changing “histohour” by “histoday”), you get an app that returns daily records. Then with three clicks on “Get previous period” you get the whole daily data for Bitcoin, starting back in July 2010 until now.
Let’s do a few plots of these data. First simply the exchange rate over time, a plot that you see in most apps, sites, and news:
The plot shows five key up-times: one around late 2013, a stronger one around late 2017 - early 2018 followed by another in 2019, and then a stronger one during the first half of 2021 followed by a new rapid increase happening right now.
It is interesting how the maxima observed in that plot roughly match the interest over time as measured by Google Trends:
Another plot of our retrieved BTC:USD exchange data, more interesting than the one we did above, is this one where the price is treated in logarithmic (here log in base 10) form:
This log transformation spots the up-phases more clearly. Check that the relative peak heights from base to top are quite different, and seem to be slowly dampening: the first main peak entails a gain of roughly 1.5 orders of magnitude (around 30X); the second, third and fourth are around 1 order of magnitude (around 10X), and the last one around only 0.5 orders of magnitude (around 3.2X). Thus despite the historical maxima getting very high, the chances of huge profits are gradually decreasing for people investing later. Although it’s then too late to get rich with Bitcoin, the overall trend in the BTC:USD exchange rate seems to indicate that it may still grow for some time (not telling you to buy here, just naively extrapolating from the plot):
These log plots contain much more data, which others have analyzed in the following blog articles. Not being an expert, I cannot judge them, but they certainly are very interesting:
medium.com
www.tradingview.com
www.lookintobitcoin.com
www.blockchaincenter.net
Conclusion and selected further reading
I hope you will have fun using these and derived scripts to get and play with crypto data. This whole field is very interesting, and in doing my research about cryptocurrencies in the last two years, I’ve read tons of papers, stories and posts, of which I have distilled these for you to keep going from here, mainly from Medium and its associated publications.
Added some months after publishing this story: check this alternative API that does not require keys:
towardsdatascience.com
Now the recommended articles:
towardsdatascience.com
medium.com
medium.datadriveninvestor.com
medium.com
medium.com
medium.com
Liked this article and want to tip me? [Paypal] -Thanks!
I am a nature, science, technology, programming, and DIY enthusiast. Biotechnologist and chemist, in the wet lab and with computers. I write about everything that lies within my broad sphere of interests. Check out my lists for more stories. Become a Medium member to access all its stories and subscribe to get my new stories by email (original affiliate links of the platform for which I get small revenues without special costs to you). Donate here through various means. Contact me here for any kind of inquiry.
To consult about small jobs (on programming, biotech + bioinf project evaluations, science outreach + communication, molecular data analysis and design, molecular graphics, photography, private courses and tutorials, private lessons, teaching and tutoring, etc.) check my services page here.