On Fractional Differencing

The fractional differencing operator is defined as an infinite binomial series expansion in powers of the backward-shift operator. Fractionally differences processes exhibit long-term persistence and antipersistence; the dependence between observations a long time span apart decays much more slowly with time span than is the case with the more commonly studied time series models. Long-term persistent processes have applications in economics and hydrology; compared to existing models of long-term persistence, the family of models introduced here offers much greater flexibility in the simultaneous modelling of the short-term and long-term behaviour of a time series.

That summary is shamelessly stolen from this paper. After listening to Marcos Lopez de Prado in some talks about how stock price data can become stationary and still maintain some long memory, I got curious. I’ve read the chapter on this subject his book, Advances in Financial Machine Learning, and will be trying to fractional differentiate danish stock prices in R.

Let’s load some packages.

library(quantmod)
library(tidyverse)
library(tseries)
library(timeSeries)
library(forecast)
library(xts)
library(lmtest)
library(fracdiff)
library(LeastFracDiff)

Data

I start of by defining a character vector containing danish tickers of interest.

tickers <- c("TRYG.CO", "CARL-B.CO", "DSV.CO", "NOVO-B.CO", "CHR.CO", "VWS.CO", "RBREW.CO", "AMBU-B.CO", "NZYM-B.CO", "FLS.CO", "MAERSK-A.CO", "SIM.CO", "PNDORA.CO", "MAERSK-B.CO", "COLO-B.CO", "ROCK-B.CO", "LUN.CO", "GN.CO", "DANSKE.CO", "JYSK.CO")

Then I pull adjusted close prices from each and append it to one singular dataframe.

Data <- NULL
for (Ticker in tickers){
  Data <- cbind(Data, getSymbols.yahoo(Ticker, from='2017-01-01', to='2019-11-01', periodicity = "daily", auto.assign=FALSE)[,6])}
colnames(Data) <- tickers

Whitout further ado, let’s try it out! Each “d”-parameter is appended to its own DF and used in the next section.

d <- data.frame(matrix(0, ncol = 1, nrow = 20))
for(i in 1:20){
  df <- Data[,i]
  d[i,] <- min_d(df, adf, 0.05)
  print(cat(names(df), "is fractionally integrated at", d[i,]))
}
## TRYG.CO is fractionally integrated at 0.4NULL
## CARL-B.CO is fractionally integrated at 0.3NULL
## DSV.CO is fractionally integrated at 0.2NULL
## NOVO-B.CO is fractionally integrated at 0.2NULL
## CHR.CO is fractionally integrated at 0.4NULL
## VWS.CO is fractionally integrated at 0.4NULL
## RBREW.CO is fractionally integrated at 0.3NULL
## AMBU-B.CO is fractionally integrated at 0.5NULL
## NZYM-B.CO is fractionally integrated at 0.2NULL
## FLS.CO is fractionally integrated at 0.1NULL
## MAERSK-A.CO is fractionally integrated at 0.3NULL
## SIM.CO is fractionally integrated at 0.3NULL
## PNDORA.CO is fractionally integrated at 0.2NULL
## MAERSK-B.CO is fractionally integrated at 0.3NULL
## COLO-B.CO is fractionally integrated at 0.3NULL
## ROCK-B.CO is fractionally integrated at 0.5NULL
## LUN.CO is fractionally integrated at 0.4NULL
## GN.CO is fractionally integrated at 0.3NULL
## DANSKE.CO is fractionally integrated at 0.3NULL
## JYSK.CO is fractionally integrated at 0.3NULL

For some reason, when the function print and cat are used in conjuntion, it adds an ugly NULL at the end of each message. Sad.

Now the chosen parameter d is used to difference each stock.

d_data <- Data
for(i in 1:20){
  d_data[,i] <- diff_series(Data[,i], d[i,])
}

To confirm the new data is actually stationary I run the ADF-test again and print the p-value. For the sake of not wasting too much space, only the last five stocks are tested.

for(i in 16:20){
  print(adf(d_data[,i]))
}
## [1] 0.01885751
## [1] 0.0142221
## [1] 0.02229423
## [1] 0.03928629
## [1] 0.02162842

All five stock were significantly stationary within 5% significance.

plot(
  cbind(
    "Log Price" = Data[,6], 
    "Differenced Log Price" = d_data[,6]
  ),
  main       = colnames(Data[,6]),
  grid.col   = "white",
  legend.loc = "right"
)

Quite the difference overall given we’ve still managed to save some of the long memory in the data.