在 KDB 中,对于每个
ticker
,我想获取除每个代码中第一次出现的 signal=1
的所有行。
og:([]
ticker:raze 5#/:(`AAPL`GOOGL`MSFT);
date:raze 3#enlist 2023.01.01+til 5;
price:45 46 47 48 49,100 102 101 103 105,200 201 199 202 205;
volume:1000 1100 900 1200 1300,500 520 510 530 550,300 310 290 320 330;
signal:0 0 1 1 0,0 1 1 1 0,0 0 0 1 1 / Example entry signals
);
t:select from og where signal=1;
t:update valid:1b from t where date>(min;date) fby ticker;
t:select from t where valid;
show t: delete valid from t; / correct but verbose
q)og
ticker date price volume signal
-------------------------------------
AAPL 2023.01.01 45 1000 0
AAPL 2023.01.02 46 1100 0
AAPL 2023.01.03 47 900 1
AAPL 2023.01.04 48 1200 1
AAPL 2023.01.05 49 1300 0
GOOGL 2023.01.01 100 500 0
GOOGL 2023.01.02 102 520 1
GOOGL 2023.01.03 101 510 1
GOOGL 2023.01.04 103 530 1
GOOGL 2023.01.05 105 550 0
MSFT 2023.01.01 200 300 0
MSFT 2023.01.02 201 310 0
MSFT 2023.01.03 199 290 0
MSFT 2023.01.04 202 320 1
MSFT 2023.01.05 205 330 1
q)t
ticker date price volume signal
-------------------------------------
AAPL 2023.01.04 48 1200 1
GOOGL 2023.01.03 101 510 1
GOOGL 2023.01.04 103 530 1
MSFT 2023.01.05 205 330 1
我发现我的方法相当冗长,我想知道是否可以更简洁并希望更有效。仅供参考,下面的天真/不正确
select
陈述给出了不期望的结果
q) select by ticker from og where date>date[first where signal=1] / incorrect
ticker| date price volume signal
------| ------------------------------
AAPL | 2023.01.05 49 1300 0
GOOGL | 2023.01.05 105 550 0
MSFT | 2023.01.05 205 330 1
您可以使用
fby
(https://code.kx.com/q/ref/fby) 和虚拟索引列 i
: 简洁地实现此目的
q)select from og where signal=1,i>(first;i)fby ticker
ticker date price volume signal
-------------------------------------
AAPL 2023.01.04 48 1200 1
GOOGL 2023.01.03 101 510 1
GOOGL 2023.01.04 103 530 1
MSFT 2023.01.05 205 330 1