Skip to content

'Neither too much, nor too little, but just right'. A portfolio assessment on the Goldie-locks of Bitcoin

knitr::opts_chunk$set(message = FALSE, warning = FALSE, echo = FALSE)

Recommendations

  • In a non-traditional fashion, Bitcoin appears to take the elevator down and the elevator back up when it comes to stock-market performance,
  • Therefore, we recommend the Glodie-locks portfolio for the company, with shares approximately at 60% in US gold, 35% in the S&P 500 and 5% in Bitcoin,
  • This amount leads to highest returns per unit of risk, relative to holding little to none, despite the increase in overall portfolio volatility,
  • We believe that Bitcoin will also be a suitable hedge for inflation given the associated high returns it yields,
  • It's also important to maintain a high portfolio weight in gold, as this appears to naturally hedge against some of the downside risk that comes with holding Bitcoin,
  • And although the nature of the asset is highly volatile with large down-side risks, diversification still remains a better strategy for reducing overall portfolio risk-return, than putting all the eggs in one basket.
install.packages(c("PerformanceAnalytics", "quantmod", "tseries", "PortfolioAnalytics"))

library(tidyverse)
library(xts)
library(PerformanceAnalytics)
library(quantmod)
library(tseries)
library(PortfolioAnalytics)
library(kableExtra)

# 
# bitcoin <- readr::read_csv('./data/bitcoin-usd.csv')
# sp500 <- readr::read_csv('./data/sp500.csv')
# monthly_data <- readr::read_csv('./data/monthly_data.csv')

monthly_xts <-  as.xts(read.zoo('./data/monthly_data.csv', sep = ",", header = TRUE))
bitcoin_xts <-  as.xts(read.zoo('./data/bitcoin-usd.csv', sep = ",", header = TRUE))
sp500_xts <-  as.xts(read.zoo('./data/sp500.csv', sep = ",", header = TRUE))

Potfolio analysis

When selecting the amount of Bitcoin to invest in, we need to find a balance in the expectation of gains vs. the risk of losses. We can reduce the risks of suffering large losses via two simple methods.

  1. Carefully selecting a diversified portfolio and avoid investing in one single investment can reduce risk and increase returns,
  2. Use back testing to test the portfolio analysis.

## plot data - check if anything weird is going on (e.g. missing vals)  - looks fine
##
  plot.zoo(Cl(bitcoin_xts), main = "Close price Bitcoin")
  plot.zoo(Cl(sp500_xts), main = "Close price S&P 500")
  plot.zoo(monthly_xts[,1], main = "USD GOLD")
  plot.zoo(monthly_xts[,2], main = "US CPI")
  
## Show the value of sp500 and bitcoin value of close prices over time
  bit_sp500 <- Cl(bitcoin_xts) / Cl(sp500_xts)
  plot.zoo(bit_sp500, abline( h = 1), main = "Bitcoin / S&P500")
  
## aggregate to monthly to compare with gold and US CPI
##
  sp500_month <- to.period(sp500_xts, period = "months", indexAt = "firstof")
  bitcoin_month <- to.period(bitcoin_xts, period = "months", indexAt = "firstof")
  

Firstly, the figures above show how dips in each equity occurring at different time points, but a general upwards trend in close prices.

Secondly, the final figure above shows the close prices of S&P500 against Bitcoin. Despite Bitcoin outstripping the value of SP 500, it's wise to invest in both assets that generates solid returns whilst mitigating loss. To do this, we need to understand the inherent risk associated with each equity and their return performance. This information which will guide the constraints we want to set in order to optimize a risk-off portfolio for the company.

To decide how much Bitcoin we want in the portfolio we need to define the portfolio weights and their returns:

  • Weights tell you the percentage of total value invested into each asset
  • returns measure relative increase over the period

A general stratergy for weight selections over time

In general, there a three ways to think about setting weights:

  1. Betting on 1 Asset - speculative and likely to be inefficient,
  2. Equal weights - perfect diversification of assets in each risky asset (if assets are similar in terms of risk and reward),
  3. Weights proportional to the market value to the assets, over-weighting stocks of big firms an under-weighting stocks of small firms.

However, to avoid extreme losses, 'don't put all your eggs into one basket', that is - a portfolio made up of only the S&P500 or Bitcoin or US gold. Further from this, we need to consider how to manage returns over time.

As the values of assets change over time, you can either be a passive investor and not trade any further; this is called the buy and hold strategy. Or to buy and trade at the close of each day, month, quarter or year. This process results in re-balancing a portfolio, such that the portfolio is re-weighted correctly to reflect the desired proportional amount of each asset.

Portoflio Perofrmance

Returns and the Sharpe ratio

## over-time returns with PerformanceAnalytics
##
 returns <- Return.calculate(merge(monthly_xts[,1], Cl(bitcoin_month), Cl(sp500_month)))[(-1),]

  names(returns) <- c("gold_usd", "Bitcoin", "SP500")
  plot.zoo(returns)

  #returns <- Return.calculate(merge(monthly_xts[,1], Cl(bitcoin_month), Cl(sp500_month)))[(-1),]
  
#   weights_val <- c(0.4,0.1,0.5)
# ## Weights over time
# ##
#  pf_ret <- Return.portfolio(returns, weights = weights_val,
                               # rebalance = "months", verbose = TRUE)

