(kdb+/q) Pivot table:行中的日期,列中的符号,最后价格作为值

(kdb+/q) Pivot table: date in rows, symbols in columns, last price as values

http://code.kx.com/q/cookbook/pivoting-tables/ 处提供的通用枢轴函数变为:

piv:{[t;k;p;v;f;g]
 v:(),v;
 G:group flip k!(t:.Q.v t)k;
 F:group flip p!t p;
 count[k]!g[k;P;C]xcols 0!key[G]!flip(C:f[v]P:flip value flip key F)!raze
  {[i;j;k;x;y]
   a:count[x]#x 0N;
   a[y]:x y;
   b:count[x]#0b;
   b[y]:1b;
   c:a i;
   c[k]:first'[a[j]@'where'[b j]];
   c}[I[;0];I J;J:where 1<>count'[I:value G]]/:\:[t v;value F]}

鉴于 fg 定义为

 f:{[v;P]`$raze each string raze P[;0],'/:v,/:\:P[;1]}
 g:{[k;P;c]k,(raze/)flip flip each 5 cut'10 cut raze reverse 10 cut asc c}

现在这个例子可以工作了(参见上面的 link table q 是如何定义的):

piv[`q;`date`sym`time;`side`level;`price`size;f;g]

date       sym  time        | Bprice0 Bsize0 Aprice0  Asize0 Bprice1  Bsize1 ..
----------------------------| -----------------------------------------------..
2009.01.05 milg 09:30:00.187|                                93.56285 29     ..
2009.01.05 milg 09:30:15.798|                                                ..
2009.01.05 milg 09:30:30.627|                                                ..

在我的例子中,我想按 sym(每列不同的符号)和 date(每行不同的日期)作为关键,最后一个值为 price(给定日期和代码的每个单元格的最后价格)。

这个幼稚的调用不起作用:

piv[`q;`date;`sym;`price;f;g]

如何重新定义 fg 函数,以便能够为每个不同的日期和每个交易品种获得 table 最后的价格,产生类似这样的结果?

date       |  syma    symb     symc 
-----------| ----------------------
2009.01.05 | 93.56     8.5    566.1
2009.01.06 | 93.6      8.0    564.2
2009.01.07 |           9.0         
2009.01.08 | 94.05            560.3

函数piv要求keypivot参数是一个列表。所以修改你的天真调用如下给我们一个结果:

q) piv[`q;(),`date;(),`sym;`price;f;g]
    date      | obhmprice oijbprice mkjkprice nihdprice ldegprice mbgnprice jmmip..
    ----------| -----------------------------------------------------------------..
    2009.01.08| 72.35531  28.9323   23.88535  12.21371  2.417089  49.45298  98.14..
    2009.01.07| 83.59946  6.036849  21.47751  78.8127   10.8295   98.52086  92.95..
    2009.01.09| 46.80912  46.26248  81.22377  93.51525  22.72674  95.42947  0.780..
    2009.01.05| 15.15728  26.88241  52.27362  90.73569  46.13635  50.67675  36.28..
    2009.01.06| 87.55843  38.49544  44.47115  59.41535  28.59271  94.38644  72.12..

...values being last price...

您需要按如下方式预处理报价数据以获得最后价格:

q) piv[0!select last price by date,sym from `date`time xasc q;(),`date;(),`sym;`price;f;g]
    date      | obhmprice oijbprice mkjkprice nihdprice ldegprice mbgnprice jmmip..
    ----------| -----------------------------------------------------------------..
    2009.01.05| 68.45829  95.92887  55.64212  82.06286  86.33655  6.020653  49.99..
    2009.01.06| 80.80825  39.97803  44.47115  20.84011  95.24609  26.23889  21.87..
    2009.01.07| 30.9605   15.85936  2.112642  74.48924  63.82276  49.55288  9.791..
    2009.01.08| 40.17655  34.08045  49.43202  59.99883  68.43116  74.76724  96.43..
    2009.01.09| 5.628707  96.54884  93.37123  65.68942  12.78308  91.10505  59.37..

最后,要让列名成为符号名,你需要修改fg函数——可以查看文档here或者简单地添加一些调试打印以查看传递给这些函数的内容以了解它们应该是什么。

在您的情况下,它们可以简单地设置为以下内容:

q) piv[0!select last price by date,sym from `date`time xasc q;(),`date;(),`sym;`price;{y[;0]};{x,z}]
    date      | abaa     aeec     agom     ahnj     amlj     aogk     bbfc     be..
    ----------| -----------------------------------------------------------------..
    2009.01.05| 1.382202 16.05533 33.8328  31.08264 82.60021 87.60909 37.37758 82..
    2009.01.06| 14.96261 35.70751 11.48701 5.394078 47.38052 79.5398  31.46943 64..
    2009.01.07| 12.95503 17.96305 92.59666 89.16665 83.80779 15.04835 34.70387 9...
    2009.01.08| 39.33969 15.18487 2.20252  8.859751 43.23156 22.88771 15.73866 76..
    2009.01.09| 48.32295 18.01393 91.38    46.87793 45.88258 67.70167 57.27067 63..