有条件地更新列

时间:2019-02-11 02:24:51

标签: kdb

我有一个交易表,包括日期,时间,交易品种,交易量,平仓拍卖量。

不幸的是,拍卖的最后成交量包括在表格的最后一个分箱中,为了使事情复杂化,它可能在半天的15:59:00或12:59:00发生。

是否可以有条件地更新卷以删除关闭卷?

例如,将其从15:59:00的卷中删除(如果存在),否则从12:59:00的卷中删除。

例如

t:([]date:2019.02.01 2019.02.01 2019.02.02 2019.02.02;time:12:59:00 15:59:00 12:59:00 15:59:00;sym:`AAPL`AAPL`AAPL`AAPL;volume:100 25000 26000 0; closingvol: 24000 24000 21000 21000) 

**date**|**time**|**sym**|**volume**|**closingvol**
:-----:|:-----:|:-----:|:-----:|:-----:
2019-02-01|12:59:00|AAPL|100|24000
2019-02-01|15:59:00|AAPL|25000|24000
2019-02-02|12:59:00|AAPL|26000|21000
2019-02-02|15:59:00|AAPL|0|21000

我想成为

**date**|**time**|**sym**|**volume**|**closingvol**
:-----:|:-----:|:-----:|:-----:|:-----:
2019-02-01|12:59:00|AAPL|100|24000
2019-02-01|15:59:00|AAPL|1000|24000
2019-02-02|12:59:00|AAPL|5000|21000
2019-02-02|15:59:00|AAPL|0|21000

我希望可以摆脱下面的内容,但是“或”显然不像我希望的那样起作用,因为它永远不会修改第二个12:59:00条目。

update volume:volume-closingvol from t where (time=15:59:00 | time=12:59:00), volume>=closingvol

**date**|**time**|**sym**|**volume**|**closingvol**
:-----:|:-----:|:-----:|:-----:|:-----:
2019-02-01|12:59:00|AAPL|100|24000 
2019-02-01|15:59:00|AAPL|1000|24000
2019-02-02|12:59:00|AAPL|26000|21000
2019-02-02|15:59:00|AAPL|0|21000

**更新1 **

根据建议,我也尝试过:

更新t的音量:volume-closingvol,其中(time = 15:59:00)| time = 12:59:00,volume> = closingvol

例如如下所示,所有卷均已更新。我本来希望在2019.02.01上仅更新AAPL的15:59:00和BAC的12:59:00,而在2019.02.02上仅更新BAC的15:59:00和12:59: AAPL为00,但这会修改​​12:59:00和15:59:00的所有实例。

t:([]date:2019.02.01 2019.02.01 2019.02.02 2019.02.02 2019.02.02 2019.02.02 2019.02.01 2019.02.01;time:12:59:00 15:59:00 12:59:00 15:59:00 12:59:00 15:59:00 12:59:00 15:59:00;sym:`AAPL`AAPL`AAPL`AAPL`BAC`BAC`BAC`BAC;volume:100 25000 26000 0 20000 12000 13000 0; closingvol: 24000 24000 21000 21000 11000 11000 12000 12000)

t:`date`time xasc t

update volume:volume-closingvol from t where (time=15:59:00)|(time=12:59:00), volume>=closingvol


**date**|**time**|**sym**|**volume**|**closingvol**
:-----:|:-----:|:-----:|:-----:|:-----:
2019-02-01|12:59:00|AAPL|100|24000
2019-02-01|12:59:00|BAC|1000|12000
2019-02-01|15:59:00|AAPL|1000|24000
2019-02-01|15:59:00|BAC|0|12000
2019-02-02|12:59:00|AAPL|5000|21000
2019-02-02|12:59:00|BAC|9000|11000
2019-02-02|15:59:00|AAPL|0|21000
2019-02-02|15:59:00|BAC|1000|11000

3 个答案:

答案 0 :(得分:1)

目前,由于q从右到左评估where子句中的每个约束,因此发生了以下情况:

q)time:12:59:00 15:59:00 12:59:00 15:59:00
q)15:59:00 | time=12:59:00
15:59:00 15:59:00 15:59:00 15:59:00

