Columns:
date of transaction
uid is the trader id
sym is the trade id
Subset of table:
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
Aim
I'm trying to get the previous 6 trades for each uid for each sym.
There are multiple uids for each sym; for each of these I need their previous 6 syms for each uid. Need to return all the columns, not just the subset you can see above.
For example, for this row:
2011.04.19 181372 527627
it would return + additional columns row by row - so it would return each prev info for each previous date where sym and uid match in same row in new table - so it is the original table by with additional columns containing previous data for each row.
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
If there are no previous dates or only 3 instead of 6 etc. then it will still return the columns but will just be null.
My attempt:
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)
}
Wrapper function:
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
}
I'm looking for a more concise approach to solving this problem.
EDIT:
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