Unlocking Cryptocurrency Insights: The Power of Log Returns
Previously, we dove into the unfiltered world of cryptocurrency price changes. However, one major hurdle with that approach is the dearth of a standard scale to match different cryptocurrencies. This time around, let’s explore how using log returns can offer a more standardized and insightful evaluation of price dynamics. You may grab the accompanying Jupyter Notebook for a hands-on experience with the info.
Discover More
If you missed my previous articles on this topic:
Stock Market Analysis in Python
What You’ll Need
For additional requirements, take a look at the primary post on this series.
Getting Started: Load Your Data
First things first, let’s load our cryptocurrency data:
import pandas as pd df_btc = pd.read_csv('BTC_USD_Coinbase_hour_2017-12-24.csv', index_col='datetime') df_eth = pd.read_csv('ETH_USD_Coinbase_hour_2017-12-24.csv', index_col='datetime') df_ltc = pd.read_csv('LTC_USD_Coinbase_hour_2017-12-24.csv', index_col='datetime') df = pd.DataFrame({'BTC': df_btc.close, 'ETH': df_eth.close, 'LTC': df_ltc.close}) df.index = df.index.map(pd.to_datetime) df = df.sort_index() df.head()
By specializing in returns fairly than raw prices, we normalize the values, making it easier to match and analyze different variables—something that is quite necessary if you’re coping with datasets of various scales. For more on why log returns are effective, take a look at “Why Log Returns.”
Defining Returns
Let’s break down returns and their significance:
Calculating Log Returns
The writer of “Why Log Returns” highlights several advantages of using log returns over easy returns. Now, we’ll transform the usual returns equation right into a log returns equation:
Let’s apply this transformation to our cryptocurrency closing prices:
import numpy as np # shift moves dates back by 1 df_change = df.apply(lambda x: np.log(x) - np.log(x.shift(1))) df_change.head()
Visualizing Log Returns
Let’s bring our data to life by plotting the normalized changes in closing prices during the last 50 hours. Log differences may be interpreted as percentage changes.
df_change[:50].plot(figsize=(15, 10)).axhline(color='black', linewidth=2)
Is Litecoin Price Log-Normally Distributed?
If we assume prices follow a log-normal distribution, then log(1+ri) is conveniently normally distributed. Let’s visualize the distribution of Litecoin’s hourly closing prices. We’ll also overlay a log-normal distribution estimate.
from scipy.stats import lognorm import matplotlib.pyplot as plt fig, ax = plt.subplots(figsize=(10, 6)) values = df['LTC'] shape, loc, scale = stats.lognorm.fit(values) x = np.linspace(values.min(), values.max(), len(values)) pdf = stats.lognorm.pdf(x, shape, loc=loc, scale=scale) label = 'mean=%.4f, std=%.4f, shape=%.4f' % (loc, scale, shape) ax.hist(values, bins=30, normed=True) ax.plot(x, pdf, 'r-', lw=2, label=label) ax.legend(loc='best')
Are Litecoin Log Returns Normally Distributed?
Next, let us take a look at the distribution of Litecoin log returns. We’ll estimate the parameters for a standard distribution and plot it for comparison.
import pandas as pd import numpy as np import scipy.stats as stats import matplotlib.pyplot as plt values = df_change['LTC'][1:] # skip first NA value x = np.linspace(values.min(), values.max(), len(values)) loc, scale = stats.norm.fit(values) param_density = stats.norm.pdf(x, loc=loc, scale=scale) label = 'mean=%.4f, std=%.4f' % (loc, scale) fig, ax = plt.subplots(figsize=(10, 6)) ax.hist(values, bins=30, normed=True) ax.plot(x, param_density, 'r-', label=label) ax.legend(loc='best')
Exploring Pearson Correlation with Log Returns
Let’s dive into the Pearson correlation calculated from log returns. The correlation matrix below is comparable to findings from Sifr Data. Note:
- Bitcoin and Ethereum have a moderate positive correlation.
- Litecoin and Ethereum show a powerful positive relationship.
import seaborn as sns import matplotlib.pyplot as plt # Compute the correlation matrix corr = df_change.corr() # Generate a mask for the upper triangle mask = np.zeros_like(corr, dtype=np.bool) mask[np.triu_indices_from(mask)] = True # Set up the matplotlib figure f, ax = plt.subplots(figsize=(10, 10)) # Draw the heatmap with the mask and proper aspect ratio sns.heatmap(corr, annot=True, fmt = '.4f', mask=mask, center=0, square=True, linewidths=.5)
Wrapping Up
We’ve illustrated the way to compute log returns from raw price data, thereby normalizing prices for easier evaluation. Additionally, we demonstrated the way to estimate parameters for each normal and log-normal distributions. Curious for more? Let’s connect!
Stay Connected
Let’s chat: Book a call
Follow me: YouTube 🎥 | LinkedIn | Twitter
Explore code: GitHub
Image Credit: towardsdatascience.com