Let's say an investor at the beginning of 2016 is looking to invest in a foreign currency to realize above-average US dollar denominated returns. Which currency would be most ideal: the Japanese Yen, the Brazilian Real, the Canadian Dollar, or the Russian Ruble?
The answer is, none of the above. Surprisingly enough, the best performing currency in 2016 was the Bitcoin. This lesser known cryptocurrency grew by 126% in USD price, far outpacing its competitors as the best currency investment.
Created in October 2008, Bitcoin is a cryptographic, peer-to-peer electronic cash system. Individual coins are “mined” using open-source software to solve complex math problems; each completed computation generates one bitcoin, a unique parcel of digital property. Nearly a decade after the concept was proposed, Bitcoins trade on organized exchanges all over the world. People with digital wallets can use their "property" to buy things online, or cash out for any currency at prevailing rates through the exchanges, brokers, and individual buyers.
Bitcoin has come a long way since the days of its inception, when the exchange rate was established based on the cost of electricity to run a computer generator. In this project, we will examine the volatility of Bitcoin by looking at price of Bitcoins in USD over time (essentially, the USD conversion rate). Since Bitcoin is a crypto-currency, we will then compare Bitcoin to a number of other currencies to determine the relative volatility of Bitcoin. Since each individual bitcoin represents a parcel of digital property, it can also be thought of as a commodity; to explore that further, we will compare Bitcoin volatility to three different commodities. Finally, we will look at historical daily number of transactions to see if volatility influences the trade volume of Bitcoin.
After installing quandl
and setting up our API key, we were able to pull data directly from Quandl. We started with our basic Bitcoin historical price data set (XBT).
We then found the daily exchange rates for the Japanese Yen (JPY, Chinese Yuan(CNY), Euro(EUR), British Pound(GBP), and Canadian Dollar(CAD).
For the commodities comparison, we used Quandl to find the historical spot prices of Gold, Crude Oil, and Natural Gas.
Finally, for our last comparison we found data on Quandl for daily Bitcoin transactions.
More information on using Quandl's python package can be found here. If it does not work, see this link for troubleshooting.
Since the Bitcoin options market is relatively underdeveloped, we have decided to use historical volatility for all our currencies, as opposed to implied volatility. We define this historical volatility as the standard deviation of daily returns for the preceding 30- day window.
Quandl gave us dataframes of historical prices in USD; we then had to manipulate these prices into log returns, set up a rolling standard deviation calculation, and then multiply by 100 to give a number representing a percent standard deviation.
In [267]:
import sys
import pandas as pd
import matplotlib.pyplot as plt
import datetime as dt
import numpy as np
import seaborn as sns
import plotly
from plotly.offline import iplot, iplot_mpl
import plotly.plotly as py
import plotly.graph_objs as go
plotly.offline.init_notebook_mode(connected=True)
import cufflinks as cf
cf.set_config_file(offline=True, offline_show_link=False)
from mpl_toolkits.axes_grid1 import host_subplot
import mpl_toolkits.axisartist as AA
import quandl as qdl
quandl.ApiConfig.api_key = 'paex25b4NdoAKpmcCD1Y'
%matplotlib inline
print('Python version: ', sys.version)
print('Pandas version: ', pd.__version__)
print('Today: ', dt.date.today())
In [149]:
# Retrieve Bitcoin data from Quandl and add columns calculating log returns and standard deviation of returns.
XBT = qdl.get("BAVERAGE/USD", authtoken="paex25b4NdoAKpmcCD1Y")
XBT['pct change'] = XBT['24h Average'].pct_change()
XBT['log return'] = np.log(1 + XBT['pct change'])
XBT['30-day std'] = XBT['log return'].rolling(window=30,center=False).std()
XBT['STD %'] = pd.Series(['{0:.2f}'.format(val * 100) for val in XBT['30-day std']], index = XBT.index)
XBT
Out[149]:
In [268]:
# Graph the volatility of Bitcoin
xbt30 = pd.to_numeric(XBT['STD %'], errors='coerce')
xbt30 = xbt30['2010-7-31':'2016-10-31']
fig, ax = plt.subplots()
fig.suptitle('Bitcoin Historical Volatility', fontsize=10, fontweight='bold')
plt.style.use('seaborn-notebook')
plt.rc('font', family='serif')
xbt30.plot(ax=ax, label='XBT', lw='.7', color='#3B56B2')
ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(False)
ax.set_xlim(xbt30.index[30], xbt30.index[-1])
ax.set_ylabel('Standard Deviation of Daily Returns', fontsize=8)
ax.set_xlabel('Date', fontsize=8)
ax.set_xlim(['2010-7-31','2016-10-31'])
ax.yaxis.set_ticks_position('left')
ax.xaxis.set_ticks_position('bottom')
ax.yaxis.grid(True)
ax.legend(loc=0)
plt.show()
In [151]:
# Import dataframes from quandl
EUR = qdl.get("CUR/EUR", authtoken="paex25b4NdoAKpmcCD1Y")
GBP = qdl.get("CUR/GBP", authtoken="paex25b4NdoAKpmcCD1Y")
CNY = qdl.get("CUR/CNY", authtoken="paex25b4NdoAKpmcCD1Y")
JPY = qdl.get("CUR/JPY", authtoken="paex25b4NdoAKpmcCD1Y")
CAD = qdl.get("CUR/CAD", authtoken="paex25b4NdoAKpmcCD1Y")
In [152]:
# Write a function to extract the 30-day standard deviation and appropriate time frame.
def STD(VAR):
'''Create additional columns in dataframe to find 30-day STD'''
VAR['pct change'] = VAR.iloc[:, 0].pct_change()
VAR['log return'] = np.log(1 + VAR['pct change'])
VAR['30-day std'] = VAR['log return'].rolling(window=30,center=False).std()
VAR['STD %'] = pd.Series(['{0:.2f}'.format(val * 100) for val in VAR['30-day std']], index = VAR.index)
var30 = pd.to_numeric(VAR['STD %'], errors='coerce')
var30 = var30['2010-7-31':'2016-10-31']
return var30
# Apply to all the currencies to be compared
eur30 = STD(EUR)
gbp30 = STD(GBP)
cny30 = STD(CNY)
jpy30 = STD(JPY)
cad30 = STD(CAD)
In [279]:
# Create graph with volatility of all currencies
trace_xbt30 = go.Scatter(
y=XBT['STD %'],
x=XBT.index,
name = "XBT",
line = dict(
color = ('rgb(150, 150, 255)'),
width = 1)
)
trace_eur30 = go.Scatter(
y=EUR['STD %'],
x=EUR.index,
name = "EUR",
line = dict(
color = ('rgb(0, 250, 0)'),
width = 1)
)
trace_gbp30 = go.Scatter(
y=GBP['STD %'],
x=GBP.index,
name = 'GBP',
line = dict(
color = ('rgb(250, 150, 250)'),
width = 1)
)
trace_cny30 = go.Scatter(
y=CNY['STD %'],
x=CNY.index,
name = 'CNY',
line = dict(
color = ('rgb(230, 100, 140)'),
width = 1)
)
trace_jpy30 = go.Scatter(
y=JPY['STD %'],
x=JPY.index,
name = 'JPY',
line = dict(
color = ('rgb(0, 230, 170)'),
width = 1)
)
trace_cad30 = go.Scatter(
y=CAD['STD %'],
x=CAD.index,
name = 'CAD',
line = dict(
color = ('rgb(230, 230, 0)'),
width = 1)
)
layout = dict(width=800, height = 600,
xaxis = dict(
range = ['2010-01-01','2017-05-04'],
title = 'Date',
titlefont=dict(
family='Serif',
size=12,
color='#000000'),
zeroline = False,
gridcolor='#ffffff',
gridwidth = 2),
yaxis = dict(
zeroline = False,
gridcolor='#ffffff',
gridwidth = 2,
title = '30-Day Standard Deviation of Daily Returns',
titlefont=dict(
family='Serif',
size=12,
color='#000000')),
title = 'Historical Volatility of Exchange Rates',
titlefont=dict(
family='Serif',
size=16,
color='#000000'),
plot_bgcolor ='rgba(235,235,242,150)',
showlegend=False,
font=dict(family='Serif', size=12))
fig = go.Figure(data=[trace_xbt30, trace_eur30, trace_gbp30, trace_cad30,
trace_jpy30,trace_cny30],layout=layout)
iplot(fig)
The graph above clearly shows how much more volatile Bitcoin is compared to other currencies. The only currency that at any point came close to replicating the large shifts in standard deviation exhibited by Bitcoin was the Sterling after Brexit was announced in mid-2016. It is also important to note, however, that Bitcoin's average volatility has been decreasing since its inception. This trend, if it continues over the next decade, points to the possibility of Bitcoin stabilizing in the future.
In [269]:
# Import dataframes from quandl
OIL = qdl.get("EIA/PET_RBRTE_D", authtoken="paex25b4NdoAKpmcCD1Y")
GOLD = qdl.get("BUNDESBANK/BBK01_WT5511", authtoken="paex25b4NdoAKpmcCD1Y")
GAS = qdl.get("ODA/PNGASUS_USD", authtoken="paex25b4NdoAKpmcCD1Y")
# Apply STD function to all the commodities to be compared
oil30 = STD(OIL)
gold30 = STD(GOLD)
gas30 = STD(GAS)
In [278]:
# Create graph with volatility of all currencies
trace_gold30 = go.Scatter(
y=GOLD['STD %'],
x=GOLD.index,
name = 'GOLD',
line = dict(
color = ('rgb(255, 100, 130)'),
width = 1)
)
trace_gas30 = go.Scatter(
y=GAS['STD %'],
x=GAS.index,
name = 'GAS',
line = dict(
color = ('rgb(230, 230, 0)'),
width = 1)
)
trace_oil30 = go.Scatter(
y=OIL['STD %'],
x=OIL.index,
name = 'OIL',
line = dict(
color = ('rgb(0, 255, 0)'),
width = 1)
)
layout = dict(width=800, height = 600,
xaxis = dict(
range = ['2010-01-01','2017-05-04'],
title = 'Date',
titlefont=dict(
family='Serif',
size=12,
color='#000000'),
zeroline = False,
gridcolor='#ffffff',
gridwidth = 2),
yaxis = dict(
zeroline = False,
gridcolor='#ffffff',
gridwidth = 2,
title = '30-Day Standard Deviation of Daily Returns',
titlefont=dict(
family='Serif',
size=12,
color='#000000')),
title = 'Historical Volatility of Commodities',
titlefont=dict(
family='Serif',
size=16,
color='#000000'),
plot_bgcolor ='rgba(235,235,242,190)',
showlegend=False,
font=dict(family='Serif', size=12))
fig = go.Figure(data=[trace_xbt30, trace_oil30, trace_gas30, trace_gold30],layout=layout)
iplot(fig)
As the graph shows, Bitcoin's level of volatility is indeed more similar to that of commodities. Most interestingly is that as Bitcoin's volatility has decreased in the past two years, the volatilities of Gas and Oil have actually increased over the same time frame. Gas prices exhibit the highest average volatility, but this can be explained by the low nominal prices (hovering at around 1 to 4 USD) which result in higher percentage changes, higher log returns, and higher standard deviation.
In [255]:
# Import dataframes from quandl
TXN = qdl.get("BCHAIN/NTRAN", authtoken="paex25b4NdoAKpmcCD1Y")
# Graph the transactions
TXN.columns = ['Trade Volume']
txn = TXN['2010-7-31':'2016-10-31']
fig, ax = plt.subplots()
fig.suptitle('Bitcoin Historical Daily Transaction Volume', fontsize=10, fontweight='bold')
plt.style.use('seaborn-notebook')
plt.rc('font', family='serif')
TXN.plot(ax=ax, label='Transactions', lw='.7', color='#8AA2F2')
ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(False)
ax.set_xlim(xbt30.index[30], xbt30.index[-1])
ax.set_ylabel('Number of Transactions', fontsize=8)
ax.set_xlabel('Date', fontsize=8)
ax.set_xlim(['2010-7-31','2016-10-31'])
ax.yaxis.set_ticks_position('left')
ax.xaxis.set_ticks_position('bottom')
ax.yaxis.grid(True)
ax.legend(loc=0)
plt.show()
In [275]:
# Creating a double y-axis graph to graph both the transaction volume and volatility for comparison.
host = host_subplot(111, axes_class=AA.Axes)
plt.subplots_adjust(right=0.75)
par1 = host.twinx()
host.set_title('Volatility and Transaction Volume', fontsize=10, fontweight='bold')
host.set_ylim(0, 18)
host.set_xlabel('Date')
host.set_ylabel('30-Day Standard Deviation')
par1.set_ylabel('Number of Transactions')
p1, = host.plot(xbt30, label='Standard Deviation', lw='.7', color='#3B56B2')
p2, = par1.plot(txn, label='Transactions', lw='.7', color='#8AA2F2')
par1.set_ylim(0, 350000)
host.legend()
host.axis["left"].label.set_color(p1.get_color())
par1.axis["right"].label.set_color(p2.get_color())
plt.draw()
plt.show()
As we can see from the graph, the number of transactions has been increasing rapidly overall. From 2013 to 2014, we can see that at the height of Bitcoin volatility, number of transactions appeared to experience a slight dip in the overall trend. Looking at the entire timeframe, the increasing number of Bitcoin transactions may be a contributing factor to why the volatility of Bitcoin has decreased since its inception.
Volatility is a measure of how much the price of an asset varies over time. The significance of looking at volatility as that it shows how risky it is to hold an asset by indicating how substantially the asset's value may go up or down on any given day. The significance of examining Bitcoin's volatility, is that it can be used as a proxy for determining how risky the market perceives Bitcoin to be.
As we can see from the graph of Bitcoin 30-day standard deviation alone, it looks like Bitcoin has only two phases; risky, and riskier. This becomes even more apparent in the comparison to established currencies; even at it's lowest volatilities, Bitcoin is almost always (much) more volatile than all other currencies. Other major currencies average between 0.5% and 1.0%.
Bitcoin's volatility makes it more like a commodity than a currency. Relative to gold and other commodities, Bitcoin's volatility looks a little more fitting, especially post-2015 where Bitcoin's decreasing volatility and Oil's increasing volatility make the two much more similar, although they seem to be moving in opposite directions. Natural gas was unexpectedly high in average volatility, hovering at around 10%-15%. For comparison, the volatility of gold averages around 1.2%.
Generally, the more volatile an asset, the more people will want to limit their exposure to it, either by simply not holding it or by hedging. We wanted to see if this was reflected in the number of daily transactions; at times of higher bitcoin volatility, there was some indication of corresponding falling number of daily transactions. This shows that as Bitcoin enters a period of being riskier, the volume of Bitcoin trading transactions does indeed decrease.
Over each of the past four years, Bitcoin has been either the best, or worst performing currency; returning to our investor at the start of our report, while it may have been advisable for him to invest in 2015 and 2016 and even 2013, he may have lost a great deal of money had he invested in 2014. Even though such high returns were realized at the end of the year, Bitcoin is a highly volatile product, as we've uncovered. While Bitcoin looks to be stabilizing in the future, it still experiences huge jumps and falls in price.
Assets with higher degrees of volatility tend to attract active traders rather than investors. Bitcoin investing may be profitable, but it could also be heart-attack inducing. A much better option to profit off of Bitcoin could involve speculation, or short-term trading activity yielding opportunity for gain in the immediate future. Investors looking for steady earnings should probably direct their efforts elsewhere, despite the yield on Bitcoin.
A possible future comparison could be Bitcoin prices to stock prices and bond prices. This could include looking at bitcoin against large-cap, mid-cap, and small-cap stocks, or bonds of different ratings.
If Bitcoin volatility decreases, the cost of converting into and out of Bitcoin will decrease as well.This hypothesis could be tested by creating a comparison graph analyzing the cost of Bitcoin transactions.
As Bitcoin data continues to be gathered and updated, it will be interesting to explore whether or not Bitcoin's downward trend in volatility is sustained.
In [ ]: