Crypto Cointergration:

Testing for a Coupled Relationship in Cryptocurrencies


By: Mike Margolis







Load in the Data

We read in the data from a Kaggle dataset and use the closing prices for each coin. The data for each of the coins used in this research can be downloaded here link

XRP <- read_xlsx("C:/Users/mikem/OneDrive/Desktop/Crypto RMD/ALT_coins.xlsx",sheet =5) 
XRP <- subset(XRP, Date > "2018-02-02") 
XRP <- XRP %>% dplyr::filter(Symbol == "XRP") %>% tk_xts(select = Close, date_var = "Date")

BTC <- read_xlsx("C:/Users/mikem/OneDrive/Desktop/Crypto RMD/ALT_coins.xlsx",sheet =8) 
BTC <- subset(BTC, Date > "2018-02-02")
BTC <- BTC %>% dplyr::filter(Symbol == "BTC") %>% tk_xts(select = Close, date_var = "Date")

ETH <- read_xlsx("C:/Users/mikem/OneDrive/Desktop/Crypto RMD/ALT_coins.xlsx",sheet =9) 
ETH <- subset(ETH, Date > "2018-02-02")
ETH <- ETH %>% dplyr::filter(Symbol == "ETH") %>% tk_xts(select = Close, date_var = "Date")

Initial look

Here we have the logged prices of Bitcoin (BTC), Ethereum (ETH), and Ripple (XRP)

Coins1 <- cbind(log(BTC),log(ETH),log(XRP))

colnames(Coins1) <- c("lBTC","lETH","lXRP")
plot(Coins1,col=c("blue","green", "red"), main="Log prices of BTC (blue),\n ETH (green) and XRP (red)")

XRP1 <- read_xlsx("C:/Users/mikem/OneDrive/Desktop/Crypto RMD/ALT_coins.xlsx",sheet =5)
BTC1 <- read_xlsx("C:/Users/mikem/OneDrive/Desktop/Crypto RMD/ALT_coins.xlsx",sheet =8) 
ETH1 <- read_xlsx("C:/Users/mikem/OneDrive/Desktop/Crypto RMD/ALT_coins.xlsx",sheet =9)
Coins <- BTC1 %>% full_join(ETH1)
Coins <- Coins %>% full_join(XRP1)
Coins <- subset(Coins, Date > "2018-02-02")

Unit Root Testing
PT <- Coins %>% as_tsibble(index = Date, key = Symbol, regular = FALSE)
PTw <- PT %>% 
  pivot_wider(names_from = Symbol, values_from = Close) %>%
  as_tsibble(index = Date) %>% 
  tsibble::fill_gaps()
PT %>% 
  features(log(Close), unitroot_ndiffs) %>% 
  kable(format = "html", table.attr = "style='width:30%;' ") %>% 
  kableExtra::kable_styling()
Symbol ndiffs
BTC 1
ETH 1
XRP 1
PT %>% 
  features(log(Close), unitroot_kpss) %>% 
  kable(format = "html", table.attr = "style='width:30%;' ") %>% 
  kableExtra::kable_styling()
Symbol kpss_stat kpss_pvalue
BTC 14.428784 0.01
ETH 12.067377 0.01
XRP 4.524104 0.01

The kpss tests confirm that the log(close) for all three coins have a unit root.If the p-value is < then significance level (0.05), then the series is non-stationary.

Now we determine how many cointegrating vectors we have. Since there are 3 variables, we cannot use the Stock-Watson approach which only tests for cointegration in pairs of variables. Instead, we will use the Johansen procedure. First, we determine the number of lags in the VAR in levels, p.coins. Second, we use the ca.jo function from the urca package to determine the number of cointegrating vectors. There can be: 0 => no cointegration; 1 => there is a single vector so that some linear combination of all 3 coins is stationary; 2 => there are 2 independent linear combinations that are stationary. This is like our term structure of interest rates example where, for 10 rates, there are 9 cointegrating vectors and only one source of non-stationary shocks. Notice that we cannot find 3 cointegrating vectors because that would mean that all 3 variables must be I(0) which we have already ruled out.