|在这种情况下表现为最大: http://code.kx.com/q/ref/arith-integer/#or-maximum

只需更改括号的位置:

q)update volume:volume-closingvol from t where (time=15:59:00)|time=12:59:00, volume>=closingvol
date       time     sym  volume closingvol
------------------------------------------
2019.02.01 12:59:00 AAPL 100    24000     
2019.02.01 15:59:00 AAPL 1000   24000     
2019.02.02 12:59:00 AAPL 5000   21000     
2019.02.02 15:59:00 AAPL 0      21000  

编辑作为第二示例-

您可以使用fby(http://code.kx.com/q/ref/qsql/#fby),这将允许您添加其他约束,从而更新每个符号/日期的最大记录(时间为12:59或15:59):

q)update volume:volume-closingvol from t where (time=15:59:00)|time=12:59:00,volume>=closingvol,time=(max;time)fby ([]date;sym)
date       time     sym  volume closingvol
------------------------------------------
2019.02.01 12:59:00 AAPL 100    24000     
2019.02.01 12:59:00 BAC  1000   12000     
2019.02.01 15:59:00 AAPL 1000   24000     
2019.02.01 15:59:00 BAC  0      12000     
2019.02.02 12:59:00 AAPL 5000   21000     
2019.02.02 12:59:00 BAC  20000  11000     
2019.02.02 15:59:00 AAPL 0      21000     
2019.02.02 15:59:00 BAC  1000   11000    

答案 1 :(得分:0)

vector conditional ?在这里可能有用:

update volume:?[time in 12:59:00 15:59:00;volume-closingvol;volume] from t where vol>=closingvol

第一个参数需要一个布尔列表,该列表由time in 12:59:00 15:59:00检查创建,并在列表返回True的情况下应用第一个条件(删除closeingvol),否则应用第二个条件(按原样放量)。

答案 2 :(得分:0)

您的示例显示,两次交易的交易量都可能大于收盘交易的交易量-(12:59:00 15:59:00)对于同一日期,交易对。这就是为什么条件'vol> = closingvol'给出错误答案的原因(您在示例中使用了该答案,并在帖子的其他答案中使用了该答案)。

以下解决方案将基于以下假设起作用:

  1. 所有日期,符号组合都有两个时间-(12:59:00 15:59:00)。
  2. 数据按时间排序。

即使以上假设在实际情况中不成立,也很容易更改下面的查询以使其工作。

  q) t:([]date:2019.02.01 2019.02.01 2019.02.02 2019.02.02 2019.02.02 2019.02.02 2019.02.01 2019.02.01;time:12:59:00 15:59:00 12:59:00 15:59:00 12:59:00 15:59:00 12:59:00 15:59:00;sym:`AAPL`AAPL`AAPL`AAPL`BAC`BAC`BAC`BAC;volume:100 25000 26000 0 20000 12000 13000 0; closingvol: 24000 24000 21000 21000 11000 11000 12000 12000)

  q) update volume:{?[0=x 1;(x[0]-y[0]),x 1;x[0],x[1]-y[1]]}[volume;closingvol] by date,sym from t where  time in (12:59:00 15:59:00)

或同一查询的其他版本:

  q) update volume: volume-closingvol*(0 1;1 0)0=volume 1 by date,sym from t where  time in (12:59:00 15:59:00)
date       time     sym  volume closingvol
------------------------------------------
2019.02.01 12:59:00 AAPL 100    24000     
2019.02.01 15:59:00 AAPL 1000   24000     
2019.02.02 12:59:00 AAPL 5000   21000     
2019.02.02 15:59:00 AAPL 0      21000     
2019.02.02 12:59:00 BAC  20000  11000     
2019.02.02 15:59:00 BAC  1000   11000     
2019.02.01 12:59:00 BAC  1000   12000     
2019.02.01 15:59:00 BAC  0      12000 

您还可以通过用volume和closevol替换x和y来避免在查询中使用lambda函数。我用这种方法把它缩小了。