创建基于唯一条目的滚动计算(Q / KDB +)

时间:2018-02-05 18:53:13

标签: kdb q-lang

我有一张桌子:

q)data:([]dt:2017.01.05D19:45:00.238248239 2017.01.05D20:46:00.282382392 2017.01.05D21:47:00.232842342 2017.01.05D22:48:00.835838442 2017.01.05D20:49:00.282382392;sym:`AAPL`GOOG`AAPL`BBRY`GOOG;price:101.20 800.20 102.30 2.20 800.50;shares:500 100 500 900 100)
q)data
dt                            sym    price   shares
2017.01.05D19:45:00.238248239 AAPL   101.20  500
2017.01.05D20:46:00.282382392 GOOG   800.20  100
2017.01.05D21:47:00.232842342 AAPL   102.30  500
2017.01.05D22:48:00.835838442 BBRY     2.20  900
2017.01.05D20:49:00.282382392 GOOG   800.50  100

我需要创建一个包含价格*份额总和的列,以便对每个股票代码进行最新观察。

为了证明使用上述数据,我们正在寻找:

data:
dt                            sym    price   shares   index
2017.01.05D19:45:00.238248239 AAPL   101.20  500      50,600
2017.01.05D20:46:00.282382392 GOOG   800.20  100      130,620
2017.01.05D21:47:00.232842342 AAPL   102.30  500      131,170
2017.01.05D22:48:00.835838442 BBRY     2.20  900      133,150
2017.01.05D20:49:00.282382392 GOOG   800.50  100      133,180

为了进一步说明,在第1行,只包括1个符号,第2行,2个符号,然后是2,然后是3,然后是3,再次是第3行。

在另一个帖子中回答:Apply formula to current and previous rows only (Q/KDB)

3 个答案:

答案 0 :(得分:4)

Jonathon解决方案的轻微变化,使用矢量条件:

q)delete dict from update index:?[all flip distinct[sym]in/: key'[dict]; {sum[x]*sum[y]%sum z} ./: flip each value each dict;0N] from update dict:@[;;:;]\[()!();sym;flip (price;shares;divisor)] from data
dt                            sym  price shares divisor index
----------------------------------------------------------------
2018.02.05D22:47:22.175914000 AAPL 101.2 500    2
2018.02.05D22:21:10.175914000 GOOG 800.2 500    1
2018.02.05D22:58:00.175914000 AAPL 102.3 500    2
2018.02.05D22:19:27.175914000 BBRY 2.2   500    1       339262.5

答案 1 :(得分:1)

q)delete ind from update index:sum@'ind from (update ind:@\[()!();sym;:;shares*price%divisor] from data) where i>=max(first;i)fby sym
dt                            sym  price shares divisor index
--------------------------------------------------------------
2017.01.05D19:45:00.238248239 AAPL 101.2 500    2
2017.01.05D20:45:00.282382392 GOOG 800.2 500    1
2017.01.05D21:45:00.232842342 AAPL 102.3 500    2
2017.01.05D22:45:00.835838442 BBRY 2.2   500    1       426775

你得到的答案略有不同,这就是做总和(股票价格%除数),而不是单独求和。

一个稍微混乱且复杂的版本,可以得到你想象中的相同答案:

q)delete ind from update index:sum'[ind[;;0]]*sum'[ind[;;1]]%sum'[ind[;;2]] from (update ind:@\[()!();sym;:;shares,'price,'divisor] from data) where i>=max(first;i)fby sym
dt                            sym  price shares divisor index
----------------------------------------------------------------
2017.01.05D19:45:00.238248239 AAPL 101.2 500    2
2017.01.05D20:45:00.282382392 GOOG 800.2 500    1
2017.01.05D21:45:00.232842342 AAPL 102.3 500    2
2017.01.05D22:45:00.835838442 BBRY 2.2   500    1       339262.5

答案 2 :(得分:1)

鉴于问题自最初发布和我之前的回答以来发生了很大变化,这里有一个更新的解决方案:

q)delete ind from update index:sum@'ind from (update ind:@\[()!();sym;:;shares*price] from data) where i>=max(first;i)fby sym
dt                            sym  price shares index
------------------------------------------------------
2017.01.05D19:45:00.238248239 AAPL 101.2 500
2017.01.05D20:46:00.282382392 GOOG 800.2 100
2017.01.05D21:47:00.232842342 AAPL 102.3 500
2017.01.05D22:48:00.835838442 BBRY 2.2   900    133150
2017.01.05D20:49:00.282382392 GOOG 800.5 100    133180

或者没有其他初始条件,只有在所有代码打勾后才能填充:

q)delete ind from update index:sum@'ind from update ind:@\[()!();sym;:;shares*price] from data
dt                            sym  price shares index
------------------------------------------------------
2017.01.05D19:45:00.238248239 AAPL 101.2 500    50600
2017.01.05D20:46:00.282382392 GOOG 800.2 100    130620
2017.01.05D21:47:00.232842342 AAPL 102.3 500    131170
2017.01.05D22:48:00.835838442 BBRY 2.2   900    133150
2017.01.05D20:49:00.282382392 GOOG 800.5 100    133180

(请注意,这些只是我昨天发布的解决方案的微小修改,针对问题中更改的要求进行了更新)