我有一个大型(150,000x7)数据框,我打算用它来进行金融市场的回溯测试和实时分析。数据代表投资工具每隔5分钟的条件(虽然确实存在漏洞)。它看起来像这样(但更长):
pTime Time Price M1 M2 M3 M4
1 1212108300 20:45:00 1.5518 12.21849 -0.37125 4.50549 -31.00559
2 1212108900 20:55:00 1.5516 11.75350 -0.81792 -1.53846 -32.12291
3 1212109200 21:00:00 1.5512 10.75070 -1.47438 -8.24176 -34.35754
4 1212109500 21:05:00 1.5514 10.23529 -1.06044 -8.46154 -33.24022
5 1212109800 21:10:00 1.5514 9.74790 -1.02759 -10.21978 -33.24022
6 1212110100 21:15:00 1.5513 9.31092 -1.17076 -11.97802 -33.79888
7 1212110400 21:20:00 1.5512 8.84034 -1.28428 -13.62637 -34.35754
8 1212110700 21:25:00 1.5509 8.07843 -1.63715 -18.24176 -36.03352
9 1212111000 21:30:00 1.5509 7.39496 -1.49198 -20.65934 -36.03352
10 1212111300 21:35:00 1.5512 7.65266 -1.03717 -18.57143 -34.35754
数据已预先加载到R中,但在我的反向测试期间,我需要按两个标准对其进行子集化:
第一个标准是一个滑动窗口,以避免窥视未来。窗口必须是这样的,在后面测试中每个新的5分钟间隔将整个窗口移动到未来5分钟。这部分我可以这样做:
require(zoo)
zooser <- zoo(x=tser$Close, order.by=as.POSIXct(tser$pTime, origin="1970-01-01"))
window(zooser, start=A, end=B)
第二个标准是另一个滑动窗口,但是可以滑过time of day
并且仅包含输入时间<{1>}分钟内<{1}}分钟内的条目任何一天。
示例:如果窗口大小为N
,输入时间为2 hours
,则窗口必须包含12:00PM
和{{1}之间Time
的所有行}
这是我无法搞清楚的部分。
编辑:我的数据中有漏洞,连续两行可能超过5分钟。数据看起来像这样(非常放大)
当窗户穿过这些间隙时,窗户内的点数会有所不同。
以下是我的MySQL代码,它执行我想要在R中执行的操作(相同的表结构):
10:00AM
答案 0 :(得分:3)
1)如果DF
是问题中显示的数据框,则按照您的方式从中创建一个zoo对象,并将其拆分为zs
天。然后lapply
您的函数f
到每个组件中每个连续的w
点集(即每天)。例如,如果您希望一次将数据应用于2小时数据,并且数据定期间隔5分钟数据,则w = 24(因为在两小时内有24个五分钟时段)。在这种情况下,f
每次被调用时将24行数据作为矩阵传递。此外,align
已设置为"right"
,但可以将其设置为align="center"
,条件ix
可以更改为双面等。有关rollapply
的详情,请参阅{ {1}}请参阅:?rollapply
library(zoo)
z <- zoo(DF[-2], as.POSIXct(DF[,1], origin = "1970-01-01"))
w <- 3 # replace this with 24 to handle two hours at a time with five min data
f <- function(x) {
tt <- x[, 1]
ix <- tt[w] - tt <= w * 5 * 60 # RHS converts w to seconds
x <- x[ix, -1]
sum(x) # replace sum with your function
}
out <- rollapply(z, w, f, by.column = FALSE, align = "right")
使用问题中的数据框,我们得到了这个:
> out
$`2008-05-30`
2008-05-30 02:00:00 2008-05-30 02:05:00 2008-05-30 02:10:00 2008-05-30 02:15:00
-66.04703 -83.92148 -95.93558 -100.24924
2008-05-30 02:20:00 2008-05-30 02:25:00 2008-05-30 02:30:00 2008-05-30 02:35:00
-108.15038 -121.24519 -134.39873 -140.28436
顺便提一下,请务必阅读this post。
2)这可以替换为w
和f
如下所示:
n <- nrow(DF)
m <- as.matrix(DF[-2])
sapply(w:n, function(i) { m <- m[seq(length = w, to = i), ]; f(m) })
如果需要,将sapply
替换为lapply
。此外,这可能看起来比第一个解决方案短,但是一旦您添加代码来定义f
和w
(它出现在第一个但不是第二个),它的差别不大。
如果白天没有漏洞,而且天之间只有漏洞,那么这些解决方案可以简化。
答案 1 :(得分:3)
假设您的目标时间t0与pTime相同的比例:自纪元以来的秒数。然后t0-pTime =(两者之间的纪元以来的天数差异)+(剩余秒数的差异)。取t0 - pTime %%(每天的数字秒数)将使我们得到时钟算术的秒数差异(如果差值为负则包裹)。这表明了以下功能:
SecondsPerDay <- 24 * 60 * 60
within <- function(d, t0Sec, wMin) {
diff <- (d$pTime - t0Sec) %% SecondsPerDay
wSec <- 60 * wMin
return(d[diff < wSec | diff > (SecondsPerDay - wSec), ])
}