1
votes

How can I make a rolling window / loop (look-back period 30 days / data points) while ranking the data with base::rank? See below that the apply.rolling function seems not to work.

See example below:

# example data
require(xts)
set.seed(3)    
A    <- matrix(runif(900, max=30), ncol=3)
Data <- xts(A, Sys.Date()-300:1)
names(Data) <- c("C1", "C2", "C3")

This results in (only last 7 days / data points are shown):

2016-06-20 16.71131510 12.80074552 19.27525535
2016-06-21 22.92512330 25.11613536 17.45237229
2016-06-22 20.09403965 17.20945809 28.06481040
2016-06-23 28.68593738  4.84698272 18.36108782
2016-06-24 15.52956209 25.54946621  3.97892474
2016-06-25 25.76582707 18.14117193  8.17883282
2016-06-26 25.23925100 16.07418907 15.35118717

I select only the last 30 data points:

rolldata30 <- tail(Data[,2:3], 30)
rollindex30 <- tail(Data[,1], 30)

I rank the data (last 30 data points) of vector C2 and C3 based on their original values. Thus this is the period 2016-05-28 until 2016-6-26. Then I make a new vector which calculates an average of the two. factorx shows the result I am interested in.

rank30 <- as.xts(apply(-rolldata30, 2, rank, na.last= "keep"))
factor <- cbind(rollindex30, global = rowMeans(rank30))
factorx <- last(factor)

Which results in:

2016-06-20 16.711315   14.5
2016-06-21 22.925123    9.5
2016-06-22 20.094040    9.0
2016-06-23 28.685937   19.0
2016-06-24 15.529562   15.0
2016-06-25 25.765827   18.5
2016-06-26 25.239251   17.0

with data on the last day:

           C1        global
2016-06-26 25.23925     17

How can I make the calculation rolling in order to make the same calculation for 2016-5-27 until 2016-06-26, 2016-05-26 until 2016-06-25, etc.?

Using PerformanceAnalytics::apply.rolling gives an error:

Error in xts(x, order.by = order.by, frequency = frequency, .CLASS = "double", : order.by requires an appropriate time-based object

require(PerformanceAnalytics)
test1 <- apply.rolling(Data, width=30, gap=30, by=1, FUN=function(x) as.xts(-x, 2, rank))

I made the following function. factorz gives the same result. Perhaps the function helps to make it rolling?

rollrank <- function(x)
{
  a <- tail(x, 30)
  b <- as.xts(apply(-a, 2, rank, na.last= "keep"))
  c <-  cbind(a, global = rowMeans(b))
  d <- last(c)
  return(d)
}
factorz <- rollrank(Data[,2:3])
1

1 Answers

1
votes

The FUN argument to apply.rolling doesn't make sense. I suspect you meant FUN = function(x) as.xts(apply(-x, 2, rank, na.last="keep")). But that still will not work because FUN returns an object with more than one row.

Your rollrank function comes very close to what you need, and I recommend you use rollapply instead of apply.rolling. I suggest that you make a function based on your first example, then pass that function to rollapply.

myrank <- function(x) {
  rolldata30 <- x[,2:3]
  rollindex30 <- x[,1]
  rank30 <- as.xts(apply(-rolldata30, 2, rank, na.last= "keep"))
  factor <- cbind(rollindex30, global = rowMeans(rank30))
  factorx <- last(factor)
  return(factorx)
}
test1 <- rollapply(Data, 30, myrank, by.column=FALSE)
tail(test1)
#                   C1 global
# 2016-06-23  7.806336   19.5
# 2016-06-24 17.456436   17.5
# 2016-06-25 29.196350   12.5
# 2016-06-26 25.185687   11.0
# 2016-06-27 19.775105    6.5
# 2016-06-28 12.067774   16.0