├── README.md ├── tick.q └── tick ├── r.q └── u.q /README.md: -------------------------------------------------------------------------------- 1 | # kdb+tick 2 | 3 | Files previously at code.kx.com/wsvn/kx/kdb+tick 4 | 5 | * tick.q: vanilla tickerplant script, used by kdb+ 6 | * tick/u.q: pub/sub script used by tick.q 7 | * tick/r.q: vanilla RDB script, used by kdb+ 8 | 9 | See http://code.kx.com/q/ for details 10 | 11 | ## Hot-linking 12 | 13 | You are welcome to download and use this code according to the terms of the licence. 14 | 15 | Kx Systems recommends you do not link your application to this repository, 16 | which would expose your application to various risks: 17 | 18 | - This is not a high-availability hosting service 19 | - Updates to the repo may break your application 20 | - Code refactoring might return 404s to your application 21 | 22 | Instead, download code and subject it to the version control and regression testing 23 | you use for your application. 24 | -------------------------------------------------------------------------------- /tick.q: -------------------------------------------------------------------------------- 1 | / q tick.q sym . -p 5001 foo 2>&1 & 2 | /2014.03.12 remove license check 3 | /2013.09.05 warn on corrupt log 4 | /2013.08.14 allow when -u is set 5 | /2012.11.09 use timestamp type rather than time. -19h/"t"/.z.Z -> -16h/"n"/.z.P 6 | /2011.02.10 i->i,j to avoid duplicate data if subscription whilst data in buffer 7 | /2009.07.30 ts day (and "d"$a instead of floor a) 8 | /2008.09.09 .k -> .q, 2.4 9 | /2008.02.03 tick/r.k allow no log 10 | /2007.09.03 check one day flip 11 | /2006.10.18 check type? 12 | /2006.07.24 pub then log 13 | /2006.02.09 fix(2005.11.28) .z.ts end-of-day 14 | /2006.01.05 @[;`sym;`g#] in tick.k load 15 | /2005.12.21 tick/r.k reset `g#sym 16 | /2005.12.11 feed can send .u.endofday 17 | /2005.11.28 zero-end-of-day 18 | /2005.10.28 allow`time on incoming 19 | /2005.10.10 zero latency 20 | "kdb+tick 2.8 2014.03.12" 21 | 22 | /q tick.q SRC [DST] [-p 5010] [-o h] 23 | system"l tick/",(src:first .z.x,enlist"sym"),".q" 24 | 25 | if[not system"p";system"p 5010"] 26 | 27 | \l tick/u.q 28 | \d .u 29 | ld:{if[not type key L::`$(-10_string L),string x;.[L;();:;()]];i::j::-11!(-2;L);if[0<=type i;-2 (string L)," is a corrupt log. Truncate to length ",(string last i)," and restart";exit 1];hopen L}; 30 | tick:{init[];if[not min(`time`sym~2#key flip value@)each t;'`timesym];@[;`sym;`g#]each t;d::.z.D;if[l::count y;L::`$":",y,"/",x,10#".";l::ld d]}; 31 | 32 | endofday:{end d;d+:1;if[l;hclose l;l::0(`.u.ld;d)]}; 33 | ts:{if[dtype first x;a,x;(enlist(count first x)#a),x]]; 39 | t insert x;if[l;l enlist (`upd;t;x);j+:1];}]; 40 | 41 | if[not system"t";system"t 1000"; 42 | .z.ts:{ts .z.D}; 43 | upd:{[t;x]ts"d"$a:.z.P; 44 | if[not -16=type first first x;a:"n"$a;x:$[0>type first x;a,x;(enlist(count first x)#a),x]]; 45 | f:key flip value t;pub[t;$[0>type first x;enlist f!x;flip f!x]];if[l;l enlist (`upd;t;x);i+:1];}]; 46 | 47 | \d . 48 | .u.tick[src;.z.x 1]; 49 | 50 | \ 51 | globals used 52 | .u.w - dictionary of tables->(handle;syms) 53 | .u.i - msg count in log file 54 | .u.j - total msg count (log file plus those held in buffer) 55 | .u.t - table names 56 | .u.L - tp log filename, e.g. `:./sym2008.09.11 57 | .u.l - handle to tp log file 58 | .u.d - date 59 | 60 | /test 61 | >q tick.q 62 | >q tick/ssl.q 63 | 64 | /run 65 | >q tick.q sym . -p 5010 /tick 66 | >q tick/r.q :5010 -p 5011 /rdb 67 | >q sym -p 5012 /hdb 68 | >q tick/ssl.q sym :5010 /feed 69 | -------------------------------------------------------------------------------- /tick/r.q: -------------------------------------------------------------------------------- 1 | /q tick/r.q [host]:port[:usr:pwd] [host]:port[:usr:pwd] 2 | /2008.09.09 .k ->.q 3 | 4 | if[not "w"=first string .z.o;system "sleep 1"]; 5 | 6 | upd:insert; 7 | 8 | / get the ticker plant and history ports, defaults are 5010,5012 9 | .u.x:.z.x,(count .z.x)_(":5010";":5012"); 10 | 11 | / end of day: save, clear, hdb reload 12 | .u.end:{t:tables`.;t@:where `g=attr each t@\:`sym;.Q.hdpf[`$":",.u.x 1;`:.;x;`sym];@[;`sym;`g#] each t;}; 13 | 14 | / init schema and sync up from log file;cd to hdb(so client save can run) 15 | .u.rep:{(.[;();:;].)each x;if[null first y;:()];-11!y;system "cd ",1_-10_string first reverse y}; 16 | / HARDCODE \cd if other than logdir/db 17 | 18 | / connect to ticker plant for (schema;(logcount;log)) 19 | .u.rep .(hopen `$":",.u.x 0)"(.u.sub[`;`];`.u `i`L)"; 20 | 21 | -------------------------------------------------------------------------------- /tick/u.q: -------------------------------------------------------------------------------- 1 | /2019.06.17 ensure sym has g attr for schema returned to new subscriber 2 | /2008.09.09 .k -> .q 3 | /2006.05.08 add 4 | 5 | \d .u 6 | init:{w::t!(count t::tables`.)#()} 7 | 8 | del:{w[x]_:w[x;;0]?y};.z.pc:{del[;x]each t}; 9 | 10 | sel:{$[`~y;x;select from x where sym in y]} 11 | 12 | pub:{[t;x]{[t;x;w]if[count x:sel[x]w 1;(neg first w)(`upd;t;x)]}[t;x]each w t} 13 | 14 | add:{$[(count w x)>i:w[x;;0]?.z.w;.[`.u.w;(x;i;1);union;y];w[x],:enlist(.z.w;y)];(x;$[99=type v:value x;sel[v]y;@[0#v;`sym;`g#]])} 15 | 16 | sub:{if[x~`;:sub[;y]each t];if[not x in t;'x];del[x].z.w;add[x;y]} 17 | 18 | end:{(neg union/[w[;;0]])@\:(`.u.end;x)} 19 | --------------------------------------------------------------------------------