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
[email protected]
[[alternative HTML version deleted]]
_______________________________________________
[email protected] mailing list
https://stat.ethz.ch/mailman/listinfo/r-sig-finance
-- Subscriber-posting only. If you want to post, subscribe first.
-- Also note that this is not the r-help list where general R questions should
go.