# Bitcoin and Gold Correlation – Portfolio Optimization with Python

What is the correlation between bitcoin and gold? How does the bitcoin and gold chart comparison look like? In this article, I would use python to plot out everything about these two assets. After which, I would draw out an efficient frontier graph and pinpoint the Sharpe ratio for portfolio optimization.

To start off, suppose you have \$10,000. You are interested in getting some gold and bitcoin to diversify your portfolio against political uncertainty and recession. How would you allocate the money? Would it be like a 50-50 ratio? 20% bitcoin and 80% gold? Or 75% gold and 25% bitcoin? The question is pretty subjective, isn’t it? It is hard to decide on the allocation.

## Introduction of Sharpe Ratio

What if there is a quantitative approach to help us make this decision? Yes, there is and it is called the Sharpe ratio. Sharpe ratio is otherwise known as the adjusted-risk returns. You can read more about it in detail from the source link.

But in essence, it is calculated by taking the return of a portfolio divided by the standard deviation which represents the volatility. If a portfolio has a high return but also a high standard deviation, it would push the Sharpe ratio down. So that reduces the attractiveness of the investment.

Investors only want two things. The first is to maximize returns and second is to minimize risk. Hence, the optimal portfolio would be one where the returns of the portfolio are the highest and the standard deviation is the lowest.

Different weights of bitcoin and gold in a portfolio have different returns and volatility. A 90% bitcoin and 10% gold portfolio would behave very differently from a portfolio of 10% bitcoin and 90% gold.

Therefore, our goal here is to find the optimal data point such that the Sharpe ratio is the highest. Then, return the weight allocation of bitcoin and gold.

Alright, enough said. Let’s open Jupyter!

## Pulling Bitcoin and Gold Prices from Yahoo

The first step, as always, import numpy as np, import pandas as pd and blah blah. Secondly, we type in the ticker symbol of bitcoin and gold and store them into a variable called `assets`. The steps and code are exactly the same as my previous post. The only thing that changed is the asset. Lastly, we want to take the closing price of bitcoin and gold starting from 2014 to date, then store it in `my_portfolio`. The reason why I used 2014 is because it is the year when Yahoo started tracking bitcoin. More specifically, it is September 2014.

In a way, that is also good because bitcoin is more mature at that time. If we start tracking the price of bitcoin since 2009, the gains would be insane as the original price was only worth a few cents. The downside is a massive loss of data in our modelling. September 2014 to date is only about five years’ worth of data. That is the first limitation to bear in mind.

## Data Cleaning and Data Visualisation

Let’s see what happens when we run `my_portfolio `

BAM! Uh oh… we have some “NaN” data. These are all missing data that are found in the gold column. Why did that happen? That is because bitcoin never sleeps. Crypto markets are 24/7 while the gold ETFs are traded on stock exchanges which are closed on weekends. That’s why they are showing “NaN” on weekends and public holidays.

We have to do something about all these “Nan” data. This can be solved easily by using the `.dropna()` function. `dropna()` automatically removes all the rows that have “Nan”. Let’s see the cleaned data version after applying this function.

Much better! But it is a painful loss. Our data set has reduced from 1947 rows to 1342 rows. That is a 30% loss from the original version. Other methods to deal with this could be replacing the missing values with mean, mode and etc. But to simplify things, we just remove all missing data. I stored this clean version under a new variable called the `new_portfolio`

## Bitcoin and Gold Chart Comparison

Let’s have a look at the price comparison between bitcoin and gold.

Whoa… That seems totally off-scale. Gold is just a flat line across. The gold price that I am using is actually the SPDR gold ETF. It is the spot gold price divided by 10. For example, if the gold price is \$1,500, the gold ETF would probably be around \$150. This is to make it accessible for everybody but it mimics the price action of the spot gold price.

This might be the reason why gold prices look insignificant in comparison to bitcoin. What if we normalize it to 100. Would the chart improve? Let’s see.

Nope. It still looks the same after normalization. Is there some kind of code error? Or gold price returns are indeed very far off from bitcoin?

