You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在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
 };

代码说明

  1. 排序处理:先对表按signalTime升序排序,确保处理顺序正确(输入表已有序时可省略,保留则更健壮)。
  2. 扫描操作:从初始值0Nt(空时间)开始,用scan逐行检查当前交易的signalTime是否大于等于上一个保留交易的exitTime,生成布尔标记数组accept。
  3. 筛选记录:去掉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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 06:45:11