KDB+中按RIC判断价格是否持续指定时长的实现问题
问题描述
我有如下时序表:
test:([] time:09:30:00.500000000 09:30:00.500500000 09:30:00.600000000 09:30:00.610000000 09:30:00.610100000 09:30:00.620500000 09:30:00.621000000 09:30:00.630000000; RIC:`AAPL`AAPL`AAPL`IBM`AAPL`AAPL`AAPL`IBM; price:1 2 2 11 2 2 3 12; moreThan1MS:`N`Y`Y`Y`Y`N`NA`NA)
表中原本没有moreThan1MS列,该列用于判断当前记录的价格是否能持续超过1毫秒:
- 第一条AAPL记录,0.5毫秒后价格就变动了,所以标记为
N; - 第一条IBM记录,20毫秒后价格才变动,所以标记为
Y(不受其他RIC的价格变动影响)。
我曾尝试以下实现,但无法按RIC区分,效果也不符合预期:
test:update X:(abs deltas price) by RIC from test; test:aj[`time;test;select time-(1000000), Y:X from test]; test:update isLong:(Y=0)|(X=Y) from test;
更新:边缘情况问题
参考Jason的方案后,我遇到了边缘情况:
t:([] time:09:30:00.500000000 09:30:00.501000000 09:30:00.502000000 09:30:00.503000000 09:30:00.540000000 09:30:00.610000000 09:30:00.610100000 09:30:00.690000000 09:30:00.700000000 09:30:00.730000000; RIC:`AAPL`AAPL`AAPL`AAPL`AAPL`IBM`AAPL`AAPL`AAPL`IBM; price:1 1 2 2 1 11 2 2 3 12; moreThan50MS:`N`N`N`N`Y`Y`Y`N`NA`NA) update moreThan50MSsignal:`N`Y price=price([]RIC;time-50000000)bin([]RIC;time)from`t;
这个实现只检查了指定时长后的价格是否和当前一致,但没考虑时段内价格变动后又复原的情况:比如前两条AAPL记录,50ms后价格回到了原值,但期间有过变动,应该标记为N。我考虑过用abs(deltas)的累积和或者时间窗口msums,但不知道具体怎么实现,求优化方案。
解决方案
核心思路是:对每个RIC分组,定位当前记录之后第一个价格变动的时间点,判断该时间点与当前记录的时间差是否超过阈值。此方法能直接覆盖“价格先变后复原”的边缘情况——只要中间存在价格变动,就会被检测到。
完整实现代码(以50ms阈值为例)
t:([] time:09:30:00.500000000 09:30:00.501000000 09:30:00.502000000 09:30:00.503000000 09:30:00.540000000 09:30:00.610000000 09:30:00.610100000 09:30:00.690000000 09:30:00.700000000 09:30:00.730000000; RIC:`AAPL`AAPL`AAPL`AAPL`AAPL`IBM`AAPL`AAPL`AAPL`IBM; price:1 1 2 2 1 11 2 2 3 12; moreThan50MS:`N`N`N`N`Y`Y`Y`N`NA`NA); // 按RIC分组,获取每条记录的下一条时间、价格 t:update nextTime:next time, nextPrice:next price by RIC from t; // 递归查找同组内第一个价格不同的记录时间 t:update nextTime:{$[x=y; z; x]}[nextTime; nextPrice; (next nextTime) over] by RIC from t; // 设置阈值(50ms对应纳秒数),生成最终标记 threshold:50000000; t:update moreThan50MSsignal:?[isNull nextTime; `NA; ?[nextTime - time > threshold; `Y; `N]] from t;
代码细节解释
- 分组获取下一条记录:
next time, next price by RIC按股票代码分组,为每条记录关联同组下一条的时间和价格。 - 递归定位价格变动点:通过lambda函数递归查找,跳过所有价格与当前记录相同的后续条目,直接定位到第一个价格变动的时间点,彻底解决“价格先变后复原”的误判问题。
- 阈值判断生成结果:
- 若
nextTime为空(当前是同组最后一条记录),标记为NA; - 计算时间差,超过阈值标记
Y,否则标记N。
- 若
如果需要改成1ms阈值,只需将threshold的值改为1000000即可。
内容的提问来源于stack exchange,提问作者Cole
相关产品推荐
相关产品推荐

