Profile picture

Co-founder @ RMOTR

Alpha Vantage Cryptos Live Docs

Last updated: July 26th, 20192019-07-26Project preview

Alpha Vantage is today one of the best sources to get financial data. It's not just for cryptos. Also offers Stock prices, Forex rates and other indicators.

Alpha Vantage strong selling point is its simplicity. It has a couple of simple to use methods that give you access to prices with just a few requests. The limitation is that it doesn't offer data "per exchange". That is, you can't access Bitcoin prices in both Coinbase and Bitstamp (for example). There's only one price for Bitcoin (probably a weighted average).

In [1]:
import os
import requests
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

%matplotlib inline

API Authentication

Before we begin, you MUST request a free API key from Alpha Vantage's official site: https://www.alphavantage.co/support/#api-key

After getting the API Key, you can set it as an environment variable (in the project edit page) or just replace it where it says 'YOUR-API-KEY'.

In [2]:
AV_API_KEY = os.environ.get('ALPHAVANTAGE_API_KEY', 'YOUR-API-KEY')
In [3]:
assert AV_API_KEY != 'YOUR-API-KEY'

we'll use this API Key in each request sending it as a regular parameter.

Supported cryptos and fiat currencies

With this project I've included 2 csv files with the cryptocurrencies supported by Alpha Vantage. Fork it to see it by yourself. Here's a quick summary:

In [ ]:
cryptos = pd.read_csv('digital_currency_list.csv')
cryptos.head()
In [ ]:
cryptos[cryptos['currency name'].str.contains('Bitcoin')]
In [ ]:
cryptos[cryptos['currency name'].str.contains('Ethereum')]
In [ ]:
fiat = pd.read_csv('physical_currency_list.csv')
In [ ]:
fiat.head()
In [ ]:
fiat[fiat['currency code'] == 'USD']

Realtime exchange rates

The simplest function exposed by Alpha Vantage API is CURRENCY_EXCHANGE_RATE, which returns the current exchange rate (the price) for a given crypto. Here's an example with Bitcoin:

In [4]:
resp = requests.get('https://www.alphavantage.co/query', params={
    'function': 'CURRENCY_EXCHANGE_RATE',
    'from_currency': 'BTC',
    'to_currency': 'USD',
    'apikey': AV_API_KEY
})
In [5]:
resp
Out[5]:
<Response [200]>
In [6]:
resp.json()
Out[6]:
{'Realtime Currency Exchange Rate': {'1. From_Currency Code': 'BTC',
  '2. From_Currency Name': 'Bitcoin',
  '3. To_Currency Code': 'USD',
  '4. To_Currency Name': 'United States Dollar',
  '5. Exchange Rate': '9865.09000000',
  '6. Last Refreshed': '2019-07-25 21:21:54',
  '7. Time Zone': 'UTC',
  '8. Bid Price': '-',
  '9. Ask Price': '-'}}

And here's one for Ethereum:

In [7]:
resp = requests.get('https://www.alphavantage.co/query', params={
    'function': 'CURRENCY_EXCHANGE_RATE',
    'from_currency': 'ETH',
    'to_currency': 'USD',
    'apikey': AV_API_KEY
})
In [8]:
resp
Out[8]:
<Response [200]>
In [9]:
resp.json()
Out[9]:
{'Realtime Currency Exchange Rate': {'1. From_Currency Code': 'ETH',
  '2. From_Currency Name': 'Ethereum',
  '3. To_Currency Code': 'USD',
  '4. To_Currency Name': 'United States Dollar',
  '5. Exchange Rate': '218.50000000',
  '6. Last Refreshed': '2019-07-25 21:22:06',
  '7. Time Zone': 'UTC',
  '8. Bid Price': '-',
  '9. Ask Price': '-'}}

Cryptos' daily data

From the docs:

This API returns the daily historical time series for a digital currency (e.g., BTC) traded on a specific market (e.g., CNY/Chinese Yuan), refreshed daily at midnight (UTC).

The function to use in this case is DIGITAL_CURRENCY_DAILY.

In [29]:
resp = requests.get('https://www.alphavantage.co/query', params={
    'function': 'DIGITAL_CURRENCY_DAILY',
    'symbol': 'BTC',
    'market': 'USD',
    'apikey': AV_API_KEY
})
In [30]:
resp
Out[30]:
<Response [200]>
In [12]:
doc = resp.json()