The answer is the returns of gold are really very far off from bitcoin. This is because gold is an \$8 trillion market cap while crypto is only about \$200 billion. To put things into perspective, the global money supply is about \$90 trillion. Because the crypto market is so small, a trillion-dollar of fiat money into bitcoin would show very different price returns as compared to gold.

The video above gives you a good feel of the scale and comparison between bitcoin and gold. It shows the time-lapse of how much you would have if you invested \$10,000 in bitcoin and gold since 2011. After watching the video, you would understand why there is such a stark comparison in prices between bitcoin and gold.

## Annual Returns & Volatility of Bitcoin and Gold

Alright, let’s see what is the annual log-returns and volatility of both bitcoin and gold. The formula for calculating the returns and volatility follows the same methods as mentioned in the previous post. So I shall save you the bore.

The log_returns show the daily price returns from 2014 to 2020. To calculate the annual returns, we simply find the daily mean and multiply by the number of trading days. You can see that Gold only returns about 3.9% while bitcoin’s annual return is about 55.5%. Remember again that this is based on a 5-year time frame.

It is expected that high-returns come with higher risk. Let’s look at the volatility chart of bitcoin and gold.

There you have it. It is clear now that bitcoin looks like a roller-coaster. High returns come with a price and that is your emotions. This is your money that we are talking about. Just imagine your portfolio value going up and down like the bitcoin volatility. Well, that is how mine looks.

Even though gold returns only about 4% based on a 5-year average, at least its volatility is a flat line. That is one positive about gold. You are not worrying whether your portfolio will tank 20% tomorrow.

Here is another way to look at volatility.

We can plot out the price returns on a histogram chart. The wider the distribution the more volatile it is. You can see that gold is mostly within the mean distribution. But BTC spreads widely across the x-axis. Sometimes the returns can be 10%,15% or 20%. But you will never see a day gold spiked up 10%.

## Bitcoin and Gold Covariance

The next step we are going to do is to find out the covariance and correlation between the 2 assets. From this part on, it is going to be more statistical. But fret not, I will try to make everything easy.

Firstly, covariance tells us the relationship between the two variables. We are trying to find if there is a linear relationship between both assets. If there is, then it can be said they co-vary. That is how the term covariance is derived.

For example, if bitcoin gains 5%, how do the returns of gold correspond to it? Does it also gain 5%? Or does it show no response to it? That is one way to think about covariance. Let’s see their annual covariance.

The variance of bitcoin is 0.523. The variance of gold is 0.016. The covariance between bitcoin and gold is 0.001934. At this point in time, we can only tell that a positive covariance value means there is a positive linear relationship. HOWEVER, it does not tell us anything about the gradient of the slope or the strength of the relationship. In order to do so, we need to calculate the correlation.

## Bitcoin and Gold Correlation

Correlation tells us how strong a relationship between the two variables is. The values are between -1 to 1. A value of -1 means it is perfectly negatively correlated. 0 means no correlation and 1 means perfectly positively correlated.

The formula for correlation is to take the covariance of X and Y, then divide by the standard deviation of X times the standard deviation of Y. This covariance is the one that we calculated previously to be 0.001934. Let’s see the correlation using `.corr()`

Oops. It is 0.020636 or 2.06%. That is close to 0. In layman terms, there is almost no correlation. Note that we are comparing the correlation between the assets’ returns rather than the price movement. Remember that we are using the `log_returns` which stores the daily % returns of the assets.

Another thing is that we don’t multiply by 252 trading days. This is because there is no average daily correlation value here. We are just trying to find out the correlation between both assets across the entire data set.

Is it surprising to see such a low correlation? Well, the earlier two price chart says it all. Gold returns pale in comparison to bitcoin, drastically.

## Portfolio Diversification

You might ask, why do we need to calculate the covariance or correlation of bitcoin and gold?

This is because the volatility of one’s portfolio depends on three things.

1. The standard deviation of the individual assets
2. Weight of the assets
3. Covariance between the assets

Hence, the covariance value is one of the inputs that we need to calculate portfolio volatility. The lower the covariance between the two assets, the lower the volatility. This is because they do not move in tandem. Generally speaking, a portfolio of assets that have a high correlation or covariance between one another usually has higher volatility.

