In this article we will be calling cryptocompare.com API to get Bitcoin, Ethereum (or any cryptocurrency) historical price data. The API serves the data in JSON format and the actual useful payload is in an array of dictionaries. Turns out that Pandas library can easily convert these into the dataframe. Once the data is in dataframe, further processing is rather straightforward. Subsequently we will visualize the historical Bitcoin price data via matplotlib library.
This historical data can eventually be used for time series analysis, price alarming script or even for creation of simple trading bot.
Import libraries
import pandas as pd
import matplotlib.pyplot as plt
import requests
from datetime import datetime
# pretty printing of pandas dataframe
pd.set_option('expand_frame_repr', False)
Call the API to get data
How to call the cryptocompare.com API:
https://min-api.cryptocompare.com/data/price?fsym=BTC&tsyms=USD
The API call consists of two parts,
first is baseurl
https://min-api.cryptocompare.com/data/price
and second are parameters that we provide for the call
fsym=BTC&tsyms=USD
We can serve the actual paramaters as a dictionary with requests.get()
method.
This is very convenient when we want to pass it multiple arguments.
We start first by implementing simpler case first, we will just get current price (optionally we can specify target currency - USD, EUR, JPY ...). This implementation can be used in the future to create for example simple price watchbot that would run from cron periodically.
# GET CURRENT PRICE DATA
def get_current_data(from_sym='BTC', to_sym='USD', exchange=''):
url = 'https://min-api.cryptocompare.com/data/price'
parameters = {'fsym': from_sym,
'tsyms': to_sym }
if exchange:
print('exchange: ', exchange)
parameters['e'] = exchange
# response comes as json
response = requests.get(url, params=parameters)
data = response.json()
return data
Get Bitcoin/USD price data from Coinbase cryptocurrency exchange
get_current_data('BTC','USD','coinbase')
Our main focus will be on getting the historical price data for given cryptocurrency. Regarding the series of historical data, we can download daily, hourly and even minute historical data.
There is a limit of 2000 time datapoints with each API call. Theoretically we can even write a script that would chain these calls together so we get minute data for all of the trading history. Another option is to choose aggreagation
option with the call, this way we can aggregate hourly data for example to 6 hour blocks. This way each candle data will be 6 hour timeframe.
Examples of daily, hourly and minute calls:
We can se that it will be convenient to use baseurl
https://min-api.cryptocompare.com/data/v2/histo
and then append to it day
, hour
or minute
based on our needs.The parameters will be again in a dictionary.
API call details
API call
https://min-api.cryptocompare.com/data/v2/histoday?fsym=BTC&tsym=USD&limit=10
results in following JSON payload:
Object
Response: "Success"
Message: ""
HasWarning: false
Type: 100
RateLimit: Object
Data: Object
Aggregated: false
TimeFrom: 1577059200
TimeTo: 1577923200
Data: Array [11]
0: Object
time: 1577059200
high: 7694.65
low: 7275.28
open: 7517.58
volumefrom: 44770.93
volumeto: 336425000.06
close: 7326.6
conversionType: "direct"
conversionSymbol: ""
important are
Data: Object
and
Data: Array [11]
The Data: Array [11]
contains dictionaries.
To get to the dictionary payload, we will need to use
data = response.json()['Data']['Data']
Alternative JSON response representation:
{"Response":"Success","Message":"","HasWarning":false,"Type":100,"RateLimit":{},"Data":{"Aggregated":false,"TimeFrom":1577059200,"TimeTo":1577923200,"Data":[{"time":1577059200,"high":7694.65,"low":7275.28,"open":7517.58,"volumefrom":44770.93,"volumeto":336425000.06,"close":7326.6,"conversionType":"direct","conversionSymbol":""},{"time":1577145600,"high":7429.42,"low":7175.5,"open":7326.6,"volumefrom":27770.75,"volumeto":203013413.87,"close":7260.91,"conversionType":"direct","conversionSymbol":""},{"time":1577232000,"high":7280.52,"low":7132.3,"open":7260.91,"volumefrom":15012.21,"volumeto":108513256.34,"close":7202.72,"conversionType":"direct","conversionSymbol":""},{"time":1577923200,"high":7224.84,"low":6945.83,"open":7189.94,"volumefrom":23986.57,"volumeto":169623124.82,"close":6959.49,"conversionType":"direct","conversionSymbol":""}]}}
So we need to access the dictionaries and transform them into Pandas dataframe. Pandas makes this process simple.
Code implementation
Download the JSON via Cryptocompare API:
def get_hist_data(from_sym='BTC', to_sym='USD', timeframe = 'day', limit=2000, aggregation=1, exchange=''):
url = 'https://min-api.cryptocompare.com/data/v2/histo'
url += timeframe
parameters = {'fsym': from_sym,
'tsym': to_sym,
'limit': limit,
'aggregate': aggregation}
if exchange:
print('exchange: ', exchange)
parameters['e'] = exchange
print('baseurl: ', baseurl)
print('timeframe: ', timeframe)
print('parameters: ', parameters)
# response comes as json
response = requests.get(baseurl, params=parameters)
data = response.json()['Data']['Data']
return data
Transform JSON paylod into Pandas dataframe:
def data_to_dataframe(data):
#data from json is in array of dictionaries
df = pd.DataFrame.from_dict(data)
# time is stored as an epoch, we need normal dates
df['time'] = pd.to_datetime(df['time'], unit='s')
df.set_index('time', inplace=True)
print(df.tail())
return df
Plot the historical price data via matplotlib library:
def plot_data(df, cryptocurrency, target_currency):
# got his warning because combining matplotlib
# and time in pandas converted from epoch to normal date
# To register the converters:
# >>> from pandas.plotting import register_matplotlib_converters
# >>> register_matplotlib_converters()
# warnings.warn(msg, FutureWarning)
from pandas.plotting import register_matplotlib_converters
register_matplotlib_converters()
plt.figure(figsize=(15,5))
plt.title('{} / {} price data'.format(cryptocurrency, target_currency))
plt.plot(df.index, df.close)
plt.legend()
plt.show()
return None
Finally, specify the cryptocurrency (in this case Bitcoin) and call the defined functions.
cryptocurrency = 'BTC'
target_currency = 'USD'
data = get_hist_data(cryptocurrency, target_currency, 'day', 1000)
df = data_to_dataframe(data)
plot_data(df, cryptocurrency, target_currency)
Sources:
Another possible API to use: