rtime-series

How to align the time-series data set with the common trading dasys among them and remove aother days


Using their daily close prices, I want to model the dependency among five major indices, the SP500, SSEC, HSI, TASI, and DAX. I need to align the three-time series with the common trading days among them and omit other days.

Here is my attempt which always results in an error:

library(quantmod)

# Fetch daily close prices
sp500 <- getSymbols("^GSPC", src = "yahoo", auto.assign = FALSE, from = "2017-10-09", to = "2022-09-29")
ssec <- getSymbols("000001.SS", src = "yahoo", auto.assign = FALSE, from = "2017-10-09", to = "2022-09-29")
hsi <- getSymbols("^HSI", src = "yahoo", auto.assign = FALSE, from = "2017-10-09", to = "2022-09-29")
tasi <- getSymbols("^TASI.SR", src = "yahoo", auto.assign = FALSE, from = "2017-10-09", to = "2022-09-29")
dax <- getSymbols("^GDAXI", src = "yahoo", auto.assign = FALSE, from = "2017-10-09", to = "2022-09-29")

# Align the data
all_dates <- Reduce(intersect, list(index(sp500), index(ssec), index(hsi), index(tasi), index(dax)))
sp500_aligned <- Cl(sp500)[all_dates]
ssec_aligned <- Cl(ssec)[all_dates]
hsi_aligned <- Cl(hsi)[all_dates]

Error

sp500_aligned <- Cl(sp500)[all_dates]
Error in [.xts(Cl(sp500), all_dates) : subscript out of bounds


Solution

  • The problem with the code in the question is that intersect strips the class from the dates. Although that is readily fixed we suggest a different approach based on merge.xts which supports multiway merges.

    1) Put the symbols' data in environment e and then use eapply to get a list of ticker data closes (or use Ad to get adjusted closes).
    Define and invoke mergeList which takes a list of one column xts objects, merges them and sets the names of the output to the original list names. Finally remove any rows that have one or more NA's using na.omit.

    library(quantmod)
    
    tickers <- c("^GSPC", "000001.SS", "^HSI", "^TASI.SR", "^GDAXI")
    getSymbols(tickers, env = e <- new.env(),
      from = "2017-10-09", to = "2022-09-29")
    
    mergeList <- \(x) do.call("merge", x) |> setNames(names(x))
    
    alldata <- e |>
      eapply(Cl) |>
      mergeList() |>
      na.omit()
    
    # rm(e)   # optional
    

    2) A variation of the above places the data in the global environment and then retrieves them. This has the advantage of being a single pipeline but does leave a bunch of loose objects hanging around in the global environment which is not as neat as keeping them all in a separate environment as in (1) although they could be deleted if unwanted as shown in the optional line below.

    alldata <- tickers |>
      getSymbols(from = "2017-10-09", to = "2022-09-29") |>
      mget(envir = .GlobalEnv) |>
      Map(f = Cl) |>
      mergeList() |>
      na.omit()
    
    # rm(list = names(alldata), envir = .GlobalEnv)   # optional
    

    Update

    Simplified and fixed. Add (2).