xts icon indicating copy to clipboard operation
xts copied to clipboard

Proposed Time Shift/Lag Function

Open rossb34 opened this issue 6 years ago • 4 comments

I propose adding functionality to shift or lag the index of an xts object by a specified number of seconds. This is similar to lag.xts, but the key difference is shifting by units of time (e.g. seconds) rather than an index. This is particularly useful for irregular time series such as high frequency market data.

Here is a prototype function that provides the proposed functionality.

timeshift <- function (x, k = 1)
{
    offset.xts <- .xts(, .index(x) + k)
    m <- merge(offset.xts, merge(offset.xts, x, fill = na.locf), join = "left")
    .index(m) <- .index(x)
    if (is.null(dimnames(x)[[2L]]))
        dimnames(m) <- NULL
    m
}

rossb34 avatar May 10 '18 17:05 rossb34

One thing I've considered is allowing the k argument to lag.xts() to be specified like n can be in last.xts(). Here's an example of last.xts():

require(xts)
data(sample_matrix)
x <- as.xts(sample_matrix, dateFormat = "Date")
last(x, "week")  # may also be preceded by a number (e.g. "2 weeks")
#                Open     High      Low    Close
# 2007-06-25 47.20471 47.42772 47.13405 47.42772
# 2007-06-26 47.44300 47.61611 47.44300 47.61611
# 2007-06-27 47.62323 47.71673 47.60015 47.62769
# 2007-06-28 47.67604 47.70460 47.57241 47.60716
# 2007-06-29 47.63629 47.77563 47.61733 47.66471
# 2007-06-30 47.67468 47.94127 47.67468 47.76719

So if lag.xts() is called with that type of k, it would do what I imagine timeshift() does.

Thoughts?

joshuaulrich avatar May 11 '18 15:05 joshuaulrich

Here is a quick example that demonstrates the functionality. The function allows one to answer the question, "For each observation, what is the value k seconds in the future?"

x <- .xts(rnorm(10), c(1, 2, 2.4, 2.5, 4, 4.2, 4.5, 4.6, 5.2, 6),
          dimnames = list(NULL, "price"))

# the price 2 seconds in the future
x$price.future <- timeshift(x, 2)

rossb34 avatar May 17 '18 18:05 rossb34

I don't like the inconsistency with lag.xts my initial prototype introduces. Note the negative k in lag.xts and positive k in timeshift.

# lagging by time and lagging by an index are equivalent on regularly spaced seconds
x <- .xts(1:5, 1:5 + 0.0)
lag(x, k = -1)
timeshift(x, k = 1)

I think it would be better to name the function timelag and treat k the same as in lag.xts. This can be handled simply by subtracting k from the index.

timelag<- function (x, k = 1)
{
    offset.xts <- .xts(, .index(x) - k)
    m <- merge(offset.xts, merge(offset.xts, x, fill = na.locf), join = "left")
    .index(m) <- .index(x)
    if (is.null(dimnames(x)[[2L]]))
        dimnames(m) <- NULL
    m
}

# equivalent
lag(x, k = 1)
timelag(x, k = 1)

rossb34 avatar May 17 '18 21:05 rossb34

I agree that we should probably roll this into lag.xts with e.g. lag.xts(x, k = "5 seconds"). For now, I'll just implement it as a separate function while I think about that.

rossb34 avatar May 17 '18 21:05 rossb34