开发者

Rollapply & xts. Can I output the time of max value in the window?

开发者 https://www.devze.com 2023-04-10 08:35 出处:网络
I\'m studying some yahoo finance data via quantmod. How would I determine not only the Max and Min price over a rolling window of data, but also the exact Timestamp of those highs and lows? I have tr

I'm studying some yahoo finance data via quantmod.

How would I determine not only the Max and Min price over a rolling window of data, but also the exact Timestamp of those highs and lows? I have tried which.max() with rollapply but this only reports the seq of the value in the rolling window itself, and not the .index() of the row that holds the timestamp.

Can anyone suggest a solution?

a reproducible example is below, and some sample output I'd like to have...

> library(quantmod)
> getSymbols("BET.L")
xmin <- rollapply(BET.L$BET.L.Close,10,min, ascending = TRUE)
names(xmin) <- "MinClose"

xmax <- rollapply(BET.L$BET.L.Close,10,max, ascending = TRUE)
开发者_运维技巧names(xmax) <- "MaxClose"

head(cbind(BET.L$BET.L.Close, as.xts(xmax), as.xts(xmin)),15)
           BET.L.Close MaxClose MinClose
2010-10-22     1550.00       NA       NA
2010-10-25     1546.57       NA       NA
2010-10-26     1545.00       NA       NA
2010-10-27     1511.26       NA       NA
2010-10-28     1490.00  1550.00     1395
2010-10-29     1435.00  1546.57     1381
2010-11-01     1447.00  1545.00     1347
2010-11-02     1420.00  1511.26     1347
2010-11-03     1407.00  1490.00     1347
2010-11-04     1395.00  1447.00     1347
2010-11-05     1381.00  1447.00     1347
2010-11-08     1347.00  1490.00     1347
2010-11-09     1415.00  1490.00     1347
2010-11-10     1426.00  1490.00     1347
2010-11-11     1430.00  1490.00     1347

and the type of output I would like to generate would look something like:

           BET.L.Close MaxClose MinClose    MaxDate    MinDate
2010-10-22     1550.00       NA       NA      NA       NA
2010-10-25     1546.57       NA       NA      NA       NA
2010-10-26     1545.00       NA       NA      NA       NA
2010-10-27     1511.26       NA       NA      NA       NA
2010-10-28     1490.00  1550.00     1395 2010-10-22 2010-11-04
2010-10-29     1435.00  1546.57     1381 2010-10-25 2010-11-05

Ideally any approach I take must cater for the fact of duplicate prices which is common, and in this case I would order my window to take the first of the max values, and the last of the min values.


There is a big problem with this plan. The coredata element is a matrix, hence all elements must be classless and of the same mode. You cannot have objects of Date class in an xts object, and if you insist on a character class then it will force all of the other elements to also be character. So with that understood it's still possible to do something by calculating the which.max result, then creating a row-number from which that which.max-value is an offset, and finally using that result as an index into the index of the object. (Sorry for the double uses of "which" and "index". Hope the meaning is clear from the code.)

xmin <- rollapply(BET.L$BET.L.Close,10,min)
names(xmin) <- "MinClose"

xmax <- rollapply(BET.L$BET.L.Close,10,max, ascending = TRUE)
names(xmax) <- "MaxClose"
head(dat <- cbind(BET.L$BET.L.Close, as.xts(xmax), as.xts(xmin)),15))

w.MaxDate <- rollapply(BET.L$BET.L.Close,10, which.max)
names(w.MaxDate) <- "w.maxdt"
dat <- cbind(dat, as.xts(w.MaxDate) )
dat<-cbind(dat,as.xts(seq.int(236), order.by=index(dat)))
> head(dat)
           BET.L.Close MaxClose MinClose       w.maxdt ..2
2010-10-22     1550.00       NA       NA            NA   1
2010-10-25     1546.57       NA       NA            NA   2
2010-10-26     1545.00       NA       NA            NA   3
2010-10-27     1511.26       NA       NA            NA   4
2010-10-28     1490.00  1550.00     1395             1   5
2010-10-29     1435.00  1546.57     1381             1   6
dat$maxdate <- xts( index(dat)[dat$..2-5+dat$BET.L.Close.1], order.by=index(dat))
> head(dat)
           BET.L.Close MaxClose MinClose       w.maxdt ..2 maxdate
2010-10-22     1550.00       NA       NA            NA   1      NA
2010-10-25     1546.57       NA       NA            NA   2      NA
2010-10-26     1545.00       NA       NA            NA   3      NA
2010-10-27     1511.26       NA       NA            NA   4      NA
2010-10-28     1490.00  1550.00     1395             1   5   14904
2010-10-29     1435.00  1546.57     1381             1   6   14907

So I got you the integer representation of the date. You can see that they are the correct values by just looking at the head of the input vector:

> head(index(dat)[dat$..2-5+dat$w.maxdt])
[1] NA           NA           NA           NA           "2010-10-22" "2010-10-25"


I think you can add one more numeric column representing date to your original xts object and then use rollapply. Look at xminmax from example below:

require(quantmod)
getSymbols("BET.L")

## add Date as numeric
BET.L$dt <- as.numeric(format(index(BET.L), "%Y%m%d"))
xmin <- rollapply(BET.L, 10, align='r', by.column = FALSE,
    FUN = function(dw)
        return(dw[which.min(dw[,'BET.L.Close']), c('BET.L.Close', 'dt')])
    )
xmax <- rollapply(BET.L, 10, align='r', by.column = FALSE,
    FUN = function(dw)
        return(dw[which.max(dw[,'BET.L.Close']), c('BET.L.Close', 'dt')])
    )

xminmax <- cbind(xmin, xmax)
## to get back to dates use: 
##  as.Date(as.character(as.integer(xminmax$dt.xmin)), format = "%Y%m%d")

## left edge of data window
x_ldt <- rollapply(BET.L$dt, 10, align='r', function(dw) return(dw[1]))

Results:

head(xminmax)
           BET.L.Close.xmin  dt.xmin BET.L.Close.xmax  dt.xmax
2010-11-04             1395 20101104          1550.00 20101022
2010-11-05             1381 20101105          1546.57 20101025
2010-11-08             1347 20101108          1545.00 20101026
2010-11-09             1347 20101108          1511.26 20101027
2010-11-10             1347 20101108          1490.00 20101028
2010-11-11             1347 20101108          1447.00 20101101
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号