p.coins <- as.integer(VARselect(Coins1,lag.max=12,type="const")$selection[2])
ca.jo.out <- ca.jo(Coins1, type = "trace", ecdet = "none", K = 2, spec = "longrun")
summary(ca.jo.out) 
## 
## ###################### 
## # Johansen-Procedure # 
## ###################### 
## 
## Test type: trace statistic , with linear trend 
## 
## Eigenvalues (lambda):
## [1] 0.0114681932 0.0065972761 0.0007884971
## 
## Values of teststatistic and critical values of test:
## 
##           test 10pct  5pct  1pct
## r <= 2 |  1.28  6.50  8.18 11.65
## r <= 1 | 11.98 15.66 17.95 23.52
## r = 0  | 30.63 28.71 31.52 37.22
## 
## Eigenvectors, normalised to first column:
## (These are the cointegration relations)
## 
##            lBTC.l2    lETH.l2   lXRP.l2
## lBTC.l2  1.0000000  1.0000000  1.000000
## lETH.l2 -0.8693364  0.1930266 -3.191496
## lXRP.l2  0.6023509 -2.8898902  2.095139
## 
## Weights W:
## (This is the loading matrix)
## 
##             lBTC.l2     lETH.l2       lXRP.l2
## lBTC.d -0.002055279 0.002112410  0.0003049150
## lETH.d  0.008181954 0.002953858  0.0002471834
## lXRP.d -0.001373557 0.003965193 -0.0001871939

Our test results indicate a single cointegrating vector and 2 sources of non-stationary shocks. This seems a little odd, but we will go with it to see what we find.

vecm1.out <- VECM(Coins1,2,r=1,include="const",estim="ML",LRinclude="none")
summary(vecm1.out)
## #############
## ###Model VECM 
## #############
## Full sample size: 1619   End sample size: 1616
## Number of variables: 3   Number of estimated slope parameters 24
## AIC -32188.35    BIC -32048.27   SSR 12.29167
## Cointegrating vector (estimated by ML):
##    lBTC       lETH      lXRP
## r1    1 -0.8750973 0.6168884
## 
## 
##               ECT                 Intercept           lBTC -1            
## Equation lBTC -0.0032(0.0036)     0.0119(0.0125)      0.0204(0.0444)     
## Equation lETH 0.0065(0.0047)      -0.0224(0.0165)     -0.0141(0.0587)    
## Equation lXRP -0.0028(0.0055)     0.0093(0.0192)      -0.0346(0.0683)    
##               lETH -1             lXRP -1             lBTC -2            
## Equation lBTC -0.0545(0.0366)     -0.0209(0.0228)     0.0002(0.0444)     
## Equation lETH -0.0459(0.0483)     -0.0466(0.0302)     -0.0521(0.0587)    
## Equation lXRP -0.1006(0.0563).    0.0395(0.0351)      0.0808(0.0683)     
##               lETH -2            lXRP -2            
## Equation lBTC 0.0771(0.0365)*    -0.0361(0.0228)    
## Equation lETH 0.1376(0.0483)**   -0.0366(0.0302)    
## Equation lXRP 0.0661(0.0561)     -0.0630(0.0351).

The results are difficult to interpret. We find that BTC adjust the most, XRP the next most, and ETH does not significantly adjust. So, in this model, we find ETH to be the drunk and BTC and XRP to be the puppies.

The IRFs seem to tell a different story–BTC is reluctant to adjust to shocks in ETH or XRP, and neither BTC nor ETH respond to shocks in XRP.

irf1.coins <- irf(vecm1.out, n.ahead = 31)
plot(irf1.coins)

These graphs demonstrate the Impulse Response Function associated with each of the coins. For all three graphs and all three coins we put each coin in their long run steady state. One at a time we take each coin and “ping” it, we push the coin one standard deviation above its steady state values. We then observe how the other coins move once the tested coin’s steady state is broken. For Bitcoin we can see that each of the other two coins rise in price once Bitcoin rises. When Ethereum is “pinged” we see that Bitcoin does not move. XRP rises in price, however, not as much as it did when Bitcoin was pinged. When XRP is pinged Bitcoin and Ethereum actually decrese in price, slightly. It seems that When Bitcoin is “the drunk” ETH and XRP are “the puppies”. When ETH is “the drunk”, BTC is another drunk and XRP is puppy. When XRP is “the drunk”, BTC and ETH are also drunks.

plot(vars::fevd(vecm1.out, n.ahead = 52))

Let’s try the case where there are two cointegrating vectors just to see what happens. The results are not wildly different so it is difficult to decide whether there should be 1 or 2 cointegrating vectors.

vecm2.out <- VECM(Coins1,2,r=2,include="const",estim="ML",LRinclude="none")
summary(vecm2.out)
## #############
## ###Model VECM 
## #############
## Full sample size: 1619   End sample size: 1616
## Number of variables: 3   Number of estimated slope parameters 27
## AIC -32191.04    BIC -32034.8    SSR 12.23921
## Cointegrating vector (estimated by ML):
##    lBTC          lETH      lXRP
## r1    1 -1.110223e-16 -2.255330
## r2    0  1.000000e+00 -3.282171
## 
## 
##               ECT1                ECT2                Intercept          
## Equation lBTC -0.0013(0.0037)     0.0031(0.0031)      -0.0124(0.0166)    
## Equation lETH 0.0094(0.0048).     -0.0053(0.0041)     -0.0587(0.0219)**  
## Equation lXRP 0.0010(0.0056)      0.0029(0.0048)      -0.0386(0.0255)    
##               lBTC -1             lETH -1             lXRP -1            
## Equation lBTC 0.0178(0.0444)      -0.0554(0.0365)     -0.0179(0.0228)    
## Equation lETH -0.0180(0.0586)     -0.0473(0.0483)     -0.0420(0.0302)    
## Equation lXRP -0.0398(0.0681)     -0.1025(0.0561).    0.0455(0.0351)     
##               lBTC -2             lETH -2            lXRP -2            
## Equation lBTC -0.0026(0.0444)     0.0756(0.0365)*    -0.0328(0.0229)    
## Equation lETH -0.0563(0.0586)     0.1353(0.0482)**   -0.0317(0.0302)    
## Equation lXRP 0.0752(0.0681)      0.0630(0.0560)     -0.0565(0.0351)
irf2.coins <- irf(vecm2.out, n.ahead = 31)
plot(irf2.coins)

plot(vars::fevd(vecm2.out, n.ahead = 52))

We can see from both Impulse Response Function Graphs and Forecasted Error Variance Decomposition Graphs that BTC barley budges and the variation in that coin is soley caused by it’s own variation. On the other hand, ETH and XRP seem to both be affected by outside variation. For ETH over 60% of the variation in it’s forecasted price will be due to BTC’s variation in price. XRP is surprisingly affect less by BTC than ETH and the variation in XRP’s forecasted price is due partially to its own variation and not BTC or ETH.


Computing the Spill Over Index: How are the price and volatility of different coins connected?

What are these coins and what are they used for?

Descriptions and Definitions are pulled in-part from Investopedia
ADA
  • The native token of Cardano. Cardano’s main applications are in identity management and trace-ability. The former application can be used to streamline and simplify processes that require the collection of data from multiple sources. The latter application can be used to track and audit a product’s manufacturing processes from provenance to finished goods and, potentially, eliminate the market for counterfeit goods.
BNB
  • The native token of the Binance block chain, initally based on the Ethereum network. Binance was created as a utility token for discounted trading fees in 2017, but its uses have expanded to numerous applications, including payments for transaction fees (on the Binance Chain), travel bookings accommodations (at sites such as TravelbyBit, Trip.io, and Travala.com), entertainment purposes (virtual gifts, card packs, lotteries), online services, and financial services (take out a loan at ETHLend or make investments at Moeda).
BTC
  • BitCoin is Bitcoin lol.
ETH
  • Ethereum is Ethereum. Ethereum enables the deployment of smart contracts and decentralized applications (dApps) to be built and run without any downtime, fraud, control, or interference from a third party.7 Ethereum comes complete with its own programming language (Solidity) that runs on a blockchain, enabling developers to build and run distributed applications.
LTC
  • Litecoin (LTC) is a cryptocurrency created from a fork in the Bitcoin blockchain in 2011. It was initially designed to address the developer’s concerns that Bitcoin was becoming too centrally controlled, and to make it more difficult for large scale mining firms to gain the upper hand in mining. While eventually unsuccessful in preventing enterprise miners from taking over the lion’s share of Litecoin mining, the cryptocurrency has reworked itself into a mineable coin and a peer-to-peer payment system. Litecoin has a faster transaction processing time compared to Bitcoin.
