kdb/q -- 按交易品种累计总和,但有上限

kdb/q -- cumulative sum by symbol, but with a cap

例如在下面的 table 中,我想 运行 table 的 "val" 列上的累计和按符号列分组。但我想用 "cap" 列中的值来限制累计总和。如果累计总和超过上限,我就把它限制在那个值。对于下一个值,我将把它加到上限值上:

示例(以及更好的图片格式)。我得到了输入日期、sym、val、cap,我想在 "cumval" 列中生成输出。

date        sym     val  cap cumval
-----------------------------------
2020.01.01  AAPL    100  200 100
2020.01.02  AAPL    100  200 200
2020.01.03  AAPL    100  200 200
2020.01.04  AAPL    -100 200 100
2020.01.01  MSFT    100  300 100
2020.01.02  MSFT    100  300 200
2020.01.03  MSFT    100  300 300
2020.01.04  MSFT    100  400 400

您需要使用自定义累加器来获得结果。内置 sums 函数使用二进制累加器 \。要添加上限逻辑,您需要使用 ternary scan accumulator。以下将起作用 {z&x+y}\。第一个参数是初始值,在您的情况下为零。第二个参数是累积的值,第三个参数是上限值。

q)show t:([]date:2020.01.01 2020.01.02 2020.01.03 2020.01.04 2020.01.01 2020.01.02 2020.01.03 2020.01.04;sym:`AAPL`AAPL`AAPL`AAPL`MSFT`MSFT`MSFT`MSFT;val:100 100 100 -100 100 100 100 100;cap:200 200 200 200 300 300 300 400)
date       sym  val  cap
------------------------
2020.01.01 AAPL 100  200
2020.01.02 AAPL 100  200
2020.01.03 AAPL 100  200
2020.01.04 AAPL -100 200
2020.01.01 MSFT 100  300
2020.01.02 MSFT 100  300
2020.01.03 MSFT 100  300
2020.01.04 MSFT 100  400
q)update cumval:{z&x+y}\[0;val;cap] by sym from t
date       sym  val  cap cumval
-------------------------------
2020.01.01 AAPL 100  200 100
2020.01.02 AAPL 100  200 200
2020.01.03 AAPL 100  200 200
2020.01.04 AAPL -100 200 100
2020.01.01 MSFT 100  300 100
2020.01.02 MSFT 100  300 200
2020.01.03 MSFT 100  300 300
2020.01.04 MSFT 100  400 400