Somebody recently mentioned to me that Bitcoin had passed through $2,500 earlier this month. Knowing I had most recently purchased Bitcoin at around $235 dollars in January 2015, I was a little disappointed at missing out on a 10x return over 2.5 years. Yes, I had spent my Bitcoin soon after buying.

Since that time 2.5 years ago, more cryptocurrencies have been invented and gained adoption within the cryptocurrency community. Some of the new protocols build upon the original Bitcoin protocol, while others take a novel approach. In a Gold Rush–esque panic, people are trying to figure out what they should do. Should they be putting their money into cryptocurrencies?

I happen to think that cryptocurrencies are not a good long-term investment. If I were to invest any money into Bitcoin and the like, I would keep my investment to a very small proportion of my wealth. By all means, buy and spend cryptocurrencies. But know that the price is driven by hype and mania, as much as it is driven by trade.

Nonetheless, I have been thinking about how I might invest my money into a portfolio of cryptocurrencies. Since there are now 7 cryptocurrencies with market capitalizations greater than $1 billion, according to CoinCap.io, it makes sense to have a broad exposure to minimize risk. I could invest on a cap-weighted basis, although I am interested to see what Modern Portfolio Theory tells me about the ideal portfolio.

## Modern Portfolio Theory

Modern Portfolio Theory (MPT) is a technique that sets the weights of assets in a portfolio such that the portfolio risk is minimized for a given level of expected return. It exploits the fact that, assuming risk is measured by the variance of returns over time and the returns are not perfectly positively correlated, it is possible to combine the assets to reduce the variance.

The math behind MPT is fairly simple. We define w to be a vector of weights w_{1}, …, w_{n} for n assets in a portfolio. These weights should sum to 1 and we can constrain w_{i} to the range [0, 1], although more generally we could relax this constraint if short positions are allowed. It is the aim of MPT to optimize the weight vector w.

A vector R contains the expected returns for each asset R_{1}, …, R_{n}. These expected returns could be based on the historical returns for each asset, although it is often sensible (in my view) to fix the expected returns within each asset class (e.g. government bonds, large-cap equities or cryptocurrencies).

The final ingredient is the returns covariance matrix Σ. This matrix is typically calculated by observing the daily, weekly or monthly returns over some extended period of time. The covariance matrix is important because the portfolio variance is calculated as w^{T}Σw, and it is the portfolio variance that MPT minimizes where the portfolio return R^{T}w is fixed to some value r: min(R_{i}) <= r <= max(R_{i}).

## Cryptocurrencies

To apply MPT to cryptocurrencies like Bitcoin, we need data on the historical returns of the currencies. Fortunately, CoinCap.io has a simple API that gives us data as far back as August 2013. I wrote a small R script to fetch the data for Bitcoin, Ethereum and Litecoin and combine it into a single CSV file. The data for Ethereum starts in August 2015.

library(RJSONIO) library(RCurl) library(anytime) coins <- c("BTC", "ETH", "LTC") globalData <- NULL for (coin in coins) { url <- paste( "http://socket.coincap.io/history/", coin, sep="" ) rawData <- getURL(url) data <- fromJSON(rawData) pricesData <- as.data.frame( matrix(unlist(data$price), ncol=2, byrow=T) ) names(pricesData) <- c("date", "price") pricesData$date <- anydate( as.numeric(pricesData$date)/1000 ) pricesData$coin <- coin globalData <- rbind(globalData, pricesData) } write.csv(globalData, "data.csv", row.names=F)

To start, we can simply plot the prices of the 3 cryptocurrencies – BTC, ETH and LTC – over time. It is interesting to see that the prices of these cryptocurrencies were fairly stable (relatively speaking) throughout 2016 and the start of this year. Only recently have the prices burst upwards, not dissimilar from the spike in Bitcoin prices at the end of 2013.

## Cryptocurrency Portfolio

To apply MPT to a portfolio of cryptocurrencies, we need to calculate the two key ingredients: the expected returns vector and the covariance matrix. We could calculate the expected returns on the data – 189% p.a. for BTC, 3,100% for ETH and 406% for LTC – but it seems more sensible to assume the returns will be similar in the future. In other words, we should assume we have no information about the future returns.

To compute the covariance matrix, I have decided to look at weekly returns starting from 2016. The data from CoinCap.io also contained some duplicates, so I have removed those:

require(ggplot2) require(plyr) data <- read.csv( "data.csv", colClasses=c("Date", "numeric", "character") ) uk <- data[ , c("coin", "date")] uk$date <- as.numeric(uk$date) data <- data[-which(duplicated(uk)), ] data <- data[data$date >= "2016-01-01", ]

The ‘data’ variable contains daily prices for each coin type. Unfortunately there are a few days missing, so I choose the start date so the weeks contain the missing values:

weeks <- seq(as.Date("2016-01-02"), max(data$date), 7) data.weekly <- data[data$date %in% weeks, c("coin", "date", "price")] data.weekly <- ddply( data.weekly, c("coin", "date"), function (row) { prevRow <- data.weekly[ data.weekly$coin == row$coin & (data.weekly$date == row$date - 7), ] if (nrow(prevRow) >= 1) { row$prev.price <- prevRow$price } else { row$prev.price <- NULL } return(row) } ) data.weekly$return <- data.weekly$price / data.weekly$prev.price data.weekly.btc <- data.weekly[data.weekly$coin == "BTC", ] data.weekly.eth <- data.weekly[data.weekly$coin == "ETH", ] data.weekly.ltc <- data.weekly[data.weekly$coin == "LTC", ]

Now we can plot the weekly returns of the 3 cryptocurrencies since 2016. It should be clear, given the plot, why MPT can (in theory) reduce portfolio variance. The 3 cryptocurrencies are not perfectly positively correlated – you can see on some days that Bitcoin is up, Ethereum may be down, for example.

Now we have these time series of weekly returns, we can calculate the covariance matrix:

S <- cov(cbind( data.weekly.btc$return, data.weekly.eth$return, data.weekly.ltc$return ), use="complete.obs")

BTC | ETH | LTC | |
---|---|---|---|

BTC | 0.0064267086 | -0.0002000435 | 0.006306524 |

ETH | -0.0002000435 | 0.0532521805 | 0.001611612 |

LTC | 0.0063065235 | 0.0016116125 | 0.023998720 |

Then, since we assumed that expected returns are fixed, we can use a simple optimization function to minimize the porfolio variance:

require(Rsolnp) w <- solnp(c(1, 1, 1) / 3, function (w) { return(t(w) %*% S %*% w) }, eqfun=function (w) { return(sum(w)) }, eqB=1, LB=c(0, 0, 0), UB=c(1, 1, 1))$pars

This results in an optimal portfolio of:

Coin | Weighting |
---|---|

BTC | 89% |

ETH | 11% |

LTC | Negligible |

So it looks like MPT recommends the majority allocation to Bitcoin, which is not surprising given its lower volatility relative to Ethereum and Litecoin.