Hello R-Sig-Finance members:

I was wondering if anyone has contributed functions that are similar
to the zoo roll* functions but which operate on fixed-length time
windows?  For example, suppose I have a zoo-based object consisting
of the daily closing prices of a stock, and I wish to know for each
date, what was the volatility over the succeeding 30 calendar days?
Probably many people would settle for something like:
  rollapply (log(lag(P))-log(P), 21, sd, align="left") * sqrt(252)
(where P is the price series).  However, this is an approximation.
Not all periods of 30 calendar days include precisely 21 trading days.

This seems like an obvious enough question that I would think that it
has been asked (and answered) many times before, but I could not find
a reference to the recommended solution.

If no one has tackled this problem before, I might try to put together
a small library of functions that are like roll* but which operate
on fixed time windows.  I am including an example of one such function
below.

Matthew Clegg

ztw_sum <- function (X, delta, align="right", partial=FALSE) {
  # Zoo Time Window Sum
  #
  # On input, X is a zoo-based numeric vector and delta is a time
difference.
  # Constructs a zoo-based numeric vector of partial sums from X.  The
values
  # included in a partial sum are those whose associated timestamps are
  # within delta of the corresponding element from X.
  #
  # If align="right", then result[i] is a sum of those elements
  # X[j] such that
  #    0 <= timestamp[i] - timestamp[j] <= delta,
  # where timestamp[i] is the timestamp (index) associated with the
  # i-th element of X.  Conversely, if align="left", then result[i] is a
  # sum of those elements X[j] such that
  #    0 <= timestamp[j] - timestamp[i] <= delta.
  #
  # Parameters:
  # X:        A zoo-based numeric vector with a time-based index type.
  # delta:    An object of type difftime specifying the size of
  #           the time window.
  # align:    Specifies whether the sum for a given index should
  #           be computed using elements of lower timestamps ("right")
  #           or higher timestamps ("left").
  # partial:  If TRUE, then partial sums are computed for elements
  #           at the left (respectively, right) end of the vector.
  #
  # Returns a zoo-based numeric vector of partial sums.
  #
  # Running time is O(length(X)).

  if (!inherits(X, "zoo") || !inherits(coredata(X), "numeric")) {
    stop ("X must be a numeric vector of type zoo");
  } else if (delta <= 0) {
    stop ("delta must be positive");
  } else if ((align != "left") && (align != "right")) {
    stop ("align must be from c('left', 'right')");
  }

  timestamp <- index(X)
  R <- zoo(NA, order.by = timestamp); # The result vector
  sum <- 0;  # The current partial sum

  if (align == "right") {
    # Invariants:
    #   (a) 0 < i <= j <= length(X)
    #   (b) 0 <= timestamp(j) - timestamp(i) <= delta
    i <- 1;  # The leftmost index in the current window
    for (j in 1:length(X)) {
      if (!is.na(X[j])) {
        sum <- sum + as.numeric(X[j]);
      }
      while (timestamp[j] - timestamp[i] > delta) {
        if (!is.na(X[i])) {
          sum <- sum - as.numeric(X[i]);
        }
        i <- i+1;
      }
      if ((i > 1) || partial) {
        R[j] <- sum;
      }
    }
  } else { # align == "left"
    # Invariants:
    #   (a) 0 < j <= i <= length(X)
    #   (b) 0 <= timestamp(i) - timestamp(j) <= delta
    i <- length(X);  # The rightmost index in the current window
    for (j in length(X):1) {
      if (!is.na(X[j])) {
        sum <- sum + as.numeric(X[j]);
      }
      while (timestamp[i] - timestamp[j] > delta) {
        if (!is.na(X[i])) {
          sum <- sum - as.numeric(X[i]);
        }
        i <- i-1;
      }
      if ((i < length(X)) || partial) {
        R[j] <- sum;
      }
    }
  }

  R
}



-- 
Matthew Clegg
matthewcleggphd@gmail.com

	[[alternative HTML version deleted]]