XRP
  • XRP is a “bridge asset” or an asset that businesses and financial institutions can use as a bridge transfer between two different fiat currencies. In such a scenario, the financial institution can simply purchase an equivalent amount of XRP and send it through Ripple’s network. Ripple refers to it as “third-party liquidity provisioning” and states that it is ideal for banks that do not have a corresponding relationship with each other. XRP is currently facing a lawsuit from the SEC. Personally I believe all data for XRP should have an (*) next to it due to the potential/real value of the coin will be revealed once the lawsuit reaches a conclusion. A situational forecast could help determine the future price, situation 1 Ripple(XRP) wins the suit, the price will probably sky rocket. Situation 2 the SEC wins the lawsuit and XRP’s price will most likely fall tremendously.
XLM
  • The term Stellar cryptocurrency refers to a digital or virtual currency developed by Stellar Development Foundation. The organization’s currency, which is called the lumen, is traded under the symbol XLM on various cryptocurrency exchanges. Lumens can be used by traders on the Stellar network, which is a blockchain-based distributed ledger network that connects banks, payments systems, and people to facilitate low-cost, cross-asset transfers of value, including payments. Stellar’s primary focus is on developing economies in the areas of remittances and bank loans to those who are outside of the scope of the banking services. Stellar doesn’t charge individuals or institutions for using the network. Stellar supports a distributed exchange mode. This allows users to send payments in specific currencies even though they may hold credits in another, while the network automatically performs the forex conversion. The receiver can withdraw their currency equivalent through a partner institute like a bank. As a cross-border transfer and payment system that connects financial entities, Stellar aims to significantly reduce transaction costs and time lags. While Stellar works just like technologies like Bitcoin, its key distinguishing feature is its consensus protocol.
TRX
  • Tron is a blockchain-based decentralized digital platform with its own cryptocurrency, called Tronix or TRX. Founded in 2017 by a Singapore non-profit organization, the Tron Foundation, Tron aims to host a global entertainment system for the cost-effective sharing of digital content.Tron uses the features of the blockchain and peer-to-peer (P2P) network technology to eliminate the middleman and allow content creators to sell their work directly to consumers. Software developers use the Solidity programming language to create apps that are hosted on the Tron platform.
#Import the daily coin data and set the starting dates for each coin as the same, convert the data into a time series element and combine them into one wide table based their date and close value

BNB1 <- read_xlsx("C:/Users/mikem/OneDrive/Desktop/Crypto RMD/ALT_coins.xlsx", sheet =1)
BNB1 <- subset(BNB1, Date > "2018-02-02")
BNB1 <- BNB1 %>% dplyr::filter(Symbol == "BNB") %>% tk_xts(select = Close, date_var = "Date")

ADA1 <- read_xlsx("C:/Users/mikem/OneDrive/Desktop/Crypto RMD/ALT_coins.xlsx",sheet =2)
ADA1 <- subset(ADA1, Date > "2018-02-02")
ADA1 <- ADA1 %>% dplyr::filter(Symbol == "ADA") %>% tk_xts(select = Close, date_var = "Date")

LINK1 <- read_xlsx("C:/Users/mikem/OneDrive/Desktop/Crypto RMD/ALT_coins.xlsx",sheet =3)
LINK1 <- subset(LINK1, Date > "2018-02-02")
LINK1 <- LINK1 %>% dplyr::filter(Symbol == "LINK") %>% tk_xts(select = Close, date_var = "Date")

LTC1 <- read_xlsx("C:/Users/mikem/OneDrive/Desktop/Crypto RMD/ALT_coins.xlsx",sheet =4)
LTC1 <- subset(LTC1, Date > "2018-02-02")
LTC1 <- LTC1 %>% dplyr::filter(Symbol == "LTC") %>% tk_xts(select = Close, date_var = "Date")

XRP1 <- read_xlsx("C:/Users/mikem/OneDrive/Desktop/Crypto RMD/ALT_coins.xlsx",sheet =5)
XRP1 <- subset(XRP1, Date > "2018-02-02")
XRP1 <- XRP1 %>% dplyr::filter(Symbol == "XRP") %>% tk_xts(select = Close, date_var = "Date")

XLM1 <- read_xlsx("C:/Users/mikem/OneDrive/Desktop/Crypto RMD/ALT_coins.xlsx",sheet =6)
XLM1 <- subset(XLM1, Date > "2018-02-02")
XLM1 <- XLM1 %>% dplyr::filter(Symbol == "XLM") %>% tk_xts(select = Close, date_var = "Date")

