Search code examples
kdb

q / KDB+ How to populate table with random symbols from the list?


I am trying to create a table, using the following syntax:

rows: 100
syms:(`VOD.L;`APPL;`AZ.L;`FB)
values:([] timestamp: rand each rows#.z.t; sym:rand syms; quote:rand each rows#1000; bid:rand each rows#1000; ask:rand each rows#1000; price:rand each rows#1000)
values

And it is returning the following:

timestamp    sym  quote bid ask price
-------------------------------------
08:08:00.050 APPL 466   498 263 657  
10:09:27.205 APPL 464   240 176 898  
04:47:18.085 APPL 191   407 105 990  
09:54:58.651 APPL 876   96  429 699  
02:19:09.967 APPL 60    227 333 954  
04:16:32.491 APPL 29    454 574 757  
00:04:47.977 APPL 945   607 559 666  
00:01:38.306 APPL 185   52  298 745  
07:41:15.101 APPL 96    397 261 924  
05:58:57.757 APPL 267   845 114 584  
04:28:41.917 APPL 20    320 300 418  
07:24:54.913 APPL 188   614 83  335  
07:03:28.536 APPL 248   20  831 565  
02:32:59.849 APPL 435   485 274 27   
08:24:16.294 APPL 831   66  810 418  
10:31:42.552 APPL 876   19  147 586  
10:40:04.843 APPL 539   752 351 194  
03:16:53.847 APPL 6     600 905 321  
03:55:59.228 APPL 376   288 427 645  
08:08:32.805 APPL 350   742 126 942  
..

The problem is that all symbols are the same - APPL:

select from values where sym<>`APPL
    
timestamp sym quote bid ask price
---------------------------------

I am not able to randomise them. I have attempted to use the same approach as randomising timestamps or number values, like this...

values:([] timestamp: rand each rows#.z.t; sym:rand each rows#syms; quote:rand each rows#1000; bid:rand each rows#1000; ask:rand each rows#1000; price:rand each rows#1000)

... but then I get the following error:

evaluation error:

VOD.L

  [3]  (<q>)


  [2]  (.q.rand)


  [1]  (.q.each)


  [0]  values:([] timestamp: rand each rows#.z.t; sym:rand each rows#syms; quote:rand each rows#1000; bid:rand each rows#1000; ask:rand each rows#1000; price:rand each rows#1000)
                                                                                     

Clearly I must be stuck on something silly, but to me it's just not obvious what it could be. Please help.

Thanks in advance.


Solution

  • Use a roll ? instead of rand:

    q)([]timestamp:rows?.z.t;sym:rows?syms;quote:rows?1000;bid:rows?1000;ask:rows?1000;price:rows?1000)
    timestamp    sym   quote bid ask price
    --------------------------------------
    00:28:43.630 AZ.L  181   879 501 394
    00:13:16.346 APPL  421   555 529 52
    04:33:06.881 APPL  379   386 914 259
    01:55:03.027 FB    198   399 684 990
    05:23:18.919 AZ.L  728   318 641 264
    ...
    

    Details here: https://code.kx.com/q/ref/deal/

    Roll/deal are better for lists, rand (https://code.kx.com/q/ref/rand/) is only good for picking one value. As stated in the docs:

    "rand is exactly equivalent to {first 1?x}. If you need a list result, use Roll"