如何为每笔交易追加前6条交易记录为列(KDB+实现)
KDB/Q 交易历史记录追加需求及优化请求
列说明
date of transaction:交易日期 uid:交易者ID sym:交易ID
表子集
以下是从表tb中查询的部分数据:
q) select date, uid, sym from tb date uid sym ------------------------ 2011.08.12 171196 537876 2012.09.08 171196 562161 2012.12.28 171196 570391 2014.04.29 171196 599420 2014.04.29 171196 601520 2014.05.11 171196 602286 2014.06.24 171196 605785 2014.07.19 171196 605686 2011.03.15 160872 524982 2011.07.11 168153 536311 2011.07.25 168153 535616 2011.08.25 30746 537340 2011.01.27 122083 523350 2011.03.05 122083 525676 2011.05.06 122083 531523 2011.01.07 181372 521088 2011.02.07 181372 522780 2011.03.02 181372 523984 2011.03.15 181372 524980 2011.03.21 181372 525448 2011.04.09 181372 529164 2011.04.19 181372 527627 2011.04.28 181372 528302 2011.05.16 181372 530337 2011.06.14 181372 532987
需求目标
- 为每个
uid的每笔sym交易,获取其前6条历史交易记录 - 将历史记录的字段(date/uid/sym)作为新列追加到原表,保留原表所有列
- 若历史记录不足6条,对应新列填充空值
示例:对于行
2011.04.19 181372 527627,追加后格式如下:
date uid sym prevdate1 prevuid1 prevsym1 prevdate2 prevuid2 etc. ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 2011.04.19 181372 527627 2011.01.07 181372 521088 2011.03.02 181372 523984 2011.03.15 181372 524980 2011.03.21 181372 525448
现有实现代码
核心函数
getHHData:{[tb;syms;colnames;numtrades] dict:exec i by uid from select uid from tb where sym=syms; tradedate:first exec date from tb where sym=syms; histdates:?[?[tb;enlist (in;`uid;(raze;(inv;`dict)));(enlist`uid)!enlist`uid;colnames!colnames];();`uid;`date]; histdatesro:raze each value (asc dict),histdates; ind:til count histdatesro; preind:{[prevtrades;ind;tradedate;histdatesro] {[prevtrades;ind;tradedate;histdatesro] prevtrades+{where y[z] in x}[tradedate;histdatesro;]each ind }[;ind;tradedate;histdatesro] }[;ind;tradedate;histdatesro]each neg 1_til numtrades; uids:exec uid from tb where sym=syms; histdata:reverse each key asc(value ?[tb;enlist (in;`uid;`uids);`uid;last colnames])!(value dict); histCols:{[x;data] {$[x<count y;y[x];0N]}[x] each data}[;histdata] each til numtrades-1; flip(`sym`uid,`$string[last colnames],/:string 1+til numtrades-1)!(enlist[count[histdata]#syms],enlist[uids],histCols) }
包装函数
getHHDataMerged:{[tb;syms;colnames;numtrades] raze{[tb;sym;colnames;numtrades](lj/){`sym`uid xkey x }each {[tb;sym;c;numtrades]getHHData[tb;sym;c;numtrades] }[tb;sym;;numtrades]each colnames }[tb;;colnames;numtrades]each syms }
尝试简化时的报错
尝试用递归方式简化实现时,触发类型错误:
q)updCols:{`$string[x],\:string[y]} q)prevCols:{if[x=0;:`date`uid`sym]; updCols[;x] `prevdate`prevuid`prevsym} q)7#f/[tb1;1+til 6] 'type [0] 7#f/[tb1;1+til 6] ^ q)tb1 date uid sym ------------------------ 2011.08.12 171196 537876 2012.09.08 171196 562161 2012.12.28 171196 570391 2014.04.29 171196 599420 2014.04.29 171196 601520 2014.05.11 171196 602286 2014.06.24 171196 605785 2014.07.19 171196 605686 2011.03.15 160872 524982
请求
寻求更简洁的KDB/Q实现方案。
内容的提问来源于stack exchange,提问作者threedom
相关产品推荐
相关产品推荐

