Как выполнить агрегацию предыдущих тиков без агрегата Trades из высокочастотного пакета

Мне нужно выполнить предыдущую агрегацию тиков на моем наборе тиковых данных за 5-минутные интервалы. Обратите внимание, что я хочу сделать аналогично функции aggregateTrades() в высокочастотном пакете. Но мне нужно решить эту проблему без использования высокочастотного пакета из-за некоторых других проблем обработки данных. Это мой набор данных:

dput(tt)
structure(c(1371.25, NA, 1373.95, NA, NA, 1373, NA, 1373.95, 
1373.9, NA, NA, 1374, 1374.15, NA, 1374, 1373.85, 1372.55, 1374.05, 
1374.15, 1374.75, NA, NA, 1375.9, 1374.05, NA, NA, NA, NA, NA, 
NA, NA, 1375, NA, NA, NA, NA, NA, 1376.35, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, 1376.25, NA, 1378, 1376.5, NA, NA, NA, 1378, 
1378, NA, NA, 1378.8, 231.9, 231.85, NA, 231.9, 231.85, 231.9, 
231.8, 231.9, 232.6, 231.95, 232.35, 232, 232.1, 232.05, 232.05, 
232.05, 231.5, 231.3, NA, NA, 231.1, 231.1, 231.1, 231, 231, 
230.95, 230.6, 230.6, 230.7, 230.6, 231, NA, 231, 231, 231.45, 
231.65, 231.4, 231.7, 231.3, 231.25, 231.25, 231.4, 231.4, 231.85, 
231.75, 231.5, 231.55, 231.35, NA, 231.5, 231.5, NA, 231.5, 231.25, 
231.15, 231, 231, 231, 231.05, NA), .indexCLASS = c("POSIXct", 
"POSIXt"), tclass = c("POSIXct", "POSIXt"), .indexTZ = "Asia/Calcutta", tzone = "Asia/Calcutta", index = structure(c(1459481850, 
1459482301, 1459482302, 1459482303, 1459482304, 1459482305, 1459482306, 
1459482307, 1459482309, 1459482310, 1459482311, 1459482312, 1459482314, 
1459482315, 1459482316, 1459482317, 1459482318, 1459482319, 1459482320, 
1459482321, 1459482322, 1459482323, 1459482324, 1459482326, 1459482328, 
1459482329, 1459482330, 1459482331, 1459482332, 1459482336, 1459482337, 
1459482338, 1459482339, 1459482342, 1459482344, 1459482346, 1459482347, 
1459482348, 1459482349, 1459482350, 1459482351, 1459482354, 1459482355, 
1459482356, 1459482357, 1459482358, 1459482359, 1459482362, 1459482363, 
1459482364, 1459482369, 1459482370, 1459482371, 1459482372, 1459482373, 
1459482378, 1459482379, 1459482380, 1459482382, 1459482388), tzone = "Asia/Calcutta", tclass = c("POSIXct", 
"POSIXt")), .Dim = c(60L, 2L), .Dimnames = list(NULL, c("A", 
"B")), class = c("xts", "zoo"))

Это мой код для предыдущего агрегирования тиков:

ag.5min.tt<-tt%>%filter(as.Date(index(tt)))%>%lapply(aggregate(by=cut(format(index(tt), format = "%H:%M:%S"), breaks = "5 mins", Fun=tail)))

То, что я пытаюсь сделать с помощью приведенного выше кода, это делать 5-минутные интервалы каждый день для цен A и B. Но я получаю ошибку. Пожалуйста, предложите, как исправить эту ошибку:

Error in UseMethod("filter_") : 
  no applicable method for 'filter_' applied to an object of class "c('xts', 'zoo')" 

Благодарю.

Редактировать: Преобразование объекта xts в фрейм данных:

tt<-as.data.frame(tt)
tt<-data.frame(Time=rownames(tt), coredata(tt))
ag.5min.tt<-tt%>% filter(as.Date(index(tt)))%>%lapply(aggregate(by=cut(format(index(tt), format = "%H:%M:%S"), breaks = "5 mins", Fun=tail)))