Portfolio performance is used make predictions about the past and future performance of any given portfolio. To do this, we need consider the performance of risks and rewards for each equity (portfolio volatility, and mean return). Portfolio volatility is the de-meaned return -that is, how much it varies from the mean. The higher the volatility the higher the probability of positive and/or negative returns occurring for a given time period.

The S&P 500 is generally considered the most important benchmark portfolio for investors in stocks. To interpret these numbers we need a benchmark to compare with - typically a risk free asset such as the TSY bill. And because there is no risk - the expected return itself is called the risk free rate. The difference between the risk-free-rate (asset) and the risky portfolio is called the excess Return of Risky Portfolio, and it tells us that how much additional return you can expect on the portfolio compared to the risk free rate.

Using the excess return and volatility in combinations gives us the Sharpe ratio, which shows the return per unit of risk taken. The higher the ratio is the more return your portfolio gets, for the same per unit of risk.


## Sharpe ratio - the excess return /  standard deviation
barplot(StdDev.annualized(returns), main = "Shapre Ratio for each equity")

# typically we look at the annualized performance of these stocks to see what investment looks like over a 1 year horizon. assuming risk-free rate of 0

df <- table.AnnualizedReturns(returns)


kable(df) %>% 
  kable_styling(bootstrap_options = c("striped", "hover", "condensed"))

Rolling estimation of returns

We also need to consider the rolling estimation of returns within out portfolio, which is using the K most recent values to help inform us of the business cycle and market direction. These are persistent periods of calm and/or stress in the market. Therefore, current performance is better estimated when we give more weight to recent observations than to the distant observations, as it captures the current business cycle.

We pick a window length that's large enough to reduce the noise of the market, but the longer the window is the more it smooths over the highs and lows and thereby becoming less informative of the current market conditions. This is down to personal preference, and we believe it's best to go with a 1 year rolling estimation.

The plots below show the rolling annualized returns, standard deviations (volatility) and the Sharpe ratio for S&P 500, Bitcoin and US Gold. This reveals both how volatile Bitcoin is, as well as how high the returns can be. It also reveals, the continually changing behavior's of the equities within the market, and how the Sharpe ratio changes over time.

## one year window
chart.RollingPerformance(R = returns, width = 12, FUN = "Return.annualized", legend.loc = "topleft", colorset = rich8equal, lwd = 2, main = "Rolling 12-Month Returns")

chart.RollingPerformance(R = returns, width = 12, FUN = "StdDev.annualized", legend.loc = "topleft", colorset = rich8equal, lwd = 2, main = "Rolling 12-Month Volatility")

chart.RollingPerformance(R = returns, width = 12, FUN = "SharpeRatio.annualized", Rf = 0, legend.loc = "topleft",colorset = rich8equal, lwd = 2, main = "Rolling 12-Month Sharpe Ratio")

Measring porfolio risk to returns

Non-normal returns and downside risk

If Portfolio returns have a normal distribution and the density function is bell shaped this means it's symmetric and gains and losses occur in equal amounts. However, this isn't typical of most stocks, which have longer fatter tails at negative values. We also use the skewness and kurtosis (symmetry and tail fatness) of the distribution to inform on risk. Left-skewed means that more negative values occurs more often than large positive returns (long left tail).Fat tails are a cause of non-normality, which means fatter-tails are a sign of larger extreme values occurring in the distribution. Non-normal returns are often skewed to the left, and more extreme negative values happen than what one would expect under a normal distribution. The s.d is not enough of a measure for volatility.

There are other measures - such as the value at risk and expected shortfall (at 5%), as a way of capturing the inherent risk in each equity. To explain, the value at risk quantifies the risk of the 5% most extreme losses - 5% value at risk are returns that are so extremely negative, there is a 5% change of observing a return that is even more negative. We can compute the value of the 5% most negative returns - thus giving the 5% expected shortfall.

Using the below information we can infer that:

  • Bitcoin presents the most symmetric distribution, but these gains and losses come in a larger magnitude,
  • Bitcoin has the highest downside risk, largest drawdowns, and loss Deviation, compared to the three other equities,
  • However, Bitcoin has also seen the highest market returns compared to the other equities.
  • US Gold is the least volatile equity of the three, but also presents the lowest returns.
  • The S&P 500 performance is the best, with relatively low volatility and modest returns.

## subset to look at the latest year of daily bitcoin  & S&P 500 returns
##
  returns_lastyr <-  Return.calculate(last(Cl(bitcoin_xts), n = 365))[-c(1),]
  returns_lastyr_sp <-  Return.calculate(last(Cl(sp500_xts), n = 365))[-c(1),]
  returns_lastyr_gd <-  Return.calculate(last(monthly_xts[,1], n = 365))[-c(1),]
  names(returns_lastyr) <- "Bitcoin"
  names(returns_lastyr_sp) <- "S&P 500"
  names(returns_lastyr_gd) <- "Gold, USD"
  chart.Histogram(returns_lastyr, methods = c("add.density", "add.normal"))
  chart.Histogram(returns_lastyr_sp, methods = c("add.density", "add.normal"))
  chart.Histogram(returns_lastyr_gd, methods = c("add.density", "add.normal"))
  
## more compactly put below
##
  
risk_tbl <- table.DownsideRisk(returns)



kable(risk_tbl) %>% 
  kable_styling(bootstrap_options = c("striped", "hover", "condensed"))
#table.Drawdowns(returns)
chart.Drawdown(returns, legend.loc =3)