Should your fund invest in Bitcoin?
π Background
You work as an analyst at an investment fund in New York. Your CFO wants to explore if it is a good idea to invest some of the fund's assets in Bitcoin. You have to prepare a report on this asset and how it compares to the stock market in general.
πΎ The data
You have access to three files:
Bitcoin daily data in US dollars
- "date" - date from September 17, 2014 to November 17, 2021
- "open" - the price at the beginning of the trading day
- "high" - the highest price reached that day
- "low" - the lowest price reached that day
- "close" - the price at the closing of the trading day
- "volume" - how many Bitcoin were traded that day
S&P 500 daily data
- "date" - date from September 17, 2014 to November 17, 2021
- "open" - the index level at the beginning of the trading day
- "high" - the highest level reached that day
- "low" - the lowest level reached that day
- "close" - the level at the closing of the trading day
- "volume" - how many shares in the companies that make up the index were traded that day
inflation and gold as monthly data
- "date" - date from September, 2014 to November, 2021
- "gold_usd" - price in usd of gold for that month
- "cpi_us" - the inflation index for the US for that month (cpi = consumer price index)
CPI data from the U.S. Bureau of Labor Statistics. Publicly available information.
import pandas as pd
bitcoin = pd.read_csv('./data/bitcoin-usd.csv', parse_dates=['date'])
bitcoin.head()sp500 = pd.read_csv('./data/sp500.csv', parse_dates=['date'])
sp500.head()monthly_data = pd.read_csv('./data/monthly_data.csv', parse_dates=['date'])
monthly_data.head()πͺ Competition challenge
Create a report that covers the following:
- How does the performance of Bitcoin compare to the S&P 500 and the price of gold?
- Analyze Bitcoin's returns and volatility profile. Do you believe it could help improve the performance of a portfolio? Do you believe Bitcoin could be used as a hedge versus inflation?
- The CFO is looking to lower volatility in the fund. Explore building a portfolio using some or all of these assets. Make a recommendation that minimizes overall risk.
π§ββοΈ Judging criteria
| CATEGORY | WEIGHTING | DETAILS |
|---|---|---|
| Recommendations | 35% |
|
| Storytelling | 30% |
|
| Visualizations | 25% |
|
| Votes | 10% |
|
β
Checklist before publishing into the competition
- Rename your workspace to make it descriptive of your work. N.B. you should leave the notebook name as notebook.ipynb.
- Remove redundant cells like the judging criteria so the workbook is focused on your story.
- Make sure the workbook reads well and explains how you found your insights.
- Check that all the cells run without error.
βοΈ Time is ticking. Good luck!
# Prepare daily data for Bitcoin and S&P 500
# Calculate daily returns using the closing price
bitcoin['btc_return'] = bitcoin['close'].pct_change()
sp500['sp500_return'] = sp500['close'].pct_change()
# Prepare monthly data for Gold and CPI (inflation)
# Calculate monthly gold return and monthly inflation change
monthly_data['gold_return'] = monthly_data['gold_usd'].pct_change()
monthly_data['inflation_rate'] = monthly_data['cpi_us'].pct_change()
# Preview the data after adding returns
bitcoin_returns_preview = bitcoin[['date', 'close', 'btc_return']].head()
sp500_returns_preview = sp500[['date', 'close', 'sp500_return']].head()
monthly_data_preview = monthly_data[['date', 'gold_usd', 'gold_return', 'cpi_us', 'inflation_rate']].head()
bitcoin_returns_preview, sp500_returns_preview, monthly_data_previewimport matplotlib.pyplot as plt
# Cumulative returns for Bitcoin and S&P 500 (daily)
bitcoin['btc_cum_return'] = (1 + bitcoin['btc_return']).cumprod()
sp500['sp500_cum_return'] = (1 + sp500['sp500_return']).cumprod()
# Cumulative returns for Gold (monthly)
monthly_data['gold_cum_return'] = (1 + monthly_data['gold_return']).cumprod()
# Plot cumulative returns for daily assets
plt.figure(figsize=(12, 6))
plt.plot(bitcoin['date'], bitcoin['btc_cum_return'], label='Bitcoin')
plt.plot(sp500['date'], sp500['sp500_cum_return'], label='S&P 500')
plt.title('Cumulative Returns: Bitcoin vs S&P 500')
plt.xlabel('Date')
plt.ylabel('Cumulative Return (Base = 1)')
plt.legend()
plt.grid(True)
plt.show()
# Plot cumulative returns for gold (monthly)
plt.figure(figsize=(12, 6))
plt.plot(monthly_data['date'], monthly_data['gold_cum_return'], label='Gold')
plt.title('Cumulative Returns: Gold')
plt.xlabel('Date')
plt.ylabel('Cumulative Return (Base = 1)')
plt.legend()
plt.grid(True)
plt.show()
# Calculate rolling 30-day volatility (standard deviation of returns)
bitcoin['btc_volatility'] = bitcoin['btc_return'].rolling(window=30).std() * (252 ** 0.5) # Annualized
sp500['sp500_volatility'] = sp500['sp500_return'].rolling(window=30).std() * (252 ** 0.5) # Annualized
# Plot rolling volatility
plt.figure(figsize=(12, 6))
plt.plot(bitcoin['date'], bitcoin['btc_volatility'], label='Bitcoin Volatility')
plt.plot(sp500['date'], sp500['sp500_volatility'], label='S&P 500 Volatility')
plt.title('30-Day Rolling Annualized Volatility: Bitcoin vs S&P 500')
plt.xlabel('Date')
plt.ylabel('Volatility (Annualized Std Dev)')
plt.legend()
plt.grid(True)
plt.show()
# Compute summary volatility stats
volatility_df = pd.DataFrame({
'Asset': ['Bitcoin', 'S&P 500'],
'Mean Daily Return': [bitcoin['btc_return'].mean(), sp500['sp500_return'].mean()],
'Std Dev of Daily Return': [bitcoin['btc_return'].std(), sp500['sp500_return'].std()],
'Annualized Volatility': [bitcoin['btc_return'].std() * (252 ** 0.5),
sp500['sp500_return'].std() * (252 ** 0.5)]
})
volatility_df.set_index('Asset', inplace=True)
volatility_df = volatility_df.round(4)
print(volatility_df)
Bitcoin has significantly higher returns and volatility. Its annualized volatility is around 62%, compared to 18% for the S&P 500. This suggests potential as a growth asset, but it introduces much more risk.
# We'll take the last closing price of each month to calculate monthly returns
bitcoin_monthly = bitcoin.set_index('date').resample('M').last().copy()
sp500_monthly = sp500.set_index('date').resample('M').last().copy()
# Calculate monthly returns
bitcoin_monthly['btc_return'] = bitcoin_monthly['close'].pct_change()
sp500_monthly['sp500_return'] = sp500_monthly['close'].pct_change()
# Reset indices and extract year-month from dates for consistent merging
monthly_data['year_month'] = monthly_data['date'].dt.to_period('M')
bitcoin_monthly['year_month'] = bitcoin_monthly.index.to_period('M')
sp500_monthly['year_month'] = sp500_monthly.index.to_period('M')
# Prepare datasets for merging
monthly_merged = monthly_data[['year_month', 'gold_return', 'inflation_rate']]
monthly_merged = monthly_merged.merge(
bitcoin_monthly[['year_month', 'btc_return']],
on='year_month',
how='inner'
)
monthly_merged = monthly_merged.merge(
sp500_monthly[['year_month', 'sp500_return']],
on='year_month',
how='inner'
)
# Drop rows with missing values
monthly_merged.dropna(inplace=True)
# Calculate correlation matrix
correlation_matrix = monthly_merged[['btc_return', 'gold_return', 'sp500_return', 'inflation_rate']].corr()
correlation_matrix.round(3)Bitcoin is weakly correlated with all other variables,a sign of potential diversification benefit. Gold has a slightly negative relationship with both Bitcoin and inflation. Inflation is essentially uncorrelated with all three assets in this period.
This supports the idea that Bitcoin behaves quite independently β possibly useful for portfolio diversification, though not clearly an inflation hedge.
β
β