kdb+ 一旦符号翻转过来,那么它不应该来回翻转
kdb+ once the symbol flipped over, then it should not flipped back and forth
要生成以下示例数据,请使用以下代码。
//To create a sample table
tdate:2010.01.01+til 31
tmp:([]sdate:`date$();sym:`symbol$();name:`symbol$();volume:`float$();rollover:`boolean$();roll_rank:`int$());
{`tmp insert (x;`VXV2;`someName1;100.1;0b;1)} each tdate;
{`tmp insert (x;`VXJ2;`someName2;200.2;0b;1)} each tdate;
{`tmp insert (x;`VXG8;`someName3;300.3;0b;1)} each tdate;
{`tmp insert (x;`VXZ4;`someName4;400.4;0b;1)} each tdate;
//below steps are to generate/update sample data for testing to match desired dataset which we want to create a new logic
tmp:`sdate xasc `volume xdesc tmp;
tmp:update sums roll_rank by sdate from tmp;
tmp:update volume:500.4 from tmp where sdate=2010.01.04, sym=`VXG8;
This is how the tmp table looks like on tmp
select from tmp
This is how the aggregation looks like
select from tmp where volume=(max;volume) fby sdate
我们想在 (select from tmp) table.
上执行我们的逻辑
- 正如我们所见,代码 VXZ4 从 2010-01-01 到
2010-01-03.
- 2010-01-04,当天最大成交量为VXG8
- 现在我们想要从 2010-01-05 到 2010-01-31 的 roll_rank:1 符号
应该是VXG8.
- 我们希望在 2010-01-04 到 2010-01-31 期间将 VXZ4 设置为 rollrank:0。
- 一旦rollrank设置为0,就无法翻转。例如,符号 VXZ4 翻转为 VXG8
- 在 2010-01-04,然后在期货日期我们不能让 VXZ4 再次出现在交易品种列表中
我们希望它设置为 roll_rank:0,这意味着我们不必再次看到它。
- 我们要根据最高音量更新roll_rank。
tmp:`sdate xasc `volume xdesc tmp;
tmp:update sums roll_rank by sdate from tmp;
预期输出为
并不是 100% 清楚您期望输出数据的外观(因为您的输出屏幕截图本身就是一个聚合),但这可能会让您走上正轨。
听起来您只需要保留 front-month 个符号的映射。
front_month:`s#exec sdate!sym from tmp where differ maxs volume;
q)front_month
2010.01.01| VXZ4
2010.01.04| VXG8
您可以根据需要向此选择添加更多逻辑。
然后在您的 tmp table 中,您在 per-date 的基础上查找 front-month 符号并选择该符号是前月符号的行
q)update rollover:differ sym from select from tmp where sym=front_month sdate
sdate sym name volume rollover roll_rank
---------------------------------------------------
2010.01.01 VXZ4 someName4 400.4 1 1
2010.01.02 VXZ4 someName4 400.4 0 1
2010.01.03 VXZ4 someName4 400.4 0 1
2010.01.04 VXG8 someName3 500.4 1 2
2010.01.05 VXG8 someName3 300.3 0 2
2010.01.06 VXG8 someName3 300.3 0 2
2010.01.07 VXG8 someName3 300.3 0 2
...
同样,根据需要添加更多逻辑。
此答案假设您的 rollover
和 roll_rank
列是 工具 预期输出,而不是它所必需的。
TL;DR – 求累积最大值;消除复发;插入一个空的table;填充空值
我们将在您的脚本中添加两行:一行用于测试您上一条评论中描述的约束;另一行用于测试您上一条评论中描述的约束;另一个检查我们找到 current 而不是前导符号的第一个最大值。我们还将 tmp
在 更新之后进行排序,以确保它反映它们。所以脚本结束:
//below steps are to generate/update sample data for testing
// to match desired dataset which we want to create a new logic
tmp:update volume:500.4 from tmp where sdate=2010.01.04, sym=`VXG8;
// find current not first maximum
tmp:update volume:600.6 from tmp where sdate=2010.01.05, sym=`VXG8;
// confirm VXZ4 cannot recur
tmp:update volume:700.7 from tmp where sdate=2010.01.06, sym=`VXZ4;
tmp:`sdate xasc `volume xdesc tmp;
/ tmp:update sums roll_rank by sdate from tmp;
第一步放大了特里林奇的答案。我们 select 最大变化的行,并标记符号变化的地方。
q)show q:update rollover:differ sym from select sdate,sym,name,volume from tmp where differ maxs volume
sdate sym name volume rollover
-----------------------------------------
2010.01.01 VXZ4 someName4 400.4 1
2010.01.04 VXG8 someName3 500.4 1
2010.01.05 VXG8 someName3 600.6 0
2010.01.06 VXZ4 someName4 700.7 1
第二步去掉最后一行q
,因为VXZ4
可能不会重现
为此,我们使用古老的 APL 习语来查找向量中的重复项。在 APL 中它是 (⍳⍴x)≠x⍳x
,它很容易转换为 q 为 (til count x)<>x?x
。然后我们输入 sdate
.
q)show r:1!delete from q where rollover and {(til count x)<>x?x}sym
sdate | sym name volume rollover
----------| ------------------------------
2010.01.01| VXZ4 someName4 400.4 1
2010.01.04| VXG8 someName3 500.4 1
2010.01.05| VXG8 someName3 600.6 0
这就是我们所需要的结果。剩下的只是填充物。
q)/ make a template table
q)s:1!flip`sdate`sym`name`volume!flip tdate,\:(`;`;0n)
q) and fill in the gaps
q)fills s upsert delete rollover from r
sdate | sym name volume
----------| ---------------------
2010.01.01| VXZ4 someName4 400.4
2010.01.02| VXZ4 someName4 400.4
2010.01.03| VXZ4 someName4 400.4
2010.01.04| VXG8 someName3 500.4
2010.01.05| VXG8 someName3 600.6
2010.01.06| VXG8 someName3 600.6
2010.01.07| VXG8 someName3 600.6
2010.01.08| VXG8 someName3 600.6
2010.01.09| VXG8 someName3 600.6
2010.01.10| VXG8 someName3 600.6
2010.01.11| VXG8 someName3 600.6
2010.01.12| VXG8 someName3 600.6
..
要生成以下示例数据,请使用以下代码。
//To create a sample table
tdate:2010.01.01+til 31
tmp:([]sdate:`date$();sym:`symbol$();name:`symbol$();volume:`float$();rollover:`boolean$();roll_rank:`int$());
{`tmp insert (x;`VXV2;`someName1;100.1;0b;1)} each tdate;
{`tmp insert (x;`VXJ2;`someName2;200.2;0b;1)} each tdate;
{`tmp insert (x;`VXG8;`someName3;300.3;0b;1)} each tdate;
{`tmp insert (x;`VXZ4;`someName4;400.4;0b;1)} each tdate;
//below steps are to generate/update sample data for testing to match desired dataset which we want to create a new logic
tmp:`sdate xasc `volume xdesc tmp;
tmp:update sums roll_rank by sdate from tmp;
tmp:update volume:500.4 from tmp where sdate=2010.01.04, sym=`VXG8;
This is how the tmp table looks like on tmp
select from tmp
This is how the aggregation looks like
select from tmp where volume=(max;volume) fby sdate
我们想在 (select from tmp) table.
上执行我们的逻辑- 正如我们所见,代码 VXZ4 从 2010-01-01 到 2010-01-03.
- 2010-01-04,当天最大成交量为VXG8
- 现在我们想要从 2010-01-05 到 2010-01-31 的 roll_rank:1 符号 应该是VXG8.
- 我们希望在 2010-01-04 到 2010-01-31 期间将 VXZ4 设置为 rollrank:0。
- 一旦rollrank设置为0,就无法翻转。例如,符号 VXZ4 翻转为 VXG8
- 在 2010-01-04,然后在期货日期我们不能让 VXZ4 再次出现在交易品种列表中 我们希望它设置为 roll_rank:0,这意味着我们不必再次看到它。
- 我们要根据最高音量更新roll_rank。
tmp:`sdate xasc `volume xdesc tmp;
tmp:update sums roll_rank by sdate from tmp;
预期输出为
并不是 100% 清楚您期望输出数据的外观(因为您的输出屏幕截图本身就是一个聚合),但这可能会让您走上正轨。
听起来您只需要保留 front-month 个符号的映射。
front_month:`s#exec sdate!sym from tmp where differ maxs volume;
q)front_month
2010.01.01| VXZ4
2010.01.04| VXG8
您可以根据需要向此选择添加更多逻辑。
然后在您的 tmp table 中,您在 per-date 的基础上查找 front-month 符号并选择该符号是前月符号的行
q)update rollover:differ sym from select from tmp where sym=front_month sdate
sdate sym name volume rollover roll_rank
---------------------------------------------------
2010.01.01 VXZ4 someName4 400.4 1 1
2010.01.02 VXZ4 someName4 400.4 0 1
2010.01.03 VXZ4 someName4 400.4 0 1
2010.01.04 VXG8 someName3 500.4 1 2
2010.01.05 VXG8 someName3 300.3 0 2
2010.01.06 VXG8 someName3 300.3 0 2
2010.01.07 VXG8 someName3 300.3 0 2
...
同样,根据需要添加更多逻辑。
此答案假设您的 rollover
和 roll_rank
列是 工具 预期输出,而不是它所必需的。
TL;DR – 求累积最大值;消除复发;插入一个空的table;填充空值
我们将在您的脚本中添加两行:一行用于测试您上一条评论中描述的约束;另一行用于测试您上一条评论中描述的约束;另一个检查我们找到 current 而不是前导符号的第一个最大值。我们还将 tmp
在 更新之后进行排序,以确保它反映它们。所以脚本结束:
//below steps are to generate/update sample data for testing
// to match desired dataset which we want to create a new logic
tmp:update volume:500.4 from tmp where sdate=2010.01.04, sym=`VXG8;
// find current not first maximum
tmp:update volume:600.6 from tmp where sdate=2010.01.05, sym=`VXG8;
// confirm VXZ4 cannot recur
tmp:update volume:700.7 from tmp where sdate=2010.01.06, sym=`VXZ4;
tmp:`sdate xasc `volume xdesc tmp;
/ tmp:update sums roll_rank by sdate from tmp;
第一步放大了特里林奇的答案。我们 select 最大变化的行,并标记符号变化的地方。
q)show q:update rollover:differ sym from select sdate,sym,name,volume from tmp where differ maxs volume
sdate sym name volume rollover
-----------------------------------------
2010.01.01 VXZ4 someName4 400.4 1
2010.01.04 VXG8 someName3 500.4 1
2010.01.05 VXG8 someName3 600.6 0
2010.01.06 VXZ4 someName4 700.7 1
第二步去掉最后一行q
,因为VXZ4
可能不会重现
为此,我们使用古老的 APL 习语来查找向量中的重复项。在 APL 中它是 (⍳⍴x)≠x⍳x
,它很容易转换为 q 为 (til count x)<>x?x
。然后我们输入 sdate
.
q)show r:1!delete from q where rollover and {(til count x)<>x?x}sym
sdate | sym name volume rollover
----------| ------------------------------
2010.01.01| VXZ4 someName4 400.4 1
2010.01.04| VXG8 someName3 500.4 1
2010.01.05| VXG8 someName3 600.6 0
这就是我们所需要的结果。剩下的只是填充物。
q)/ make a template table
q)s:1!flip`sdate`sym`name`volume!flip tdate,\:(`;`;0n)
q) and fill in the gaps
q)fills s upsert delete rollover from r
sdate | sym name volume
----------| ---------------------
2010.01.01| VXZ4 someName4 400.4
2010.01.02| VXZ4 someName4 400.4
2010.01.03| VXZ4 someName4 400.4
2010.01.04| VXG8 someName3 500.4
2010.01.05| VXG8 someName3 600.6
2010.01.06| VXG8 someName3 600.6
2010.01.07| VXG8 someName3 600.6
2010.01.08| VXG8 someName3 600.6
2010.01.09| VXG8 someName3 600.6
2010.01.10| VXG8 someName3 600.6
2010.01.11| VXG8 someName3 600.6
2010.01.12| VXG8 someName3 600.6
..