phenance.com
Stock Data Pages | TCA League Tables | About

Analyzing Bitcoin in R - Part 13 - Copulas and extreme values, two asssets

Pub: 04.12.17

| By Anonymous

In Finance.

Tags: coding r bitcoin analysis .

The issue with portfolio allocation is that for some assets there are not enough return observations. Or that we want to establish how robust the allocations are in simulated outcomes of the world. However, we also know that returns are notoriously difficult to simulate. One way that we can attempt to capture some of the interesting return dynamics is by using copulas and extreme value / tail risk dynamics to help.

A straight forward description of the background, math, and application can be read in Optimization with Tail-Dependence and Tail Risk: A Copula Based Approach for Strategic Asset Allocation by Francesco Paolo Natale. It gives you all you need to continue pursuing this type of analysis yourself.

The following is a simple paraphrasing of the approach. I will leave out the initial ARMA / GARCH model residual estimation and instead model the returns directly. I will also only show one simulation run instead of multiple.

Let's start by doing it for two assets. Bitcoin and the Index. They are not that correlated.

tworets <- cbind(btcnret, spidret)
colnames(tworets) <- c('BitcoinUSD', 'SP500')
tworets <- as.timeSeries(tworets)
cor(tworets)
           BitcoinUSD     SP500
BitcoinUSD  1.0000000 0.1552561
SP500       0.1552561 1.0000000

What does the scatter plot look like

png(filename = "btc_plot_scatter1.png")
plot(as.matrix(tworets), pch = 20)
dev.off()

Bitcoin and Index Returns Scatter Plot

Let's automatically find out which copula best represents the two series:

library(VineCopula)
selectedCopula <- BiCopSelect(pobs(tworets[,1]), pobs(tworets[,2]), familyset=NA)
selectedCopula
Bivariate copula: Rotated Tawn type 1 180 degrees (par = 1.57, par2 = 0.36, tau = 0.19)
summary(selectedCopula)
Family
------ 
No:    114
Name:  Rotated Tawn type 1 180 degrees

Parameter(s)
------------
par:  1.57
par2: 0.36
Dependence measures
-------------------
Kendall's tau:    0.19 (empirical = 0.16, p value = 0.04)
Upper TD:         0 
Lower TD:         0.24 

Fit statistics
--------------
logLik:  3.49 
AIC:    -2.99 
BIC:    1.65 

Now that we know the copula, let's simulate from it:

cop <- BiCop(family = 114, par = 1.57, par2 = 0.36)
simdata <- BiCopSim(300, cop)
outsim <- matrix(NA, 300, 2)
colnames(outsim) <- colnames(tworets)
outsim[,1] <- qnorm(simdata[,1], mean(tworets[,1]), sd(tworets[,1]))
outsim[,2] <- qnorm(simdata[,2], mean(tworets[,2]), sd(tworets[,2]))
png(filename = "btc_plot_scatter2.png")
plot(as.matrix(outsim), pch = 20)
dev.off()
outsim <- as.timeSeries(outsim)
out <- minvariancePortfolio(outsim, constraints = "LongOnly")
store <- out@portfolio@portfolio$weights
out <- maxratioPortfolio(outsim, constraints = "LongOnly")
store <- rbind(store, out@portfolio@portfolio$weights)

Bitcoin and Index Returns Simulated Scatter Plot

Let's also get results from the normal distribution for comparison:

outsim[,1] <- rnorm(300, mean(tworets[,1]), sd(tworets[,1]))
outsim[,2] <- rnorm(300, mean(tworets[,2]), sd(tworets[,2]))
outsim <- as.timeSeries(outsim)
out <- minvariancePortfolio(outsim, constraints = "LongOnly")
store <- rbind(store, out@portfolio@portfolio$weights)
out <- maxratioPortfolio(outsim, constraints = "LongOnly")
store <- rbind(store, out@portfolio@portfolio$weights)
rownames(store) <- c('CopulaMinVar', 'CopulaMaxRat', 'NormMinVar', 'NormMaxRat')

Is the difference big? Not really, I guess.

             BitcoinUSD     SP500
CopulaMinVar 0.000000000 1.0000000
CopulaMaxRat 0.028204004 0.9717960
NormMinVar   0.004985198 0.9950148
NormMaxRat   0.027463749 0.9725363

The results from the simulated data of 300 observations is almost the same as from the raw data.

A partial problem with extreme value theory is that fitting the tail distributions needs a bit more data than we have on Bitcoin. But we can use our simulation from the Copula to help us:

library(spd)
cop <- BiCop(family = 114, par = 1.57, par2 = 0.36)
simdata <- BiCopSim(1000, cop)
outsim <- matrix(NA, 1000, 2)
colnames(outsim) <- colnames(tworets)
outsim[,1] <- qnorm(simdata[,1], mean(tworets[,1]), sd(tworets[,1]))
outsim[,2] <- qnorm(simdata[,2], mean(tworets[,2]), sd(tworets[,2]))
simout <- matrix(NA, 1000, 2)
colnames(simout) <- colnames(outsim)
fit <- spdfit(outsim[,1], upper=0.9, lower=0.1, tailfit='GPD', kernelfit='normal')
simout[,1] <- rspd(1000, fit)
fit <- spdfit(outsim[,2], upper=0.9, lower=0.1, tailfit='GPD', kernelfit='normal')
simout[,2] <- rspd(1000, fit)
png(filename = "btc_plot_scatter3.png")
plot(as.matrix(simout), pch = 20)
dev.off()

Bitcoin and Index Returns EV Simulated Scatter Plot

Let's compare the new results with our old

simout <- as.timeSeries(simout)
out <- minvariancePortfolio(simout, constraints = "LongOnly")
store <- rbind(store, out@portfolio@portfolio$weights)
out <- maxratioPortfolio(simout, constraints = "LongOnly")
store <- rbind(store, out@portfolio@portfolio$weights)
rownames(store) <- c('CopulaMinVar', 'CopulaMaxRat', 'NormMinVar', 'NormMaxRat', 'EVMinVar', 'EVMaxRat')
store

So or tail fitting seems to produce something a bit more interesting than the few copula observations but less weight on Bitcoin than just simulating from a normal distribution. Probably meaning that the tails matter a bit more for Bitcoin and that should be considered with a lower weight.

              BitcoinUSD     SP500
CopulaMinVar 0.000000000 1.0000000
CopulaMaxRat 0.028204004 0.9717960
NormMinVar   0.004985198 0.9950148
NormMaxRat   0.027463749 0.9725363
EVMinVar     0.001179433 0.9988206
EVMaxRat     0.028906096 0.9710939

We can compare all three distributions:

png(filename = "btc_plot_scatter4.png")
par(mfrow = c(3, 1))
par(mar = c(4, 4, 3, 2))
plot(as.numeric(tworets[,1]), as.numeric(tworets[,2]), pch = 20);abline(h=0,v=0);
plot(as.numeric(outsim[,1]), as.numeric(outsim[,2]), pch = 20);abline(h=0,v=0);
plot(as.numeric(simout[,1]), as.numeric(simout[,2]), pch = 20);abline(h=0,v=0);
dev.off()

Bitcoin and Index Scatter Plots

Because we extended the data using our copula approach, we were able to add some extreme values and get a broader distribution of returns.

What if you have more than two assets that you want to evaluate in conjunction: Copulas and extreme value, many assets

You can also jump to each section directly from here: