根据特定条件对 kdb 中的数据进行分组

5 kdb

我有一个名为 raw 的主数据框,如下所示:

tab:([]date:2018.02.05 2018.02.05 2018.02.06 2018.02.06;time:01:30:25.000 02:30:45.000 04:15:15.000 02:15:15.000;vol:50 55 64 12; name:`A`B`B`A)

date           time         vol     name   
2018.02.05     1:30:25      50       A
2018.02.05     2:30:45      55       B
2018.02.06     4:15:15      64       B
2018.02.06     2:15:15      12       A
Run Code Online (Sandbox Code Playgroud)

我需要根据以下条件创建一个新表:

在两个特定日期之间,我需要找到名称 B 在两小时内累积交易量为 100 的时间。

我认为应该起作用的逻辑:按时间升序排列数据。将所有卷按名称 = `B 添加为 (time[i]: time[i]+2hrs) 内的时间。如果 cum vol > 100,则返回时间间隔和相应的日期。继续 i +1 。我是 kdb 的新手,所以我在实施它时遇到了困难。

示例输出:

time1          time2         date1         date2
1:30:00        3:30:00       2018.02.05    2018.02.05
23:00:00       1:00:00       2018.02.05    2018.02.06
Run Code Online (Sandbox Code Playgroud)

任何有关这方面的线索都将受到赞赏。谢谢

小智 1

我相信使用 aj 可以解决您的问题

最初正如您所指出的,表格应按时间排序

`time xasc `tab;
Run Code Online (Sandbox Code Playgroud)

然后,应使用 sums 创建卷的累积总和

tab:update cumvol:sums vol by name from tab
Run Code Online (Sandbox Code Playgroud)

然后使用aj - 获取每次不在2小时内的交易量的累计总和。

aj[`name`time;tab;select time:time+02:00,name,cumvol2:cumvol from tab]
Run Code Online (Sandbox Code Playgroud)

然后我们可以执行 cumvol - cumvol2 来获取每 2 小时内的总音量

tab:select time, name, runningvol:cumvol-0^cumvol2 from 
aj[`name`time;tab;select time:time+02:00,name,cumvol2:cumvol from tab]
Run Code Online (Sandbox Code Playgroud)

然后一个简单的select语句就可以得到cumvol大于100的次数

select time,time+02:00 from tab where runningvol>100
Run Code Online (Sandbox Code Playgroud)

对此可以添加的改进是在 aj.table 中的第二个表上添加分组属性。对此的另一个改进是将日期和时间格式化为单个时间戳或日期时间。

有关函数 aj 和 sum 的更多信息可以在此处找到:

http://code.kx.com/q/ref/joins/#aj-aj0-asof-join

http://code.kx.com/q/ref/arith-integer/#sums