Новая ошибка:

Error in eval(substitute(expr), envir, enclos) : 
  filter condition does not evaluate to a logical vector. 

Изменить: попытка:

tt$Time<- as.POSIXct(tt$Time, format="%Y-%m-%d %H:%M:%S")
ag.5min.tt<-tt%>% group_by(Time==as.Date(tt$Time))%>%lapply(aggregate(by=cut(format(tt$Time, format = "%H:%M:%S"), breaks = "5 mins", Fun=tail)))

Ошибка:

Error in cut.default(format(tt$Time, format = "%H:%M:%S"), breaks = "5 mins",  : 
  'x' must be numeric
In addition: Warning message:
In eval(substitute(expr), envir, enclos) :
  Incompatible methods ("Ops.POSIXt", "Ops.Date") for "=="

Результат будет выглядеть так. Каждая пятиминутная отметка времени будет иметь значения для этой конкретной отметки времени или, если существует NA, отметка времени будет иметь последнее значение, отличное от NA, для акций A и B

  time                  A      B
1 2016-04-01 09:00:00      NA    NA
2 2016-04-01 09:05:00      NA    NA
3 2016-04-01 09:10:00      NA    NA
4 2016-04-01 09:15:00 1371.25 231.90
5 2016-04-01 09:20:00 1376.35 231.55

2 ответа

Решение

Ты можешь использовать .indexmin чтобы проиндексировать ваш временной ряд по минутам, а затем манипулировать этим индексом для подмножеств наблюдения:

ind <- which(diff(.indexmin(tt) %% 5) == -4)
res <- tt[ind]

Вот, .indexmin(tt) %% 5 вернет количество минут с последней пятой минуты. Для наших целей мы хотим извлечь из этого последний индекс из каждой серии 4s, который является последним наблюдением за минуту, предшествующую каждой пятой минуте. Для этого мы можем использовать diff и просто извлечь индекс, для которого есть переход от 4 в 0 (в результате чего diff из -4) с помощью which,

Чтобы проиллюстрировать это, мы изменим ваши опубликованные данные, добавив наблюдения, которые на самом деле удовлетворяют вашим условиям извлечения:

tt <- structure(c(1371.25, NA, 1373.95, NA, NA, 1373, NA, 1373.95, 
            1373.9, NA, NA, 1374, 1374.15, NA, 1374, 1373.85, 1372.55, 1374.05, 
            1374.15, 1374.75, NA, NA, 1375.9, 1374.05, NA, NA, NA, NA, NA, 
            NA, NA, 1375, NA, NA, NA, NA, NA, 1376.35, NA, NA, NA, NA, NA, 
            NA, NA, NA, NA, NA, 1376.25, NA, 1378, 1376.5, NA, NA, NA, 1378, 
            1378, NA, NA, 1378.8, 231.9, 231.85, NA, 231.9, 231.85, 231.9, 
            231.8, 231.9, 232.6, 231.95, 232.35, 232, 232.1, 232.05, 232.05, 
            232.05, 231.5, 231.3, NA, NA, 231.1, 231.1, 231.1, 231, 231, 
            230.95, 230.6, 230.6, 230.7, 230.6, 231, NA, 231, 231, 231.45, 
            231.65, 231.4, 231.7, 231.3, 231.25, 231.25, 231.4, 231.4, 231.85, 
            231.75, 231.5, 231.55, 231.35, NA, 231.5, 231.5, NA, 231.5, 231.25, 
            231.15, 231, 231, 231, 231.05, NA), .indexCLASS = c("POSIXct", 
                                                                "POSIXt"), tclass = c("POSIXct", "POSIXt"), .indexTZ = "Asia/Calcutta", tzone = "Asia/Calcutta", index = structure(c(1459482299, 
                                                                                                                                                                                     1459482301, 1459482302, 1459482303, 1459482304, 1459482305, 1459482306, 
                                                                                                                                                                                     1459482307, 1459482309, 1459482310, 1459482311, 1459482312, 1459482314, 
                                                                                                                                                                                     1459482315, 1459482316, 1459482317, 1459482318, 1459482319, 1459482320, 
                                                                                                                                                                                     1459482321, 1459482322, 1459482323, 1459482324, 1459482326, 1459482328, 
                                                                                                                                                                                     1459482329, 1459482330, 1459482331, 1459482332, 1459482336, 1459482337, 
                                                                                                                                                                                     1459482338, 1459482339, 1459482342, 1459482344, 1459482346, 1459482347, 
                                                                                                                                                                                     1459482348, 1459482349, 1459482590, 1459482591, 1459482594, 1459482595, 
                                                                                                                                                                                     1459482596, 1459482597, 1459482598, 1459482599, 1459482602, 1459482603, 
                                                                                                                                                                                     1459482604, 1459482609, 1459482610, 1459482611, 1459482612, 1459482613, 
                                                                                                                                                                                     1459482618, 1459482619, 1459482620, 1459482622, 1459482628), tzone = "Asia/Calcutta", tclass = c("POSIXct", 
                                                                                                                                                                                                                                                                                      "POSIXt")), .Dim = c(60L, 2L), .Dimnames = list(NULL,c("A", 
                                                                                                                                                                                                                                                                                                                                              "B")), class = c("xts", "zoo"))
##                          A      B
##2016-04-01 09:14:59 1371.25 231.90
##2016-04-01 09:15:01      NA 231.85
##2016-04-01 09:15:02 1373.95     NA
##2016-04-01 09:15:03      NA 231.90
##2016-04-01 09:15:04      NA 231.85
##2016-04-01 09:15:05 1373.00 231.90
##2016-04-01 09:15:06      NA 231.80
##2016-04-01 09:15:07 1373.95 231.90
##2016-04-01 09:15:09 1373.90 232.60
##2016-04-01 09:15:10      NA 231.95
##2016-04-01 09:15:11      NA 232.35
##2016-04-01 09:15:12 1374.00 232.00
##2016-04-01 09:15:14 1374.15 232.10
##2016-04-01 09:15:15      NA 232.05
##2016-04-01 09:15:16 1374.00 232.05
##2016-04-01 09:15:17 1373.85 232.05
##2016-04-01 09:15:18 1372.55 231.50
##2016-04-01 09:15:19 1374.05 231.30
##2016-04-01 09:15:20 1374.15     NA
##2016-04-01 09:15:21 1374.75     NA
##2016-04-01 09:15:22      NA 231.10
##2016-04-01 09:15:23      NA 231.10
##2016-04-01 09:15:24 1375.90 231.10
##2016-04-01 09:15:26 1374.05 231.00
##2016-04-01 09:15:28      NA 231.00
##2016-04-01 09:15:29      NA 230.95
##2016-04-01 09:15:30      NA 230.60
##2016-04-01 09:15:31      NA 230.60
##2016-04-01 09:15:32      NA 230.70
##2016-04-01 09:15:36      NA 230.60
##2016-04-01 09:15:37      NA 231.00
##2016-04-01 09:15:38 1375.00     NA
##2016-04-01 09:15:39      NA 231.00
##2016-04-01 09:15:42      NA 231.00
##2016-04-01 09:15:44      NA 231.45
##2016-04-01 09:15:46      NA 231.65
##2016-04-01 09:15:47      NA 231.40
##2016-04-01 09:15:48 1376.35 231.70
##2016-04-01 09:15:49      NA 231.30
##2016-04-01 09:19:50      NA 231.25
##2016-04-01 09:19:51      NA 231.25
##2016-04-01 09:19:54      NA 231.40
##2016-04-01 09:19:55      NA 231.40
##2016-04-01 09:19:56      NA 231.85
##2016-04-01 09:19:57      NA 231.75
##2016-04-01 09:19:58      NA 231.50
##2016-04-01 09:19:59      NA 231.55
##2016-04-01 09:20:02      NA 231.35
##2016-04-01 09:20:03 1376.25     NA
##2016-04-01 09:20:04      NA 231.50
##2016-04-01 09:20:09 1378.00 231.50
##2016-04-01 09:20:10 1376.50     NA
##2016-04-01 09:20:11      NA 231.50
##2016-04-01 09:20:12      NA 231.25
##2016-04-01 09:20:13      NA 231.15
##2016-04-01 09:20:18 1378.00 231.00
##2016-04-01 09:20:19 1378.00 231.00
##2016-04-01 09:20:20      NA 231.00
##2016-04-01 09:20:22      NA 231.05
##2016-04-01 09:20:28 1378.80     NA

С этими данными мы получаем:

print(res)
##                          A      B
##2016-04-01 09:14:59 1371.25 231.90
##2016-04-01 09:19:59      NA 231.55

Чтобы получить вывод, который вы разместили, вам сначала нужно сгенерировать временной ряд, содержащий данные (для NA) за каждые 5 минут, которые вы хотите. Для этого примера этот временной ряд (только для 5-минутных тиков от 09:00 в 09:20 на 2016-04-01) может быть:

every.5.min <- structure(c(NA, NA, NA, NA, NA), .Dim = c(5L, 1L), .Dimnames = list(
NULL, "Empty"), index = structure(c(1459481400, 1459481700, 
1459482000, 1459482300, 1459482600), tzone = "Asia/Calcutta", tclass = c("POSIXct", 
"POSIXt")), class = c("xts", "zoo"), .indexCLASS = c("POSIXct", 
"POSIXt"), tclass = c("POSIXct", "POSIXt"), .indexTZ = "Asia/Calcutta", tzone = "Asia/Calcutta")
##                    Empty
##2016-04-01 09:00:00    NA
##2016-04-01 09:05:00    NA
##2016-04-01 09:10:00    NA
##2016-04-01 09:15:00    NA
##2016-04-01 09:20:00    NA

Затем, merge это с tt:

tt <- merge(tt, every.5.min, all=TRUE)[,1:ncol(tt)]

all=TRUE заполнит строки в оригинале tt с NA если эта строка (т.е. каждые 5 минут) не существует в tt, Заметьте, что после слияния мы сохраняем только столбцы tt,

Затем более tt, заполните все NA с предыдущими значениями, как вы сделали:

res <- do.call(merge, lapply(tt, na.locf))

Наконец, извлекайте только те строки для каждого 5-минутного тика .indexmin а также .indexsec:

res <- res[.indexmin(res) %% 5 == 0 & .indexsec(res) == 0]
##                          A      B
##2016-04-01 09:00:00      NA     NA
##2016-04-01 09:05:00      NA     NA
##2016-04-01 09:10:00      NA     NA
##2016-04-01 09:15:00 1371.25 231.90
##2016-04-01 09:20:00 1376.35 231.55

Измените объект xts на фрейм данных для работы с dplyr

library(dplyr)
library(tibble)
library(xts)
library(tidyr)
dtf <- tt %>% 
    as.data.frame() %>%
    # add time information
    rownames_to_column("time") %>%
    mutate(time = as.POSIXct(time))

Генерация вектора времени для выбора каждые 5 минут (300 секунд) между минимальным и максимальным временем

timepick <- seq(trunc(min(dtf$time),"hour"), # start at the hour
                max(dtf$time)+300 , 300)

Используйте вектор разрывов, чтобы выбрать последнее доступное наблюдение за каждые 5 минут.

ag.5min.tt <- dtf %>%
    # Add missing interval
    full_join(data_frame(time = timepick), by = "time") %>%
    arrange(time) %>% # important to arrange by time here
    # Replace each NA with the most recent non-NA
    fill(-time) %>% 
    # take selected values only
    filter(time %in% timepick) 

Преобразовать обратно в объект XTS

ag.5min.tt <- ag.5min.tt %>% 
    as.data.frame() %>% 
    column_to_rownames("time") %>% 
    as.xts()
ag.5min.tt

                          A      B
2016-04-01 09:00:00      NA     NA
2016-04-01 09:05:00      NA     NA
2016-04-01 09:10:00 1371.25 231.90
2016-04-01 09:15:00 1371.25 231.90
2016-04-01 09:20:00 1378.80 231.05
Другие вопросы по тегам