For example, Singaporean investors love REITs. All these REITs are probably highly correlated to one another. When one rises, it all rises. When a property market bust comes, all will go down together. In a REITs bull market, they make really good money. But in a bear market, they also lose a lot.

Compare it to another portfolio that has REITs, banks, consumer goods, and crypto. In a REITs bull market, their portfolio returns might not be as high as a 100% REITs play portfolio. But when REITs fall, their other assets don’t fall with it. Some might even rise to offset the loss from REITs.

That is what portfolio volatility is all about. Hence, it is important to get different assets that have low covariance and correlation. Ideally, your portfolio should have a mix of different sectors and asset classes. This would help diversify your portfolio volatility. Don’t use mine as an example. Use it as a bad example. I already screwed up by going heavily in on crypto.

## Controllability of Variables

Anyways, if you look at the above three variables. Covariance between the assets is something we can’t control. The risk or standard deviation of the individual assets is also something that we can’t control.

The only variable which we have control over is the weight of the assets. We can decide on how much of the \$10,000 should go into bitcoin and how much of it should go into gold. The decision that we made would ultimately determine our portfolio returns and variance.

That is the purpose of this article. The objective end goal is simply to find the weights of the assets. We are going to write a python code and run some trial runs. At the end of it, the output would tell us the point where the Sharpe ratio is the highest. That is the point where the adjusted-risk return is the maximum. Finally, we will ask python to tell us the weights of the assets at this particular point. Here is where the real fun begins.

## Overview of Python Code Functions

Firstly, I set the number of iterations to 1000 times. This makes the machine runs 1000 rounds to generate 1000 different combinations of weights for bitcoin and gold. Next, I created an array called `results` which is made up of 5 rows and 1000 columns. However, it is all set to zeros now.

Each column represents 1 iteration, that’s why there are 1000 columns. In each iteration, we are going to calculate and store 5 things in this `results` array. That’s why I created 5 rows.

1. Portfolio Returns
2. Portfolio Volatility
3. Sharpe Ratio
4. Bitcoin Weight
5. Gold Weight

The Sharpe Ratio is calculated by taking the first row divided by the second row. It is the portfolio returns divided by the portfolio volatility. For simplicity, I am excluding the risk-free rate in the Sharpe ratio. The bitcoin weight and the gold weight is just our randomly generated weights.

So you can imagine what happens when this runs. The `results` array would be populated with these 5 data points, one column at a time and 1000 times from left to right. That is a brief overview of what we are trying to do.

## Setting the Weights of Bitcoin and Gold

Let’s see what goes on inside each iteration.

for i in range (iterations). That is the loop function that runs through 1000 times. In each round, we will randomly generate two different weights between 0 and 1.

However, how do we ensure that these two weights add up to be equal 1? We can’t possibly have a randomly generated 70% weight in bitcoin and another 90% in gold. That doesn’t make sense. The two weights have to add up to 100%.

There is a simple trick and it can be shown in this formula here.

The mathematic formula forces both weight 1 and weight 2 to adds up to be equal 100%. In the above example, let’s say the machine throws us a random weight of 70% in bitcoin and 90% in gold.

Bitcoin (weight 1) would be readjusted to 43.75% [70% / (70% + 90%)]
Gold (weight 2) would be readjusted to 56.25% [90% / (90% + 70%)]
Weight 1 + Weight 2 = 100%, Voila! Problem solved!

## Portfolio Returns Calculations

We got the weights, the annual returns of bitcoin and gold and the covariance. Now its time to start piecing everything up. So how do we calculate a portfolio’s returns?

The formula for calculating portfolio returns is simply the sum of the weights and the returns of all the individual assets. Above is a simple illustration of calculating the returns of a portfolio that holds four different stocks. Pretty straight forward.

Similarly, we have the returns of bitcoin and gold. Now, the machine is going to throw us 1000 different weights combinations. In each iteration, we would calculate what is the portfolio return based on the weights, then store it in the results array.

Next, calculating portfolio volatility is slightly more complex.

## Portfolio Variance Calculations

This is the formula for calculating portfolio variance. There are five inputs we need. Weight of bitcoin, the variance of bitcoin. Weight of gold, the variance of gold. And lastly, the covariance of bitcoin and gold. We already have all these data from our covariance matrix.

