Reputation: 2085
I am trying to convert xts time series data to lower periodicity in a cumulative way.
For example, using to.weekly on sample data (sample_matrix) from xts package I get this:
library(xts)
data(sample_matrix)
to.weekly(as.xts(sample_matrix), name="")
> to.weekly(as.xts(sample_matrix), name="")
.Open .High .Low .Close
2007-01-08 50.03978 50.42188 49.95041 49.98806
2007-01-15 49.99489 50.68583 49.80454 50.48912
.....
I would like to be able to use a slightly different function to.weekly.cumulative that would instead return this:
> to.weekly.cumulative(as.xts(sample_matrix), name="")
.Open .High .Low .Close
2007-01-02 50.03978 50.11778 49.95041 50.11778
2007-01-03 50.03978 50.42188 49.95041 50.39767
2007-01-04 50.03978 50.42188 49.95041 50.33236
2007-01-05 50.03978 50.42188 49.95041 50.33459
2007-01-06 50.03978 50.42188 49.95041 50.18112
2007-01-07 50.03978 50.42188 49.95041 49.99185
2007-01-08 50.03978 50.42188 49.95041 49.98806
2007-01-09 49.99489 49.99489 49.80454 49.91333
2007-01-10 49.99489 50.13053 49.80454 49.97246
2007-01-11 49.99489 50.23910 49.80454 50.23910
2007-01-12 49.99489 50.35980 49.80454 50.28519
2007-01-13 49.99489 50.48000 49.80454 50.41286
2007-01-14 49.99489 50.62395 49.80454 50.60145
2007-01-15 49.99489 50.68583 49.80454 50.48912
....
This function would not return the data only for the endpoints but for all the rows in the xts object. For example, what I am trying to get is a weekly bars from daily bars (or 15 minute bars from 1 minute bars) in such a way that for every day (or minute) I get the current (from that day/minute) development of the weekly (15 minute) bar. So, on Monday I would get as a weekly bar Open, High, Low, Close exactly as they were on Monday, on Tuesday Open will be from Monday, Close will be from Tuesday, and High would be Tuesday High if greater than Monday High and Low would be Tuesday Low if lower than Monday Low ... and on Friday I would get Open from Monday, High as High of the whole week, Low the low of the whole week and Close Close of Friday. Data fro Friday should be the same if I would use to.weekly function from xts.
So, basically, this is not just the data at the endpoints (like xts to.weekly does) but all along the time steps available at the periodicity of the original xts object. So somehow a movie of the development of weekly bar through days (on each day I get where the weekly bar stands on close of each week).
How to do that (How to write function to.weekly.cumulative?)?
Examples on how to do this highly appreciated.
EDIT: Tried to explain a bit more based on DWin comment.
Upvotes: 3
Views: 2420
Reputation: 49810
Split on "weeks", apply a custom function to each week's data, then rbind the results
to.weekly.cumulative <- function(xts.obj, name="") {
out <- do.call(rbind,
lapply(split(xts.obj, 'weeks'),
function(x) cbind(rep(first(x[,1]), NROW(x[,1])),
cummax(x[,2]), cummin(x[,3]), x[,4])))
colnames(out) <- paste(name, c("Open", "High", "Low", "Close"), sep=".")
out
}
> library(quantmod)
> data(sample_matrix)
> myxts <- as.xts(sample_matrix)
> head(to.weekly.cumulative(myxts), 15)
.Open .High .Low .Close
2007-01-02 50.03978 50.11778 49.95041 50.11778
2007-01-03 50.03978 50.42188 49.95041 50.39767
2007-01-04 50.03978 50.42188 49.95041 50.33236
2007-01-05 50.03978 50.42188 49.95041 50.33459
2007-01-06 50.03978 50.42188 49.95041 50.18112
2007-01-07 50.03978 50.42188 49.95041 49.99185
2007-01-08 50.03555 50.10363 49.96971 49.98806
2007-01-09 50.03555 50.10363 49.80454 49.91333
2007-01-10 50.03555 50.13053 49.80454 49.97246
2007-01-11 50.03555 50.23910 49.80454 50.23910
2007-01-12 50.03555 50.35980 49.80454 50.28519
2007-01-13 50.03555 50.48000 49.80454 50.41286
2007-01-14 50.03555 50.62395 49.80454 50.60145
2007-01-15 50.61724 50.68583 50.47359 50.48912
2007-01-16 50.61724 50.73731 50.47359 50.67835
Upvotes: 1
Reputation: 66842
Not sure if this is what you want, but maybe you can do that work by:
wday
) for the timeseries.rollapplyr
using the wday
as the window width.here is an example:
z <- as.xts(sample_matrix)
wday <- .indexwday(z) + 1
wday <- (wday-3)%%7 + 1 # rotate the wday index if need.
z2 <- data.frame(
Open = rollapplyr(z$Open, wday, function(x) x[1], partial = TRUE),
High = rollapplyr(z$High, wday, max, partial = TRUE),
Low = rollapplyr(z$Low, wday, min, partial = TRUE),
Close = z$Close
)
z2
is like this:
> head(z2, 15)
Open High Low Close
2007-01-02 50.03978 50.11778 49.95041 50.11778
2007-01-03 50.03978 50.42188 49.95041 50.39767
2007-01-04 50.03978 50.42188 49.95041 50.33236
2007-01-05 50.03978 50.42188 49.95041 50.33459
2007-01-06 50.03978 50.42188 49.95041 50.18112
2007-01-07 50.03978 50.42188 49.95041 49.99185
2007-01-08 50.03978 50.42188 49.95041 49.98806
2007-01-09 49.99489 49.99489 49.80454 49.91333
2007-01-10 49.99489 50.13053 49.80454 49.97246
2007-01-11 49.99489 50.23910 49.80454 50.23910
2007-01-12 49.99489 50.35980 49.80454 50.28519
2007-01-13 49.99489 50.48000 49.80454 50.41286
2007-01-14 49.99489 50.62395 49.80454 50.60145
2007-01-15 49.99489 50.68583 49.80454 50.48912
2007-01-16 50.62024 50.73731 50.56627 50.67835
Upvotes: 2