Rolling window in multi groups

自闭症网瘾萝莉.ら 提交于 2020-01-03 05:39:08

问题


I have the following trade table:

  time ticker side price qty
  --------------------------
  2018.01.01T13:00:20 AAPL BUY  10.0  100
  2018.01.01T13:01:30 AAPL SELL 12.0  300
  2018.01.01T13:01:45 AAPL BUY  11.0  500  
  2018.01.01T13:02:13 AAPL BUY  10.5  100
  2018.01.01T13:05:00 AAPL SELL 13.0  200

I need a rolling window function with a lookback of 1 minute to seperate the buy/sells of a stock price

  time ticker BUYs SELLs TOTAL
  --------------------------------
  2018.01.01T13:00:20 AAPL 1 0 1
  2018.01.01T13:01:30 AAPL 0 1 1
  2018.01.01T13:01:45 AAPL 1 1 2
  2018.01.01T13:02:13 AAPL 1 1 2 
  2018.01.01T13:05:00 AAPL 0 1 1

I have decided on using the "wj" function, because the rolling function suit my purpose. However I can't get it to work:

  w: -00:01 00:00 +:/ select time from table
  wj[w;'ticker'time;table;(table;(count;ticker);(count;ticker))]

So at least I want the count every buy/sell first then group them later. But I cannot even get the initial query to run without getting a type error.

Can someone point me in the right direction?

Additional Question

I know would have to perform a rolling sum/count over several accounts which is not known until runtime.

  time ticker side price qty account
  ----------------------------------
  2018.01.01T13:00:20 AAPL BUY  10.0  100 ACCT123
  2018.01.01T13:01:30 AAPL SELL 12.0  300 ACCT456 
  2018.01.01T13:01:45 AAPL BUY  11.0  500 ACCT789  
  2018.01.01T13:02:13 AAPL BUY  10.5  100 ERRORACCT123
  2018.01.01T13:05:00 AAPL SELL 13.0  200 TESTACCT123

I know I can pivot the table to:

  time ticker side price qty ACCT123 ACCT456 ACC789 ERRORACCT123 TESTACCT23
  ---------------------------------

but can I using the rolling function to sum the sizes in a 1 minute lookback period?


回答1:


The window w is required to be a pair of lists:

   w: -00:01 00:00 +\: exec time from t

You'll also need to use wj1 as you only want to consider rows on or after entry to the window.

http://code.kx.com/q/ref/joins/#wj-wj1-window-join

    q)table,'exec side from wj1[w;`ticker`time;table;(table;({`BUY`SELL!count each (group x)`BUY`SELL};`side))]

The monadic lambda: {`BUY`SELL!count each (group x)`BUY`SELL}

Uses group to return the indices of BUY and SELL values and also ensures that BUY and SELL are present in all keys.

exec creates a table:

     q)exec side from wj1[w;`ticker`time;table;(table;({{`BUY`SELL!count each x`BUY`SELL}group x};`side))]
    BUY SELL
    --------
     1   0
     0   1
     1   1
     2   1
     0   1

And then we use join each to get the final result:

    q)update TOTAL:BUY+SELL from table,'exec side from wj1[w;`ticker`time;table;(table;({`BUY`SELL!count each (group x)`BUY`SELL};`side))]
    time                          ticker side price qty BUY SELL TOTAL
    ------------------------------------------------------------------
    2018.01.01D13:00:20.000000000 AAPL   BUY  10    100 1   0    1
    2018.01.01D13:01:30.000000000 AAPL   SELL 12    300 0   1    1
    2018.01.01D13:01:45.000000000 AAPL   BUY  11    500 1   1    2
    2018.01.01D13:02:13.000000000 AAPL   BUY  10.5  100 2   1    3
    2018.01.01D13:05:00.000000000 AAPL   SELL 13    200 0   1    1

For summing quantities depending on side it is easier to the following: First update two new columns using vector conditional and then sum these using wj1.

http://code.kx.com/q/ref/lists/#vector-conditional

    q)wj1[w;`ticker`time;table;(update BUYQUANTITY:?[`BUY=side;qty;0],SELLQUANTITY:?[`SELL=side;qty;0]from table;(sum;`BUYQUANTITY);(sum;`SELLQUANTITY))]
    time                          ticker side price qty BUYQUANTITY SELLQUANTITY
    ----------------------------------------------------------------------------
    2018.01.01D13:00:20.000000000 AAPL   BUY  10    100 100         0           
    2018.01.01D13:01:30.000000000 AAPL   SELL 12    300 0           300         
    2018.01.01D13:01:45.000000000 AAPL   BUY  11    500 500         300         
    2018.01.01D13:02:13.000000000 AAPL   BUY  10.5  100 600         300         
    2018.01.01D13:05:00.000000000 AAPL   SELL 13    200 0           200         



回答2:


w: -00:01 00:00 +\: exec time from table

Using an exec will allow you to create a pair of times or timestamps for the time interval to join on. You must also use \: to perform the each left operation.

wj[w;`sym`time;table;(table;(count;`sym);(count;`sym))]

w defines the time interval - a pair of times or timestamps;

The table names in the window join must also be passed in as a symbol using `.



来源:https://stackoverflow.com/questions/49754101/rolling-window-in-multi-groups

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!