TRX1 <- read_xlsx("C:/Users/mikem/OneDrive/Desktop/Crypto RMD/ALT_coins.xlsx",sheet =7)
TRX1 <- subset(TRX1, Date > "2018-02-02")
TRX1 <- TRX1 %>% dplyr::filter(Symbol == "TRX") %>% tk_xts(select = Close, date_var = "Date")

BTC2 <- read_xlsx("C:/Users/mikem/OneDrive/Desktop/Crypto RMD/ALT_coins.xlsx",sheet =8)
BTC2 <- subset(BTC2, Date > "2018-02-02")
BTC2 <- BTC2 %>% dplyr::filter(Symbol == "BTC") %>% tk_xts(select = Close, date_var = "Date")


ETH2 <- read_xlsx("C:/Users/mikem/OneDrive/Desktop/Crypto RMD/ALT_coins.xlsx",sheet =9)
ETH2 <- subset(ETH2, Date > "2018-02-02")
ETH2 <- ETH2 %>% dplyr::filter(Symbol == "ETH") %>% tk_xts(select = Close, date_var = "Date")


Crypto2 <- cbind(log(BTC2),log(ETH2),log(XRP1),log(ADA1),log(BNB1),log(LTC1),log(TRX1),log(LINK1),log(XLM1))
colnames(Crypto2) <- c("lBTC","lETH","lXRP","lADA","lBNB","lLTC","lTRX","lLINK","lXLM")

Plot the logged values of all the coins
plot(Crypto2)

KEY:
  • BTC (BLACK)
  • ETH (RED)
  • LTC (PINK)
  • BNB (Light BLUE)
  • LTC (GREY)
  • ADA (Dark BLUE)
  • XRP (GREEN)
  • XLM (BLACK)
  • TRX (YELLOW”)
p <- tmp$selection[2]
var.Crypto <- VAR(Crypto2, p=p, type="const")

spilloverDY12(var.Crypto, n.ahead = 100, no.corr = FALSE) 
## The spillover table has no frequency bands, standard Diebold & Yilmaz.
## 
## 
## |      |  lBTC|  lETH|  lXRP|  lADA|  lBNB|  lLTC|  lTRX| lLINK|  lXLM|  FROM|
## |:-----|-----:|-----:|-----:|-----:|-----:|-----:|-----:|-----:|-----:|-----:|
## |lBTC  | 21.51| 13.81|  3.46| 14.89|  9.71| 16.46|  3.99|  8.96|  7.20|  8.72|
## |lETH  | 14.17| 17.25|  5.30| 17.46|  8.70| 14.32|  6.22|  8.33|  8.24|  9.19|
## |lXRP  | 10.13| 10.26| 17.53| 15.21|  7.69| 11.58|  7.88|  5.20| 14.51|  9.16|
## |lADA  | 10.79| 13.02|  3.93| 24.83|  9.09| 12.83|  5.20|  8.46| 11.84|  8.35|
## |lBNB  | 12.84| 10.88|  3.50| 15.56| 22.48| 12.15|  7.69|  7.38|  7.52|  8.61|
## |lLTC  | 12.93| 11.47|  7.35| 16.17|  7.73| 21.58|  6.46|  6.86|  9.45|  8.71|
## |lTRX  | 10.42| 11.52|  7.12| 17.17|  8.64| 11.11| 18.23|  5.74| 10.04|  9.09|
## |lLINK | 11.30|  8.97|  4.10| 12.23|  7.15|  9.87|  4.39| 35.76|  6.23|  7.14|
## |lXLM  | 12.50| 12.00|  7.03| 17.61|  6.05| 13.08|  6.16|  5.37| 20.21|  8.87|
## |TO    | 10.57| 10.21|  4.64| 14.03|  7.19| 11.27|  5.33|  6.26|  8.34| 77.85|

The across rows represent how much ones coins variation is shared with another coins variation. For example, 14% of the variation in ETH is due to the fluctuation in price of Bitcoin. The down columns show how much one coin’s change in price causes volatility in the others. Bitcoin is a huge factor in other coins price changes. It seems to cause significant variation in all the other coins. The last cell of “To” and “From” shows how interconnected the entire variability in coin prices are. We find about 78% of variation in price for all of these coins are interconnected.