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
例如在下面的 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