Skip to content

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:

  1. How does the performance of Bitcoin compare to the S&P 500 and the price of gold?
  2. 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?
  3. 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

CATEGORYWEIGHTINGDETAILS
Recommendations35%
  • Clarity of recommendations - how clear and well presented the recommendation is.
  • Quality of recommendations - are appropriate analytical techniques used & are the conclusions valid?
  • Number of relevant insights found for the target audience.
Storytelling30%
  • How well the data and insights are connected to the recommendation.
  • How the narrative and whole report connects together.
  • Balancing making the report in depth enough but also concise.
Visualizations25%
  • Appropriateness of visualization used.
  • Clarity of insight from visualization.
Votes10%
  • Up voting - most upvoted entries get the most points.

βœ… 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_preview
import 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.

β€Œ
β€Œ
β€Œ