R 如何将报价和交易数据与data.table匹配(滚动联接)
我拼命地试图重现滚动联接的经典R 如何将报价和交易数据与data.table匹配(滚动联接),r,data.table,R,Data.table,我拼命地试图重现滚动联接的经典Pandas示例,其中quotes数据与trade数据合并 看这里 以下是数据格式的数据。表格式: trades <- data.table(time = c('2016-05-25 13:30:00.023', '2016-05-25 13:30:00.038', '2016-05-25 13:30:00.048',
Pandas
示例,其中quotes
数据与trade
数据合并
看这里
以下是数据格式的数据。表格式:
trades <- data.table(time = c('2016-05-25 13:30:00.023',
'2016-05-25 13:30:00.038',
'2016-05-25 13:30:00.048',
'2016-05-25 13:30:00.048',
'2016-05-25 13:30:00.048'),
ticker = c('MSFT','MSFT','GOOG','GOOG','AAPL'),
price = c(51.95,51.95,720.77,720.92,98.0),
quantity = c(75,155,100,100,100))
> trades
time ticker price quantity
1: 2016-05-25 13:30:00.023 MSFT 51.95 75
2: 2016-05-25 13:30:00.038 MSFT 51.95 155
3: 2016-05-25 13:30:00.048 GOOG 720.77 100
4: 2016-05-25 13:30:00.048 GOOG 720.92 100
5: 2016-05-25 13:30:00.048 AAPL 98.00 100
事实上,您可以看到,唯一可能的报价匹配是在2016-05-25 13:30:00.038处的第二笔交易,因为关闭的(上一笔)报价发生在2016-05-25 13:30:00.030处,所以这是在10毫秒内(而不是精确匹配)
尽管我进行了试验,但我无法在数据表中重现这一点。有什么想法吗?
谢谢 以下是完成工作的方法(快速而肮脏):
# Format as POSIXct*
quotes[, time := as.POSIXct(time, format="%Y-%m-%d %H:%M:%OS", tz = "GMT")]
trades[, time := as.POSIXct(time, format="%Y-%m-%d %H:%M:%OS", tz = "GMT")]
# Match the nearest time (in the right direction) for each ticker and add as column
trades[quotes, on = .(time > time, ticker), qtime := i.time]
# Remove if not within time limit (10 millsecs)
trades[(time - qtime) > 0.01, qtime := NA_real_]
# Now perform an equi-join after removing timestamp that was too distant
trades[, c("bid", "ask") := quotes[trades, on = .(time = qtime), .(bid, ask)]]
trades[, !"qtime"] # drop this temporary column
# time ticker price quantity bid ask
# 1: 2016-05-25 13:30:00 MSFT 51.95 75 NA NA
# 2: 2016-05-25 13:30:00 MSFT 51.95 155 51.97 51.98
# 3: 2016-05-25 13:30:00 GOOG 720.77 100 NA NA
# 4: 2016-05-25 13:30:00 GOOG 720.92 100 NA NA
# 5: 2016-05-25 13:30:00 AAPL 98.00 100 NA NA
*构建了POSIXct向量
在双向量之上,其中值表示自1970-01-01以来的秒数
从亚历克西斯的帖子中学习,这里有一个稍微简洁的版本,使用了roll参数
trades[, c("qtime", "bid", "ask") := quotes[.SD, roll = 0.01, on = .(ticker, time), .(x.time, bid, ask)]]
trades[time == qtime, c("bid", "ask") := NA_real_][, qtime := NULL]
以下是完成工作的方法(快速和肮脏):
# Format as POSIXct*
quotes[, time := as.POSIXct(time, format="%Y-%m-%d %H:%M:%OS", tz = "GMT")]
trades[, time := as.POSIXct(time, format="%Y-%m-%d %H:%M:%OS", tz = "GMT")]
# Match the nearest time (in the right direction) for each ticker and add as column
trades[quotes, on = .(time > time, ticker), qtime := i.time]
# Remove if not within time limit (10 millsecs)
trades[(time - qtime) > 0.01, qtime := NA_real_]
# Now perform an equi-join after removing timestamp that was too distant
trades[, c("bid", "ask") := quotes[trades, on = .(time = qtime), .(bid, ask)]]
trades[, !"qtime"] # drop this temporary column
# time ticker price quantity bid ask
# 1: 2016-05-25 13:30:00 MSFT 51.95 75 NA NA
# 2: 2016-05-25 13:30:00 MSFT 51.95 155 51.97 51.98
# 3: 2016-05-25 13:30:00 GOOG 720.77 100 NA NA
# 4: 2016-05-25 13:30:00 GOOG 720.92 100 NA NA
# 5: 2016-05-25 13:30:00 AAPL 98.00 100 NA NA
*构建了POSIXct向量
在双向量之上,其中值表示自1970-01-01以来的秒数
从亚历克西斯的帖子中学习,这里有一个稍微简洁的版本,使用了roll参数
trades[, c("qtime", "bid", "ask") := quotes[.SD, roll = 0.01, on = .(ticker, time), .(x.time, bid, ask)]]
trades[time == qtime, c("bid", "ask") := NA_real_][, qtime := NULL]
也可以与滚动连接组合,
这与@sindri_baldur的提议相似,但并不完全相同:
library(lubridate)
library(data.table)
quotes[, time := as.POSIXct(time, format="%Y-%m-%d %H:%M:%OS", tz = "GMT")]
trades[, time := as.POSIXct(time, format="%Y-%m-%d %H:%M:%OS", tz = "GMT")]
match_inexact <- function(q_time, t_time, bid, ask) {
exact <- q_time == t_time # exact matches get NA
bid[exact] <- NA_real_
ask[exact] <- NA_real_
list(bid, ask)
}
trades[, c("bid", "ask") := quotes[.SD,
match_inexact(x.time, i.time, x.bid, x.ask),
on = .(ticker, time),
roll = lubridate::dmilliseconds(10L)]]
库(lubridate)
库(数据表)
quotes[,time:=as.POSIXct(time,format=“%Y-%m-%d%H:%m:%OS”,tz=“GMT”)]
交易[,时间:=as.POSIXct(时间,格式=“%Y-%m-%d%H:%m:%OS”,tz=“GMT”)]
匹配不精确您也可以与滚动连接组合,
这与@sindri_baldur的提议相似,但并不完全相同:
library(lubridate)
library(data.table)
quotes[, time := as.POSIXct(time, format="%Y-%m-%d %H:%M:%OS", tz = "GMT")]
trades[, time := as.POSIXct(time, format="%Y-%m-%d %H:%M:%OS", tz = "GMT")]
match_inexact <- function(q_time, t_time, bid, ask) {
exact <- q_time == t_time # exact matches get NA
bid[exact] <- NA_real_
ask[exact] <- NA_real_
list(bid, ask)
}
trades[, c("bid", "ask") := quotes[.SD,
match_inexact(x.time, i.time, x.bid, x.ask),
on = .(ticker, time),
roll = lubridate::dmilliseconds(10L)]]
库(lubridate)
库(数据表)
quotes[,time:=as.POSIXct(time,format=“%Y-%m-%d%H:%m:%OS”,tz=“GMT”)]
交易[,时间:=as.POSIXct(时间,格式=“%Y-%m-%d%H:%m:%OS”,tz=“GMT”)]
在10毫秒窗口内使用最新报价匹配另一种可能的非等联接方法:
options(digits.secs=3) #see https://stackoverflow.com/a/43475068/1989480
library(data.table)
quotes[, time := as.POSIXct(time, format="%Y-%m-%d %H:%M:%OS", tz = "GMT")]
trades[, time := as.POSIXct(time, format="%Y-%m-%d %H:%M:%OS", tz = "GMT")][,
c("start", "end") := .(time-0.01, time)]
trades[, c("bid", "ask") :=
quotes[trades, on=.(ticker, time>=start, time<end), mult="last", .(bid, ask)]
][, c("start", "end") := NULL]
在该10ms窗口内使用最新报价的另一种可能的非等联接方法:
options(digits.secs=3) #see https://stackoverflow.com/a/43475068/1989480
library(data.table)
quotes[, time := as.POSIXct(time, format="%Y-%m-%d %H:%M:%OS", tz = "GMT")]
trades[, time := as.POSIXct(time, format="%Y-%m-%d %H:%M:%OS", tz = "GMT")][,
c("start", "end") := .(time-0.01, time)]
trades[, c("bid", "ask") :=
quotes[trades, on=.(ticker, time>=start, time<end), mult="last", .(bid, ask)]
][, c("start", "end") := NULL]
有趣。谢谢你能解释一下你在那里做什么吗?qtime:=i.time
做什么?为什么我们不能用一些roll
参数一次性完成呢?谢谢将尝试添加更多注释。也许有一种方法可以用一卷纸来做。我是一个非equi连接的初学者。这里也有同样的想法<代码>时间>时间
有点模棱两可。我如何确保我指的是报价的时间
或交易的时间
?同意。但在这种情况下,第一次指的是交易
。无论如何,我会选择第二个更干净的版本。很有趣。谢谢你能解释一下你在那里做什么吗?qtime:=i.time
做什么?为什么我们不能用一些roll
参数一次性完成呢?谢谢将尝试添加更多注释。也许有一种方法可以用一卷纸来做。我是一个非equi连接的初学者。这里也有同样的想法<代码>时间>时间
有点模棱两可。我如何确保我指的是报价的时间
或交易的时间
?同意。但在这种情况下,第一次指的是交易
。无论如何,我会选择第二个更干净的版本。哇,很好。您介意再解释一下发生了什么吗?在这种情况下,滚动联接表示法(当您指定roll
时激活)意味着:对于用于联接的最后一列,如果没有精确匹配,则最多向后看10毫秒。使用match\u increact
我们可以简单地检查时间是否已滚动:如果x.time==i.time
,则未进行滚动,则为精确匹配。这个习惯用法只是通过引用将结果列(每个列打包在一个列表中)分配给交易。但有一点,时间是指什么?左边DT?Ah中的时间变量,在数据表
文档中,它们通常用变量x[i,j,by]
描述事物,其中i
可以是另一个数据表
。在连接过程中,它们公开带有x.
和i.
前缀的变量,具体取决于从哪个表中获取值。因此i.time
来自.SD
,它表示来自交易的数据子集。明白了。我猜是x。指的是左边的DT?在这种情况下,交易
?哇,非常好。您介意再解释一下发生了什么吗?在这种情况下,滚动联接表示法(当您指定roll
时激活)意味着:对于用于联接的最后一列,如果没有精确匹配,则最多向后看10毫秒。使用match\u increact
我们可以简单地检查时间是否已滚动:如果x.time==i.time
,则未进行滚动,则为精确匹配。这个习惯用法只是通过引用将结果列(每个列打包在一个列表中)分配给交易。但有一点,时间是指什么?左边DT?Ah中的时间变量,在数据表
文档中,它们通常用变量x[i,j,by]
描述事物,其中i
可以是另一个数据表
。在连接过程中,它们公开带有x.
和i.
前缀的变量,具体取决于从哪个表中获取值。因此i.time
来自.SD
,它表示来自交易的数据子集。明白了。我猜是x。指的是左边的DT?在这种情况下,交易
?很酷的东西。你介意解释一下你在这里做什么吗?mult
参数是什么?mult
arg允许您处理一对多匹配的情况(当mult=“last”
使用上次观察时,请参阅?data.table
了解更多详细信息)。我认为加入条件是明确的?很酷,谢谢!假设我想在