【问题标题】:Rolling window in multi groups多组滚动窗口
【发布时间】:2018-04-10 12:46:13
【问题描述】:

我有以下交易表:

  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

我需要一个回溯 1 分钟的滚动窗口函数来分隔股票价格的买入/卖出

  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

我决定使用“wj”功能,因为滚动功能适合我的目的。但是我无法让它工作:

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

因此,至少我希望先计算每个买卖的计数,然后再将它们分组。但是我什至无法在没有出现类型错误的情况下运行初始查询。

有人能指出正确的方向吗?

其他问题

我知道必须对几个帐户执行滚动求和/计数,这要到运行时才知道。

  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

我知道我可以将表格旋转到:

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

但是我可以使用滚动函数来汇总 1 分钟回顾期内的大小吗?

【问题讨论】:

    标签: kdb


    【解决方案1】:

    窗口w必须是一对列表:

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

    您还需要使用 wj1,因为您只想考虑进入窗口时或之后的行。

    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))]
    

    一元 lambda: {`BUY`SELL!count each (group x)`BUY`SELL}

    使用 group 返回 BUY 和 SELL 值的索引,并确保 BUY 和 SELL 出现在所有键中。

    exec 创建一个表:

         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
    

    然后我们使用 join each 得到最终结果:

        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
    

    对于取决于边的求和数量,以下操作更容易: 首先使用向量条件更新两个新列,然后使用 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         
    

    【讨论】:

    • 感谢您的回答。我试过了,它有效。我有一个额外的要求。这次我尝试对大小求和,因此我将 lambda 函数更改为 {BUYSELL!sum qty each (group x)BUYSELL},但它似乎不起作用。对此有何提示?
    • 不客气,我编辑了上面的答案以显示一种根据侧面对数量求和的方法。
    • 嗨@jomahony,我还有一个问题。我们有一个名为“accounts”的新字段,而不是 BUY|SELL。并且直到运行时才知道所有唯一帐户。如何将相同的计数/求和方法应用于滚动查询?能给个提示吗?
    【解决方案2】:
    w: -00:01 00:00 +\: exec time from table
    

    使用 exec 将允许您为要加入的时间间隔创建一对时间或时间戳。您还必须使用\: 来执行每个左操作。

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

    w 定义时间间隔——一对时间或时间戳;

    窗口连接中的表名也必须使用`作为符号传入。

    【讨论】:

      猜你喜欢
      • 2017-09-16
      • 2020-02-07
      • 1970-01-01
      • 2020-07-01
      • 2018-11-25
      • 2017-03-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多