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()
```

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)
```

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()
```

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()
```

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:

- Introduction to Bitcoin analysis with R
- Retrieving Bitcoin transaction data
- Part 2 - Reading the bitcoin data in to R
- Using the xts package and dates
- Using xts to summarize Bitcoin transaction data
- Setting up Bitcoin data in OHLC format
- Charting Bitcoin data
- Prliminary return analysis with plots
- Preliminary return analysis with rolling windows
- Technical analysis plots of Bitcoin
- Bitcoin's future price path
- Evaluating a portfolio
- Evaluating a stock portfolio
- Copulas and extreme values with Bitcoin
- Copulas and extreme value, many assets