使用自定义开始时间创建每日OHLC

时间:2017-08-03 17:26:36

标签: r xts zoo

我有15分钟的OHLC数据,想要转换为每日OHLC

  • 但是当天17:00:00开始。

  • 这样,生成的每日栏应该从17:00:00到17:00:00,而不是从00:00:00到00:00:00

_

x <- zoo(runif(25), order.by=seq(
                             as.POSIXct("2010-05-03 17:00:00"), 
                             as.POSIXct("2010-05-06 17:00:00"), 
                             by="15 min"
                             )
     )

_

head(x)

2010-05-03 17:00:00 0.9788685
2010-05-03 17:15:00 0.5414294
2010-05-03 17:30:00 0.8435366
2010-05-03 17:45:00 0.3064713
2010-05-03 18:00:00 0.1395849
2010-05-03 18:15:00 0.9916730

使用xts:将周期从15米改为60米非常有效:

x_agg <- to.minutes(x,k=60, indexAt="startof")
head(x_agg)

                       x.Open    x.High      x.Low   x.Close
2010-05-03 17:00:00 0.9788685 0.9788685 0.30647133 0.3064713
2010-05-03 18:00:00 0.1395849 0.9916730 0.09497550 0.5301038
2010-05-03 19:00:00 0.3580554 0.4264711 0.11728640 0.1172864
2010-05-03 20:00:00 0.9791394 0.9791394 0.01904849 0.1643573
2010-05-03 21:00:00 0.3096280 0.9193756 0.30962797 0.8896507
2010-05-03 22:00:00 0.8125618 0.8976714 0.74335042 0.7433504

使用xts:将周期从15m更改为 1440m = 1Day不起作用

x_agg <- to.minutes(x,k=1440, indexAt="startof")
head(x_agg)

_

                       x.Open   x.High      x.Low    x.Close
2010-05-03 17:00:00 0.9788685 0.991673 0.01904849 0.38669801
2010-05-04 02:00:00 0.1172864 0.991673 0.01904849 0.09497550
2010-05-05 02:00:00 0.5301038 0.991673 0.01904849 0.84353659
2010-05-06 02:00:00 0.3064713 0.991673 0.01904849 0.01904849

我不知道为什么索引变为02:00:00 - 所有日子都应该是17:00:00。

如何做到这一点 - 使用xts? 谢谢你的努力。

dput(x_agg)
structure(c(0.97886852407828, 0.117286398308352, 0.530103818513453, 
0.306471328716725, 0.991673005977646, 0.991673005977646, 0.991673005977646, 
0.991673005977646, 0.0190484928898513, 0.0190484928898513, 0.0190484928898513, 
0.0190484928898513, 0.386698011076078, 0.0949754973407835, 0.843536590691656, 
0.0190484928898513), .Dim = c(4L, 4L), .Dimnames = list(NULL, 
c("x.Open", "x.High", "x.Low", "x.Close")), index = structure(c(1272898800, 
1272931200, 1273017600, 1273104000), class = c("POSIXct", "POSIXt"
), tzone = ""), class = "zoo")

1 个答案:

答案 0 :(得分:2)

Most (all?) xts functions define time intervals using the endpoints() function, which creates the intervals based on offsets from the epoch. This is usually desirable, because it finds/creates breaks at round units of time (at the change of a minute, hour, etc).

If I understand correctly, you want intervals defined by the first observation in your data. I can see how you would expect endpoints at 17:00:00, since that's the hour and minute of your first observation. I'm not sure you would have the same expectation if your first observation was at an irregular time like 17:01:32.741.

So, that's the backstory, and therefore I can't think of an easy/straight-forward way to get the result you want. But here's an attempt at a kludge, using period.apply() with custom endpoints and function.

# custom aggregation function to convert a chunk of data to one OHLC observation
toOHLC <- function(x) {
  op <- as.vector(first(x))
  hl <- range(x, na.rm = TRUE)
  cl <- as.vector(last(x))
  xts(cbind(Open = op, High = hl[2], Low = hl[1], Close = cl), end(x))
}

Now a hack to get endpoints for days defined by 17:00.

# Convert to xts
y <- as.xts(x)
# Convert index to UTC
indexTZ(y) <- "UTC"
# Set first observation to epoch (zero)
.index(y) <- .index(y) - .index(y)[1]
# Get endpoints for y by day
ep <- endpoints(y, "days")

Now you can use ep in your call to period.apply() to get OHLC by days, where 17:00:00 is the breakpoint.

period.apply(x, ep, toOHLC)
#                          Open      High        Low      Close
# 2010-05-04 16:45:00 0.6415173 0.8440296 0.01497329 0.84402960
# 2010-05-05 16:45:00 0.8411363 0.8440296 0.01497329 0.08874158
# 2010-05-06 16:45:00 0.7843095 0.8440296 0.01497329 0.40912559
# 2010-05-06 17:00:00 0.5669512 0.5669512 0.56695121 0.56695121