We can see the metadata associated with the response:

In [13]:
doc['Meta Data']
Out[13]:
{'1. Information': 'Daily Prices and Volumes for Digital Currency',
 '2. Digital Currency Code': 'BTC',
 '3. Digital Currency Name': 'Bitcoin',
 '4. Market Code': 'USD',
 '5. Market Name': 'United States Dollar',
 '6. Last Refreshed': '2019-07-24 (end of day)',
 '7. Time Zone': 'UTC'}

This endpoint returns more than 4 years of data. For example, Jan 1st:

In [34]:
doc['Time Series (Digital Currency Daily)']['2019-01-01']
Out[34]:
{'1a. open (USD)': '3750.20584555',
 '1b. open (USD)': '3750.20584555',
 '2a. high (USD)': '3863.96690671',
 '2b. high (USD)': '3863.96690671',
 '3a. low (USD)': '3718.57823790',
 '3b. low (USD)': '3718.57823790',
 '4a. close (USD)': '3862.87078827',
 '4b. close (USD)': '3862.87078827',
 '5. volume': '96375.76131757',
 '6. market cap (USD)': '372287113.09130031'}

Feb 2nd:

In [35]:
doc['Time Series (Digital Currency Daily)']['2019-02-01']
Out[35]:
{'1a. open (USD)': '3451.51132461',
 '1b. open (USD)': '3451.51132461',
 '2a. high (USD)': '3492.93792403',
 '2b. high (USD)': '3492.93792403',
 '3a. low (USD)': '3423.10011716',
 '3b. low (USD)': '3423.10011716',
 '4a. close (USD)': '3479.09411435',
 '4b. close (USD)': '3479.09411435',
 '5. volume': '117437.91487470',
 '6. market cap (USD)': '408577558.44244128'}

There are repeated values because the result will always include USD information. Now, I'll turn it into a pandas DataFrame to visualize it:

In [16]:
df = pd.DataFrame.from_dict(doc['Time Series (Digital Currency Daily)'], orient='index', dtype=np.float)
df.head()
Out[16]:
1a. open (USD) 1b. open (USD) 2a. high (USD) 2b. high (USD) 3a. low (USD) 3b. low (USD) 4a. close (USD) 4b. close (USD) 5. volume 6. market cap (USD)
2014-04-01 468.480106 468.480106 491.267273 491.267273 468.480106 468.480106 479.023434 479.023434 62894.683068 3.012803e+07
2014-04-02 479.679615 479.679615 494.111337 494.111337 430.725909 430.725909 438.377824 438.377824 96314.587552 4.222218e+07
2014-04-03 437.322089 437.322089 452.441405 452.441405 414.811104 414.811104 446.819755 446.819755 74292.749549 3.319547e+07
2014-04-04 448.597144 448.597144 457.327172 457.327172 429.184117 429.184117 451.645992 451.645992 39267.667348 1.773508e+07
2014-04-05 450.027798 450.027798 466.385470 466.385470 445.107783 445.107783 464.379322 464.379322 21574.144537 1.001859e+07

And we'll do some processing to "clean it" a little bit. First step is get rid of repeated columns:

In [36]:
[c for c in df.columns.values if 'b.' in c]
Out[36]:
[]
In [37]:
df.drop(columns=[c for c in df.columns.values if 'b.' in c], inplace=True)
In [38]:
df.head()
Out[38]:
BTC BCH BTG
index
2017-10-24 5512.769492 322.941096 106.242199
2017-10-25 5739.145869 328.902454 111.763120
2017-10-26 5893.642088 335.314685 114.858331
2017-10-27 5761.508307 364.390464 102.277440
2017-10-28 5737.983387 417.587081 96.758188

And now turn the index into a DateTime index:

In [39]:
df.reset_index(inplace=True)
df.head()
Out[39]:
index BTC BCH BTG
0 2017-10-24 5512.769492 322.941096 106.242199
1 2017-10-25 5739.145869 328.902454 111.763120
2 2017-10-26 5893.642088 335.314685 114.858331
3 2017-10-27 5761.508307 364.390464 102.277440
4 2017-10-28 5737.983387 417.587081 96.758188
In [40]:
df['index'] = pd.to_datetime(df['index'])
df.set_index('index', inplace=True)
In [41]:
df.head()
Out[41]:
BTC BCH BTG
index
2017-10-24 5512.769492 322.941096 106.242199
2017-10-25 5739.145869 328.902454 111.763120
2017-10-26 5893.642088 335.314685 114.858331
2017-10-27 5761.508307 364.390464 102.277440
2017-10-28 5737.983387 417.587081 96.758188
In [42]:
df.info()
<class 'pandas.core.frame.DataFrame'>
DatetimeIndex: 639 entries, 2017-10-24 to 2019-07-24
Data columns (total 3 columns):
BTC    639 non-null float64
BCH    639 non-null float64
BTG    639 non-null float64
dtypes: float64(3)
memory usage: 20.0 KB

We can now visualize the prices:

In [44]:
df.plot(figsize=(14, 7))
Out[44]:
<matplotlib.axes._subplots.AxesSubplot at 0x7fd3942720b8>

Utility function

I've written a small function to simplify the process of pulling the daily data, let's use it to get Ether prices:

In [17]:
from utils import get_daily_data
In [18]:
df = get_daily_data(AV_API_KEY, 'ETH')
In [19]:
df.head()
Out[19]:
1a. open (USD) 2a. high (USD) 3a. low (USD) 4a. close (USD) 5. volume 6. market cap (USD)
index
2015-08-08 3.00000 3.00000 0.15000 1.19999 1942.888147 2331.446348
2015-08-09 1.19999 1.19999 1.19999 1.19999 0.000000 0.000000
2015-08-10 1.19999 1.19999 1.19999 1.19999 0.000000 0.000000
2015-08-11 1.19999 1.19999 0.65038 0.99000 9234.568705 9142.223018
2015-08-12 0.99000 1.28800 0.90500 1.28800 1736.114983 2236.116098
In [20]:
df['4a. close (USD)'].plot(figsize=(14, 7))
Out[20]:
<matplotlib.axes._subplots.AxesSubplot at 0x7fd3973e67f0>

A simple multi-currencies experiment

With the get_daily_data it's now simple to pull multiple currencies and work them together, here's a quick example using Bitcoin (BTC), Bitcoin Cash (BCH) and Bitcoin Gold (BTG):

In [21]:
btc = get_daily_data(AV_API_KEY, 'BTC')
bch = get_daily_data(AV_API_KEY, 'BCH')
btg = get_daily_data(AV_API_KEY, 'BTG')
In [22]:
df = pd.DataFrame(index=btc.index)
In [23]:
df = pd.concat([btc['4a. close (USD)'], bch['4a. close (USD)'], btg['4a. close (USD)']], axis=1, join='inner')
In [24]:
df.columns = ['BTC', 'BCH', 'BTG']
In [25]:
df.head()
Out[25]:
BTC BCH BTG
index
2017-10-24 5512.769492 322.941096 106.242199
2017-10-25 5739.145869 328.902454 111.763120
2017-10-26 5893.642088 335.314685 114.858331
2017-10-27 5761.508307 364.390464 102.277440
2017-10-28 5737.983387 417.587081 96.758188

Plotting them:

In [26]:
df[['BTG', 'BCH']].plot(figsize=(14, 7))
Out[26]:
<matplotlib.axes._subplots.AxesSubplot at 0x7fd3974607f0>
In [27]:
df[['BTC', 'BCH']].plot(figsize=(14, 7))
Out[27]:
<matplotlib.axes._subplots.AxesSubplot at 0x7fd397371668>
In [28]:
(df['BTC'] / df['BCH']).plot(figsize=(14, 7))
(df['BCH'] / df['BTG']).plot(figsize=(14, 7))
Out[28]:
<matplotlib.axes._subplots.AxesSubplot at 0x7fd39717ac18>

Stock Prices

I started this notebook with Cryptos because it was included in guide about accessing crypto data from different APIs. But Alpha Vantage also includes Stocks:

In [29]:
resp = requests.get('https://www.alphavantage.co/query', params={
    'function': 'DIGITAL_CURRENCY_DAILY',
    'symbol': 'BTC',
    'market': 'USD',
    'apikey': AV_API_KEY
})
In [ ]:
 
Notebooks AI
Notebooks AI Profile20060