Rings a bell? Remember we mentioned earlier portfolio volatility is dependent on three things. The standard deviation of the individual assets, the weight of the assets and the covariance of the assets. All these inputs go directly into the calculation of one’s portfolio variance.

Let’s see how this works. There are two parts to it. The first part is as follows.

It is unnecessary to know this, but if you are interested in the code, this is the step-by-step breakdown of the calculations. If you hate numbers, you can skip this.

`annual_cov` is something that we have already calculated earlier. If we take `np.dot(annual_cov, weights)`, it is multiplying the covariance matrix with the randomly generated weights. Let’s take weight x as the bitcoin weight and weight y as the gold weight in this example.

Matrix multiplication usually goes by 1st row, 1st column, then 2nd row 1st column, 2nd row 2nd column and so on. The first part of the calculation would give us the output as shown above.

This output from the first part is then multiplied against the weights again.

Firstly, we need to transpose the weights to make it the same matrix: 1 row, 2 columns. Then just multiply both arrays across. You would see that it would return the exact same formula as the portfolio variance. The final step is just to square root it to get the portfolio volatility.

## Summary of 1000 Portfolio Combinations

Okay. Now it is time to see some results. We already told Python how to calculate portfolio returns, portfolio volatility and the Sharpe ratio. The formula is fixed. The only variable that changes in each iteration is our randomly generated weights. So each weight combination would give us different portfolio returns, volatility and the Sharpe ratio.

We do this 1000 times then store everything in our results array. Finally, transpose the entire data set from 5 rows and 1000 columns into 5 columns and 1000 rows. Let’s call this new transposed version `df`. Then we want to sort it by returns to see what is the lowest and highest returns. Let’s run df and see the output.

The highest return is 55% with a 99.9% weight in bitcoin. However, that also means the portfolio volatility is 72%. On the other hand, the lowest return is 4.1% with a 99.5% weight in gold. The volatility is only 12.9%. The returns match the annual means of gold and bitcoin which we have calculated earlier.

## The Efficient Frontier and Sharpe Ratio

We have come to the last part, finally. The last step is to plot out all the data points of 1000 different weight combinations. Then we want to find out the exact point where the Sharpe ratio is the highest.

BAM!! The Sharpe ratio is the golden cross right there. That is the point where the adjusted-risk return is the HIGHEST. How does it know its there?

Remember ‘Sharpe’ is one of our columns? We are storing the Sharpe ratio in each iteration. So we just need to find the index position where the Sharpe Ratio is the highest. This can be done by using `.idxmax()`. Then use `.iloc[]` to bring us to that data row. Finally, call the first index and second index and that will return us the returns and volatility figure. That is how it plots the golden cross there.

Now that we know where the Sharpe ratio is. The key question to ask is, so how much bitcoin and gold should I allocate? Well, simply print the variable `max_sharpe` and lets’ see the results.

VOILA! That is the optimal weight based on the past 5-years price returns, statistics, modern portfolio theories, mathematics, and python. 32% bitcoin and 68% gold. Such an allocation would give an average return of about 20%. The volatility is about 25%. You can catch some upside potential in bitcoin, but yet your risk is also minimised by having a heavier weight in gold.

What is mine? I am about 80% bitcoin and 20% gold. I wished I knew about this before my investments. Anyways, I tried to find what is the returns and volatility based on my current allocation. Here is what I have got.

45% returns and 58% standard deviation…

Anyways, be it finance or python, hope this article has been insightful for you. This is pretty much some of the things I have absorbed so far. Probably will be away for some time to learn other python stuff and continue my journey ahead.

I would describe this cycle as learning > summarize and reinforce > continue learning. Then repeat. It is good to breathe and consolidate your learning. Helps build a better foundation. I have summarized and reinforced over the past few days by writing all these python articles. It is time to move on with the next phase of learning. Stay tuned for future posts! As always, do remember to like our FB page and subscribe to our mailing list! ?

•
•
•
•
•
•
•
•
•

#### 1 Comment

1. Awsome beakdown of the Sharpe Ratio in real time. Clean, crisp and well scripted. Genius.