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.

上执行我们的逻辑
  1. 正如我们所见,代码 VXZ4 从 2010-01-01 到 2010-01-03.
  2. 2010-01-04,当天最大成交量为VXG8
  3. 现在我们想要从 2010-01-05 到 2010-01-31 的 roll_rank:1 符号 应该是VXG8.
  4. 我们希望在 2010-01-04 到 2010-01-31 期间将 VXZ4 设置为 rollrank:0。
  5. 一旦rollrank设置为0,就无法翻转。例如,符号 VXZ4 翻转为 VXG8
  6. 在 2010-01-04,然后在期货日期我们不能让 VXZ4 再次出现在交易品种列表中 我们希望它设置为 roll_rank:0,这意味着我们不必再次看到它。
  7. 我们要根据最高音量更新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
...

同样,根据需要添加更多逻辑。

此答案假设您的 rolloverroll_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
..