在kdb中获取无重叠交易的高效q语言实现方案
解决KDB交易时间段去重叠的高效实现
现有数据表
我们有如下KDB表trades:
q)trades: ([] signalTime: 2024.01.05 2024.01.12 2024.01.19 2024.01.25 2024.02.02 2024.02.09 2024.02.16 2024.02.23 2024.03.01 2024.03.07; exitTime: 2024.01.25 2024.02.01 2024.02.08 2024.02.15 2024.02.22 2024.02.29 2024.03.07 2024.03.14 2024.03.21 2024.03.28 );
表内容展示:
signalTime exitTime ---------------------- 2024.01.05 2024.01.25 2024.01.12 2024.02.01 2024.01.19 2024.02.08 2024.01.25 2024.02.15 2024.02.02 2024.02.22 2024.02.09 2024.02.29 2024.02.16 2024.03.07 2024.02.23 2024.03.14 2024.03.01 2024.03.21 2024.03.07 2024.03.28
需求说明
需要保留signalTime与exitTime之间时间段不与其他交易重叠的记录(即任意日期仅存在一笔交易),预期输出如下:
signalTime exitTime ---------------------- 2024.01.05 2024.01.25 2024.02.02 2024.02.22 2024.02.23 2024.03.14
尝试的问题代码
此前尝试用do循环实现,但存在问题,代码如下:
removeOverlappingTrades:{[t] n: count t; accept: n#0b; accept[0]: 1b; lastExitTime: t[`exitTime][0]; do[n-1; {[t;lastExitTime;accept;x] i: x+1; // 当前索引 if[t[`signalTime][i] >= lastExitTime; accept[i]: 1b; lastExitTime: t[`exitTime][i]; ]; }[t;lastExitTime;accept] each til n-1]; t where accept };
高效地道的KDB实现方案
KDB中可以利用**扫描(scan)**操作实现无循环的高效处理,这是更符合KDB惯用风格的写法:
removeOverlappingTrades:{[t] // 先确保表按signalTime排序(输入未排序时也能正常处理) sortedT: `signalTime xasc t; // 使用scan跟踪上一个保留交易的exitTime,生成接受标记 accept: {[prevExit; row] if[row.signalTime >= prevExit; :1b; :0b] } scan 0Nt, sortedT[`exitTime]; // 去掉第一个初始值后,筛选符合条件的记录 sortedT where 1_accept };
代码说明
- 排序处理:先对表按
signalTime升序排序,确保处理顺序正确(输入表已有序时可省略,保留则更健壮)。 - 扫描操作:从初始值
0Nt(空时间)开始,用scan逐行检查当前交易的signalTime是否大于等于上一个保留交易的exitTime,生成布尔标记数组accept。 - 筛选记录:去掉
accept数组的第一个初始值,用剩余标记筛选出符合条件的记录。
测试该函数:
q)removeOverlappingTrades[trades] signalTime exitTime ---------------------- 2024.01.05 2024.01.25 2024.02.02 2024.02.22 2024.02.23 2024.03.14
完全匹配预期输出。
另外还有一种更简洁的实现(假设表已按signalTime排序):
removeOverlappingTrades:{ t: `signalTime xasc x; // 计算需要保留的索引:第一个记录 + 后续signalTime >= 前一个保留的exitTime keep: 0, where t[`signalTime] >= (t[`exitTime] keep prev keep); t keep keep };
该写法通过keep变量跟踪保留的索引,递归计算前一个保留记录的exitTime,同样高效且符合KDB风格。
内容的提问来源于stack exchange,提问作者marital_weeping
相关产品推荐
相关产品推荐

