草本香舍能调理皮肤吗:Wiki: KdbPlusSlides

来源:百度文库 编辑:偶看新闻 时间:2024/04/29 08:19:04
基于开源软件的金融计算 最近更新 交易技术 金融市场 Kdb+ GIT仓库 RSS汇集 使用帮助

KdbPlusSlides

kdb+使用介绍

安装与启动

下载试用版(32bit+2小时退出限制)

  • w32
  • l32

安装

  • 默认路径
    • w32:解压到c盘根目录
    • l32:解压到用户HOME目录~内
  • 自选路径:解压到任意路径后设置相应环境变量QHOME,例如:
    • w32:set QHOME=d:\q
    • l32:export QHOME=/opt/q
  • 安装odbc选件
    1. 下载odbc.k到q目录
    2. 下载odbc.dll到q/w32子目录,或odbc.so到q/l32子目录
  • 安装qml选件(http://althenia.net/qml)
    1. 下载qml-0.2.1.zip
    2. 解压后将源码加入q目录,动态库加入对应执行文件子目录

启动

  • w32:set path=c:/q/w32;%path%,q -p 5001
  • l32:export PATH=/root/q/l32:$PATH,rlwrap q -p 5001
  • 命令行参考(https://code.kx.com/trac/wiki/Reference/Cmdline)
    • 一般格式 q [脚本|磁盘表文件|数据库目录] [选项列表] [脚本参数列表]
    • 常用选项
      • -p:web/ipc监听端口,如 -p 5000,端口号为负数表示客户端多线程模式,即每个客户端查询使用独立线程并发服务
      • -s:服务端多线程模式,如 -s 16,目前最大支持16,用于对分区数据库的并发查询和基于peach的并行计算,与客户端多线程模式互斥
      • -l/-L:写磁盘log,-l为缓冲IO,-L为同步IO,通常使用-l
      • -t:内部定时器周期毫秒数,如 -t 500会每隔500毫秒运行.z.ts函数
      • -c/-C:屏幕/WEB 显示行列数,如 -c 20 80,-C 80 160
      • -P:屏幕显示数值精度,如 -P 0为全部精度,-P 6为显示6位浮点精度
      • -b:客户端只读模式
      • -u/-U:用户账号认证
      • -T:客户端查询超时秒数,如-T 60会Abort运行超过1分钟的客户端查询
      • -r/-R:同步复制其他kdb+实例,注意要能够访问该实例的log日志,如 -r :127.0.0.1:5001

连接与使用

  • 连接方式
    • 本地终端交互
q)sum til 1045
    • WEB方式查询:http://localhost:5001
      • excel定时web查询:
http://127.0.0.1:4441/q.txt?`fsym xasc select fsym,price,size,o1sz,o1px,b1px,b1sz,vwap,cumqty,high,low,o5px,o5sz,o4px,o4sz,o3px,o3sz,o2px,o2sz,b2px,b2sz,b3px,b3sz,b4px,b4sz,b5px,b5sz from QX 
    • 远程终端连接
q)h:hopen `:127.0.0.1:5001q)h "sum til 10"45q)(-h)"a:2"
    • 远程客户端API方式连接:C/C++,Java,C#,Matlab,...
    • IDE开发环境:Studio for kdb+(win32下载,l32下载)
  • 使用方式
    • 内部命令
      • \a:查看table列表
      • \b:查看view列表
      • \v:查看变量列表
      • \f:查看函数列表
      • \w:查看内存使用,也可使用.Q.w[]
      • \l [f]:load file (or dir:files splays parts scripts)
      • \ts exp:统计执行exp所需时间(毫秒数)和空间(字节数)
      • \cd..:\开头的非内部命令作为操作系统命令执行
      • \\:结束q进程
      • \e 0|1: error trap clients
      • \c [23 79]:view/set console height,width
      • \p [i]:view/set port (0 turns off)
      • \t [t]:view/set timer (or time expression) (1st fire after delay)
      • \C [36 2000]:view/set browser height,width
      • \P [7]:view/set print digits(0-all)
      • \S [-314159]:view/set random seed
      • \T [0]:view/set client timeout
    • 交互式执行语句
      • 使用\在q模式与k模式间切换
      • 使用k)前缀执行k代码
      • 使用s)前缀执行sql代码
      • 使用;抑制运行结果输出
    • 系统错误列表

q语言基础

数据类型

Kdb+ type name Kdb+ type number Encoded type name C type Size in bytes Interface list/accessor function example null inf mixed list 0 - K - kK (`a;"bcd";10b;45;7 8f),() - - boolean 1 KB char 1 kG 0b,10001b - - byte 4 KG char 1 kG 0x1f,0xffff00 - - short 5 KH short 2 kH 5h,1 2 3 4 5h 0Nh 0Wh,-0Wh int 6 KI int 4 kI 5,1 2 3 4 5 0N 0W,-0W long 7 KJ int64_t 8 kJ 5j,1 2 3 4 5j 0Nj 0Wj,-0Wj real 8 KE float 4 kE 4.2e,1.1 2.2 3.3e 0Ne 0we,-0we float 9 KF double 8 kF 4.2,1.1 2.2 3.3 0n 0w,-0w char 10 KC char 1 kC "m",enlist "m","mner gh","" " " - symbol 11 KS char* 4 or 8 kS `abc,`a`b`c`d ` - timestamp 12 KP int64_t 8 kJ 2010.09.02D14:48:31.232875000 0Np 0Wp,-0Wp month 13 KM int 4 kI 2010.09m 0Nm 0Wm,-0Wm date 14 KD int 4 kI (days from 2000.01.01) 2010.09.01 0Nd 0Wd,-0Wd datetime 15 KZ double 8 kF (days from 2000.01.01) 2010.09.02T14:49:11.029 0Nz 0Wz,-0Wz timespan 16 KN int64_t 8 kJ 0D00:00:05.359375000 0Nn 0Wn,-0Wn minute 17 KU int 4 kI 15:00 0Nu 0Wu,-0Wu second 18 KV int 4 kI 09:30:00 0Nv 0Wv,-0Wv time 19 KT int 4 kI (milliseconds) 14:50:28.029 0Nt 0Wt,-0Wt table/flip 98 XT - - x->k ([]a:`a`b`c`d;b:1 2 3 4) - - dict/table 99 XD - - kK(x)[0] for keys and kK(x)[1] for values `a`b`c`d!(`f;1.2;0110b;"tmp") - - error -128 - char* 4 or 8 kS - - - 特殊类型 类型号 例子 user enum 20+ `sym$600000.XSHG lambda 100 {[x;y]x+2*y} unary prim 101 sin,cos binary prim 102 xexp ternary(operator) 103 ',\: projection 104 (5 xexp) composition 105 '[sin;xexp] f'(each) 106 ,' f/(over) 107 +/ f\(scan) 108 +\ f':(eachprior) 109 -': f/:(each right) 110 ,/: f\:(each left) 111 ,\: dynamic load 112 `oslib 2: (`udpsend;1)
  • 类型转换$
    • 兼容类型互转:"i"$5.4或`int$5.4,`$"abc"
    • 字符串解析:"F"$"5.4","I"$"12345","S"$"abc"
  • 数组类型(list)
    • 数组分为类型数组(值数组,unboxed)和混合数组(指针数组,boxed)
    • string就是字符数组,没有单独的字符串类型
    • 没有单独的二维矩阵(或一般的多维类型数组)概念,二维矩阵就是一个混合数组,每个元素为等长的浮点数组
    • 使用enlist创建单元素数组(singleton),如enlist 5,不能采用加括号的方式,如(5)等价于原子5,type enlist 5=6h,type (5)=-6h
    • 数值型数组使用空格区分元素,如1 2 3,1.1 2.2 3.3,2001.1m 2001.2m,对于h,j,e三种特殊类型在数组最后加修饰符如1 2 3j,4 5 6e,其它类型无分割符,如0110b,0xff00ff,"abcd",`a`b`c`
    • 使用()和;构建显示混合数组,如(`abc;4;5 6;"abc")
    • 数组下标从0开始,越界读取返回null值,越界写入报错,不能使用负数下标反向寻址,尾元素为last a,首元素为first a=a[0]
    • 数组基本操作(a:til 10=0 1 2 3 4 5 6 7 8 9)
      • 连接(join):,连接数组/原子,如1 2 3 4,5或1,2 3 4 5或1 2,3 4 5
      • 子数组块复制(take):#,如3#a=0 1 2,-3#a=7 8 9,二维复制如2 3#a=(0 1 2;3 4 5)
        • 长度超出时循环补齐,如3 4#a=(0 1 2 3;4 5 6 7;8 9 0 1)
        • #可用于单元素复制,如3 4#0(0 0 0 0;0 0 0 0;0 0 0 0)
        • 列数固定分块:0N 3#a=(0 1 2;3 4 5;6 7 8;,9)
        • 行数固定分块:3 0N#a=(0 1 2 3;4 5 6 7;8 9)
        • 可以使用0#获得空表
      • 子数组块删除(drop):_,如7_a=7 8 9,-7_a=0 1 2,单元素删除(delete)如a _4=0 1 2 3 5 6 7 8 9
      • 数组分块(cut):_,如0 3 7 _ a=0 3 7 cut a=(0 1 2;3 4 5 6;7 8 9),4 cut a=0N 4#a=(0 1 2 3;4 5 6 7;8 9)
      • 数组翻转:reverse a=9 8 7 6 5 4 3 2 1 0
      • 矩阵转置:flip (0 1 2;3 4 5)=(0 3;1 4;2 5)
    • 数组寻址(b=0N 3#a=(0 1 2;3 4 5;6 7 8;,9))
      • 一层寻址:b[1]=b 1=3 4 5,b[0 2]=b 0 2=b@0 2=(0 1 2;6 7 8)
      • 深层寻址:b[1;2]=b . 1 2=5,取子列b[;2]=2 5 8 0N
  • 字典类型(dict,hashmap)
    • 是数组的推广,list->list的一一映射,用!构建,如d:`a`b`c!(1;"456";3.2),!前的部分称为定义域,后部称为值域,可分别用key d,value d获得
    • 字典创建后key列和value列的类型就固定了,当增加/修改操作时使用不兼容类型时就会报错,如d[4.5]:7,可以使用占位符::强制创建通用列表,如d:(::;`a;`b;`c)!(::;1;"456";3.2)
    • 元素寻址方式为d[`b]=d `b=d@`b="456",不在定义域内的元素查找返回值域第一个元素对应类型的null值
    • 插入或更新(upsert),如d[`f]:6或d,`b`g!1 2
    • 值域内查找用?,如d?3.2,不在值域内的元素查找返回定义域第一个元素对应类型的null值
    • 元素删除用_,如d _ `b=(enlist `b) _ d,注意只是返回修改后的字典,原字典并未修改
    • 定义域相同的字典可以进行算术运算,即值域进行相应运算
  • 表类型
    • 表是一个特殊的list,每个元素都是具有相同定义域元素和值域类型的字典,如d:`x`y!(`a;2),f:(d;`x`y!(`b;3))
    • 表也可以看成列字典的转置,如f:flip`x`y!(`a`b;2 3)
    • 表可以用列表示定义,如f:([]x:`a`b;y:2 3)
    • 表的第i行(第i条记录)就是list的第i个元素字典
  • 表字典(带主键的表)
    • 列表示定义为f:([x:`a`b]y:2 3)
    • 是定义域和值域都是表的特殊字典
  • 日期时间相关类型
    • 使用.z.P获得基本时间戳t:.z.P
    • 获取分量:t.(year mm dd hh uu ss month date week minute second time)
    • month.(year mm)
    • date.(year mm dd month week)
    • minute.(hh mm)
    • second.(hh mm ss minute)
    • time.(hh mm ss minute second)
    • Week is rolled to mondays.Day of week is date mod 7 . 0 is saturday. Quarters can be handled as 3 xbar month .

基本语法

  • 变量
    • 变量名大小写敏感
    • 使用:进行变量赋值,如a:3,在全局环境为全局变量赋值,在函数体内为局部变量赋值
    • 在函数体内对全局变量赋值用::
    • 在全局环境用::赋值依赖变量(view),如b::a+1,注意不能用;结尾
    • 可以使用set进行全局变量批量赋值:`a`b`c set' 1 2 3
  • 语句(表达式)
    • 使用;作为语句结束符
    • 对于.k文件,换行等价于插入一个;,因此在$[...]和(...)间的换行要特别注意!
    • 使用""作为字符串起止符,字符串内使用\进行escape,支持的escape模式为
      • \":转义双引号
      • \\:转义反斜线
      • \NNN:character with octal value NNN (3 digits)
      • \n:换行
      • \r:回车
      • \t:制表符
    • 赋值作为表达式返回左值,支持嵌套,如a:b:1+c:(d:2*7)*e:5
    • 没有运算符优先级,表达式由右至左计算,如2*3+414
    • 使用value函数进行字符串动态解释执行,如value "a:2*sin 5"
    • 除法用%而不是/,乘方用xexp而不是**或^
  • 函数
    • 定义形式为函数名:{[局部变量声明]语句序列},例如f:{[s;t]u:1;u+s+t}
    • 如果省略局部变量声明,则根据函数体x,y,z的存在情况自动判断,例如g:{x+2*y}
    • 函数f编译结果:(bytecode;params(8);locals(23);globals(31)),Constants(96)可以使用value f查看
    • 函数中的分支结构编译字节码不能超过255字节
    • 多行函数定义(或表达式)除首行外其他行首必须缩进(注意除末行外每行末都有一个隐含的;)
    • 一元函数调用入参用空格或[]或使用@算符,如sin[1]=sin 1=sin@1
    • 多元函数调用入参用;间隔或使用.算符,如f:{[x;y]x+2*y};f[2;3]=f . 2 3
  • 控制结构(表达式)
    • if[cond;exp1;exp2;...]条件执行,返回::值.
    • do[n;exp1;exp2;...]重复执行,返回::值.无对应的for结构
    • while[cond;exp1;exp2;...]条件重复执行,返回::值.无对应的break和continue功能
    • case表达式$[c1;e1;c2;e2;c3;e3;e4]条件计算表达式并返回值,如果是多语句复合表达式要用[]包围,如$[a1;3;a2;[b:1;1+b];0]
    • 向量版case表达式?[C;Y;Z],C,Y,Z是等长向量或者Y,Z之一为原子,对每个元素分别条件取值
    • 函数体内快速返回用:,如f:{[x]if[x<0;:-1];1+sqrt x}
    • 函数体内抛出异常用':如f:{[x]if[x<0;'error];1+sqrt x},此时进入debug模式,用\退出
    • 保护式执行(try-catch):@[f;x;r]或.[f;x;r],trap: f @ x 或f . x (return r on error. if r is a func apply r to error string.)
  • 注释
    • 使用 空格+/作为单行注释
    • 用单独一行/与单独一行\作为多行注释起止标志

内置函数

  • 函数分为原子型(原子->原子),聚集型(数组->原子),齐次型(数组->等长数组),其它型
    • 原子型函数可以自动分布到数组上去,如2 xexp 2 3 4=4 8 16f
atomic not neg null string floor signum exp log sqrt abs infix + - * %(dividedby) < > &(and) |(or) ^(fill) $(cast) mod mixed in within like @(at) ?(find) bin aggregate count sum prd min max first last avg var(variance) dev(deviation) infix wavg(weighted..) wsum(weighted..) cov(covariance) cor(correlation) uniform sums prds mins maxs fills deltas ratios prev next reverse rank infix mavg rotate xprev msum mcount mdev mmax mmin xbar xrank other get distinct group where enlist flip raze rand type key value infix set each sv vs union inter except ,(cat) #(take) _(drop) !(xkey) .(dot)

kdb+数据库基础

表类型

  • 内存表:临时存在,q进程退出则丢弃
  • 磁盘表:永久存在,需要显式保存或追加
    • 文件表:无附加限制,加载时全部复制到内存,symbol型元素自动映射到系统全局符号表中以加速查询和比较
    • 目录表:采用内存文件映射方式按需由操作系统换页到内存并缓存,无加载处理,symbol型元素必须先做枚举处理,元素只能为基本类型或基本类型数组,不能为key表
      • 分列表(splayed):纵向分割
      • 分区表(partitioned):横向分割,使用MapReduce式并行查询技术
      • 分段表(segments):并行分割(多驱动器),可以实现并行IO,使用par.txt描述,可以将不同分区分布到不同段上,也可以将同一分区内不同记录分布到不同段上
size small medium large 32bit 1GB 32M rows unlimited 64bit 10GB 512M rows unlimited store file directory partitions query 10us 300us 10ms(seek) attr `s#,`u# `s#,`g# `p# tick taq

列属性

  • `s:sorted,标志列为升序,可以使用二分法加速查询
    • `s#作用在表上表明表的第一列是升序的
    • `s#作用在字典上表明定义域是升序的,并将字典改变为按分段函数对不在定义域内的元素取值,如ds:`s#1 3 5!`a`c`e,则ds 0 2 4 6=``a`c`e
    • `s#作用在表字典上表明表字典,key表和key列都是升序的
  • `u:unique,标志列无重复元素,加速查询,可以使用hash查询代替线性查询
    • 对于key表通常要在主键列上加`u属性以便随机定位某一行
  • `p:parted,标志列为分段重复,建立段首元素的hash索引表(小量额外存储),如`p#2 2 2 1 1 4 4 4 4 3 3
  • `g:grouped,为列中每个不同元素建立位置列表索引(大量额外存储),当更新时动态维护
  • 可以使用update为表中的列添加属性,如update `s#c1,`p#c2 from `t

基本操作

  • 基本语法
    • select [a] [by b] from t [where c],相当于 s)select [b,] [a] from t [where c] [group by b order by b]
    • update [a] [by b] from t [where c],相当于 s)update t set [a] [where c]
    • delete [a] [by b] from t [where c],即可以做记录删除也可以做列删除
    • `t insert t1,相当于 s)insert into t select from t1
    • `t upsert t1,t,:t1,当t为普通表时为insert,当t为key表时为对应key存在时做update,否则做insert
    • update/delete 将t替换为`t则更新t表,否则t表不变,返回新表
    • select的where子句采用,进行逐步过滤,而and无此功能,即where dated1,sym`s1不同于where (dated1) and (sym`s1)
  • q-sql对照
s)create table s(s varchar(*)primary key,name varchar(*),status int,city varchar(*))q)s:([s:`symbol$()]name:`symbol$();status:`int$();city:`symbol$())s)create table sp(s varchar(*)references s,p varchar(*)references p,qty int)q)sp:([]s:`s$();p:`p$();qty:`int$())s)insert into s values('s1','smith',20,'london')q)`s insert(`s1;`smith;20;`london)s)update s set status=status+1 where s='s1'q)update status:status+1 from`s where s=`s1s)delete from s where s='s1'q)delete from`s where s=`s1s)select * from s where s='s1'q)select from s where s=`s1s)select s,count(*)as x from sp group by s order by sq)select count i by s from sps)select s,sum(qty)as qty from sp,s,p where sp.s=s.s and sp.p=p.p and p.city=s.city group s order sq)select sum qty by s from sp where s.city=p.citys)select distinct ..q)select distinct ..s)count sum min max avgq)count sum min max avg prd first last wavg wsum ..s)+ - * / < > = <= >= <> like between-and not and orq)+ - * % < > = <= >= <> like within      not &   |  ..
  • 虚列i为行号
  • fby:where条件中的分组子查询,如select from sp where s`s1,qty>(avg;qty)fby p
  • 表算术:t:([x:`a`b]y:2 3) u:([x:`b`c]y:4 5) t+u / ([x:`a`b`c]y:2 7 5
  • 计算列名自动推断:select count i,sum qty by order.customer.nation等价于select x:count i,qty:sum qty by nation:order.customer.nation
  • 普通表和表字典的相互转化:select ...by ...的结果为key表,0!t将key表t变为普通表,2!t或 `date`sym xkey t将普通表t变为key表
  • ungroup:select a by ...如果不是做聚集操作,则a列的元素可能是简单类型数组,使用ungroup做by的逆运算还原为简单表,如ungroup select 2*price by sym from t
  • exec简化查询结果,可以直接返回原子/数组/字典
  • 列处理
    • 列改名:`a`b xcol sp
    • 列换序:`p`s xcols sp

表关联

  • 左连接(left join)
    • 使用外键(fkey)
s:([s]name;city;..)p:([p]name;city;..)sp:([]s:`s$();p:`p$();..) / foreign key definitionsselect .. from sp where s.city=p.city / supplier city equal part cityupdate .. from sp where s.city=p.city / try that in sql 
    • 使用lj(adhoc):设有表结构形如x:(..a..b..) y:([a;b]..)
s)select .. from x,y where x.a=y.a and x.b=y.bselect .. from x lj yselect ..,y[([]a;b);..] from x
    • pj(PlusJoin):lj的相同列被右方表覆盖,pj的相同列数值相加
    • 建立link列
sym:()t1:([] c1:`sym?`c`b`a; c2: 10 20 30)t2:([] c3:`sym?`a`b`a`c; c4: 1. 2. 3. 4.)update t1link:`t1!t1.c1?c3 from `t2q)meta t2c     | t f  a------| ------c3    | sc4    | ft1link| i t1q)select c3, t1link.c2 from t2c3 c2-----a  30b  20a  30c  10
  • 时间序列连接
    • asof:取快照,右侧(表)字典描述过滤条件和时间戳,结果为左侧表在过滤条件和时间戳下的最新记录
    • aj:aj[`sym`time;trade;quote]右侧表字典看成时间列上的分段函数再做lj
    • wj:aj的推广, wj[-2 1+\:trade.time;`sym`time;trade;(quote;(max;`ask);(min;`bid))]
  • 行列双union连接
    • uj:x uj y是x,y的推广,结果表的列是源表列的并集,按需填充null值

磁盘表操作

  • 磁盘表加载
    • 文件表加载
      • 使用load:load `:c:/db/EOD,表名与文件名相同
      • 使用get或value:T:get `:c:/db/EOD,表名可以与文件名不同
    • 目录表加载
      • 使用\l:\l c:/db1
  • 磁盘表保存
    • 文件表保存
      • save:save `:c:/db/EOD,表名与文件名相同
      • set:`:c:/db/EOD1 set EOD,表名可以与文件名不同
      • 使用@算符:@[`:c:/db;`EOD;:;EOD]
    • 目录表保存
      • 使用set,文件句柄以/结束:`:c:/db1/EOD/ set .Q.en[`:c:/db1] EOD,.Q.en负责将表中的symbol类型元素枚举至指定目录的sym文件
      • 使用rsave:rsave `:c:/db1/T,适用于不需要枚举的简单情形
      • 使用.算符:.[`:c:/db1;`EOD`;:;.Q.en[`:c:/db1] EOD]
    • 分区表保存
      • 循环保存各分区为目录表:
{[x](`$":c:/db2/",(string x),"/") set .Q.en [`:c:/db2] delete date from select from EOD where date=x} each exec distinct date from EOD 
  • 磁盘表追加
    • 先追加内存表,再做表存盘
    • 使用@算符或.算符:.[`:c:/db1;`EOD`;,;.Q.en[`:c:/db1] select from EOD]
  • 磁盘表更新
    • 先更新内存表,再做表存盘(对于目录表不能直接覆盖原表,否则会破坏数据库)
q)\l c:/db1q)`:c:/db1/EOD1/ set update prevclose:prev close by fsym from EODq)\l .
    • 使用@算符对单个列或列名文件.d单独更新保存,再刷新内存表
q)\l c:/db1q)@[`:c:/db1/EOD;`prevclose;:;raze value exec prev close by fsym from EOD]q)@[`:c:/db1/EOD;`.d;,;`prevclose]q)\l .

外部接口

文件系统接口

文本文件 二进制文件 字节流读写 结构化读入 字节流读写 结构化读入 读 写 追加 定长记录 变长记录 读 写 追加 定长记录 变长记录 a:read0 `:c:/eg.txt `:c:/eg.txt 0: ("So";"Long") h:hopen `:/eg.txt;(neg h)["and"];hclose h ("IFC D";4 8 10 6 4) 0: `:/c:/Fixed.txt ("ISF";enlist ",") 0: `:/q/data/eg.csv a:read1 `:c:/eg.bin `:c:/eg.bin 1: 0xabcd h:hopen `:/eg.bin;h 0x020304;hclose h ("ich";4 1 2) 1: (`:c:/fix.bin;8;10000) -
  • 文件句柄:以:+路径名,路径名使用/为目录分隔符
  • 其它文件操作:hcount `:c:/q/Life.txt返回文件长度, hdel `:c:/q/Life.txt删除文件,\r src dst 重命名文件
  • kdb+数据文件操作
    • 使用set/get读写数据文件:`:/q/qdata.dat set 101 102 103;get `:/q/qdata.dat
    • 向数据文件中追加数据:h:hopen `:c:/qdata.dat; h[42]; h 1 2 3 4;hclose h;get `:/q/qdata.dat
    • 使用.算符操作数据文件:[`:/q/qdata.dat;();:;1001 1002 1003];.[`:/q/qdata.dat;();,;42 43];get `:/q/qdata.dat
  • http socket句柄操作:`:http://www.hylt.net "GET /vb HTTP/1.1\r\nHost:www.hylt.net\r\n\r\n"

进程间通信

  • 连接kdb+server:h:hopen `:172.0.0.1:5001:user:pwd,h:hopen `:172.0.0.1:5001,h:hopen `::5001
  • 消息格式
    • 字符串消息:h "a:42";h "a"
    • 列表消息:h (f; arg1; arg2; ...),如 h ({y+x*x};2;3)
  • 调用方式
    • 同步调用(需要等待返回结果):h "select from EOD where fsym`000001.XSHE"
    • 异步调用(立刻返回无结果):(neg h) "a:b+1", (neg h) "`t insert (`y;43)"
  • 断开远程连接:hclose h
  • ipc通讯协议

API接口

  • 接口下载
    • c接口:k.h,文档
      • w32:c.def,c.dll,c.lib,c.o,q.lib
      • l32:c.o
    • java接口:c.java,文档
    • C#接口:c.cs,文档
  • C接口说明
typedef struct k0 {I r;                   // The object's reference count H t, u;                // The object's type and attribute flagsunion {                // The data payload is contained within this union.// The scalars are held in the following members:G g;H h;I i;J j;E e;F f;S s;// The following members are used for more complex data.struct k0*k;struct {I n;G G0[1];};};}*K;
    • 外部进程连接服务器
int c = khpu("localhost", 1234,"myusername:mypassword");
    • 内部dll供kdb+服务器加载:定义一个入参和返回值都是k对象的c函数
K2(ema){int i,n=y->n;double a=x->f,b=1.0-a,t;K r=ktn(KF,n);if((0==n)||!(KF==y->t))R r;kF(r)[0]=t=kF(y)[0];for(i=1;i
    • 与服务器进行消息交互(内部dll的连接句柄c0),函数k的第一个参数是连接句柄,后面是变长消息列表,以(K)0为消息结束符.
k(-c,"a:2+2",(K)0);             // Asynchronously set a to be 4 on the server.r = k(c,"b:til 1000000",(K)0);  // Synchronously set b to be a list up to 1000000.r = k(c,(K)0); // read incoming asynch
    • q数据转为c数据
Q类型 原子数据 数组数据 boolean x->g kG(x)[i] byte x->g kG(x)[i] char x->g kC(x)[i] short x->h kH(x)[i] int x->i kI(x)[i] long x->j kJ(x)[i] real x->e kE(x)[i] float x->f kF(x)[i] symbol x->s kS(x)[i] 混合数组 - kK(x)[i] 字典 - kK(x)[0]与kK(x)[1]分别为key和value 表(flip) - kK(x->k)[0]与kK(x->k)[1]分别为列名向量和列值二维数组
    • c数据转为q数据
Q类型 原子数据 数组数据 boolean kb(I) kG(x)[i]=C byte kg(I) kG(x)[i]=C char kc(I) kp(string),kpn(string, n) short kh(I) kH(x)[i]=H int ki(I) kI(x)[i]=I long kj(J) kJ(x)[i]=J real ke(F) kE(x)[i]=E float kf(F) kF(x)[i]=F symbol ks(S) kS(x)[i]= ss("some") timestamp ktj(-KP,J) - time kt(I) - date kd(I) - timespan ktj(-KN,J) - datetime kz(F) - 混合数组 ka(I) kK(x)[i]= 字典 - xD(K,K) 表(flip) - xT(KD),ktd(K) 列表操作 函数 Create a simple list K ktn(type,length); Create a mixed list K knk(n,x,y,z); Join an atom to a list K ja(K*,V*); Join a string to a list K js(K*,S); Join another K object to a list K jk(K*,K);
    • 回调c函数(只适用于进程内扩展dll)
      • sd1(d,f);将socket d加入kdb+的主循环select中,当socket可读/写时回调c函数K f(I d){..}
      • sd0(d);去掉对d的监听

查询示例

示例数据库EOD(股票日收盘数据1999.11.10-2010.08.27):下载压缩包EOD.7z(下载解压软件),假设下载解压为c:\db\EOD(或参考下面从通达信数据导入)

q)load `:c:/db/EOD`EODq)EODfsym        date       open  high  low   close volume  amount--------------------------------------------------------------------600000.XSHG 1999.11.10 29.5  29.8  27    27.75 1740850 4.859102e+009600000.XSHG 1999.11.11 27.58 28.38 27.53 27.71 294034  8.21582e+008600000.XSHG 1999.11.12 27.86 28.3  27.77 28.05 150079  4.21591e+008600000.XSHG 1999.11.15 28.2  28.25 27.7  27.75 119210  3.32952e+008600000.XSHG 1999.11.16 27.88 27.97 26.48 26.55 232231  6.28908e+008600000.XSHG 1999.11.17 26.5  27.18 26.37 27.18 100525  2.68995e+008q)meta EODc     | t f a------| -----fsym  | sdate  | dopen  | ehigh  | elow   | eclose | evolume| eamount| eq)count EOD3889448q)count -8!EOD155578035q).Q.w[]used| 134326544heap| 469762048peak| 469762048wmax| 0mmap| 0syms| 3200symw| 118803

在线下载除权数据

httpget:{[host;location] r:(`$":http://",host)"GET ",location," HTTP/1.1\r\nHost:",host,"\r\n\r\n";i:first r ss "\r\n\r\n";(i+4) _ r};ADJ:{[x]y:("i** ";4 2 6 8) 1: x;z:("ieeee";4 4 4 4 4) 1: x;e:fills {?[-1=x 0;?["SH"~/:x 1;`XSHG;`XSHE];`]} y;s:fills {?[-1=x 0;`$x 2;`]} y;k:where -1<>y 0;`date`fsym xasc delete from (flip `date`fsym`song`pei`peiprice`pai!(`date$`datetime$-10957+z[0;k]%86400;(s k){[x;y]`$(string x),".",string y}' (e k)),z[1 2 3 4;k])where date>.z.D} 8_httpget["www.000562.com";"/fxjdata/SPLIT.PWR"]q)ADJdate       fsym        song pei peiprice pai----------------------------------------------1990.03.01 000001.XSHE 0    0.1 3.56     01991.02.26 600653.XSHG 9    0   0        01991.03.11 600601.XSHG 4    0   0        01991.06.08 000002.XSHE 0    0.5 4.4      01991.06.28 000004.XSHE 0.15 0   0        01991.08.17 000001.XSHE 1    0   0        0q)meta ADJc       | t f a--------| -----date    | d   sfsym    | ssong    | epei     | epeiprice| epai     | e

由除权数据生成除权因子

q)ADJX:{[]d:update b:k*(pei*peiprice)-pai from update k:1%(1+song+pei) from select from ADJ;d:`date xdesc select fsym,date,adj:1^k+b%price from d lj update `p#fsym from 2!ungroup select date,price:prev close by fsym from EOD;d,:(exec distinct fsym from d),\:(0Nd;1.0);d:ungroup select date,adj:(1f,-1_prds adj) by fsym from d;update`s#date,`g#fsym from `date xasc d}[];q)ADJXfsym        date adj---------------------------000001.XSHE      0.01679383000002.XSHE      0.0108764000004.XSHE      0.2307701

对原始行情数据进行历史除权处理

q)EODX:`fsym`date xasc select fsym,date,open:`real$open*adj,high:`real$high*adj,low:`real$low*adj,close:`real$close*adj,volume:`real$volume%adj,amount from update adj:1^adj from aj[`fsym`date;EOD;ADJX]q)EODXfsym        date       open      high      low       close     volume  amount------------------------------------------------------------------------------000001.XSHE 1991.12.23 0.9303785 0.937096  0.9270197 0.9337372 3781150 3530600000001.XSHE 1991.12.24 0.937096  0.9841187 0.9068671 0.9757218 3126147 3050250000001.XSHE 1991.12.25 0.9790806 1.00763   0.9774012 0.9841187 6755456 6648170

由日数据生成月数据和周数据

EOWX:update `s#fsym from 0!select first open,max high,min low,last close,`real$sum volume,`real$sum amount by fsym,`week$date from EODXEOMX:update `s#fsym from 0!select first open,max high,min low,last close,`real$sum volume,`real$sum amount by fsym,`month$date from EODXEOQX:update `s#fsym from 0!select first open,max high,min low,last close,`real$sum volume,`real$sum amount by fsym,3 xbar date from EOMXEOYX:update `s#fsym from 0!select first open,max high,min low,last close,`real$sum volume,`real$sum amount by fsym,`year$date from EOQX

过滤指数数据

isstk:{[x]y:string x;(y like "6*G")|y like "0*E"};EOD:select from EODX where isstk fsymEOW:select from EOWX where isstk fsymEOM:select from EOMX where isstk fsymEOQ:select from EOQX where isstk fsymEOY:select from EOYX where isstk fsym

使用技术分析策略进行历史回测

  • 以天才机械操盘术(朱淋靖)一书中部分策略为例
irlast:{neg (last where x)-count x};crossup:{[x;y](y>x)&(prev y)<=prev x}; /y上穿x//sma:`:talib 2:(`sma;2);ema:`:talib 2:(`ema;2);sma:mavg;ema:{[x;y]z:1-x;(({[x;y;z;w](w*x)+z*y}[;;x;z])\) y};rsi:{100*{sma[x;y]%sma[x;abs y]}[x;y-prev y]};TARULE:()!();TAPARA:()!();APPLYTA:{TARULE[x][TAPARA[x];]};//Chap 2TARULE[`101]:{o:y`o;h:y`h;l:y`l;c:y`c;((x 0)>l%c&o)&((x 1)>h%c)&(c<(x 2)*(x 3) mmax c)};TAPARA[`101]:(0.98;1.01;0.7;30);    /1.锤头TARULE[`102]:{o:y`o;l:y`l;c:y`c;((x 0)=(x 0) msum (c>=o)&(x 1)>=c%o)&(((x 2) mmin l)=(x 3) mmin l)&(((x 4) mavg c)>(x 5)*(x 6) mavg c)};TAPARA[`102]:(5;1.03;10;100;3;1.01;5); /2.秋影金波TARULE[`103]:{o:y`o;c:y`c;((x 0)>prev c%o)&(oprev c)&(c<(x 1)*(x 2) mmax c)};TAPARA[`103]:(0.97;0.7;30); /3.好友反攻TARULE[`104]:{o:y`o;l:y`l;c:y`c;1=(x 0) msum ((x 1)<=(x 0) msum (c>o)&(o0.5*prev o+c)&((x 2)>prev c%o))&(((x 3) mmin l)=(x 4) mmin l)};TAPARA[`104]:(10;2;0.97;10;100); /4.卷土重来TARULE[`105]:{o:y`o;h:y`h;l:y`l;c:y`c;m:x 7;{(x&1<=z msum y)|y&1<=z msum x}[;;x 0] [((x 1)>(x 2) xprev c%o)&((prev o)<(x 2) xprev c)&((x 3)(x 2) xprev c)&((x 4)>abs prev -1+o%c);crossup[x 5;] (x 6) mavg 100*((m mmin l)-c)%((m mmax h)-m mmin l)]};TAPARA[`105]:(10;0.97;2;1.03;0.02;-5;5); /5.早晨之星TARULE[`106]:{o:y`o;l:y`l;c:y`c;(((x 0) mmin l)=(x 1) mmin l)&({xc%o)};TAPARA[`106]:(10;100;5;10;1.05;5;0.95); /6.炉架底TARULE[`107]:{o:y`o;l:y`l;c:y`c;((prev c)<(x 0)*(x 1) mmax c)&(l=o)&((x 2)//Chap 3TARULE[`ZERO]:{l:y`l;c:y`c;m:x 0;n:x 1;(l=m mmin l)&(0mh-a*mh-ml)&(lprev h};TAPARA[`WAVE3]:(); /三浪启动过滤TARULE[`WAVE4]:{h:y`h;l:y`l;c:y`c;m:x 0;a:x 1;b:x 2;mh:m mmax h;ml:m mmin l;(l>mh-a*mh-ml)&(lr*nl)&(lmh-b*(mh-nl))};TAPARA[`WAVEB]:(30;100;1.3;0.618;1.236); /B浪底过滤//Chap 4TARULE[`AO]:{h:y`h;l:y`l;{(y mavg x)-z mavg x}[;x 0;x 1] 0.5*h+l};TAPARA[`AO]:(5 34); /AO动量TARULE[`AC]:{ao:TARULE[`AO][2#x;y];(x 3) mavg (ao- (x 2) mavg ao)};TAPARA[`AC]:(5 34 5 5); /AC动量加速//chap 5TARULE[`Oh]:{o:y`o;c:y`c;(c<(x 0)*(x 1) mavg c)&(o<(x 2)*prev c)&c>prev c};TAPARA[`Oh]:(0.96;5;0.99); /5.2 哎呀跳空TARULE[`123]:{m:x 0;n:x 1;a:x 2;c:y`c;c0:m mmin c;c1:n xprev c0;(c>c1)&(c0a*c1};TAPARA[`123]:(100;10;0.95); /5.3 123法则TARULE[`TD]:{m:x 0;n:x 1;u:x 2;h:y`h;l:y`l;c:y`c;fz:(0|h-prev c)+c-l;fm:(0|(prev c)-l)+h-l;td:100*(8 msum fz)%(8 msum fm+fz);u=u msum td100*-1+c%28 mavg c};TAPARA[`REV]:(28;-10) /5.6 摆荡交易系统TARULE[`YSZD]:{c:y`c;{[x]y:prev x;(x>y)&y=100 mmin y} {x-y mavg x}[;x 3] (x 2) mavg (x 1) mavg rsi[x 0;c]};TAPARA[`YSZD]:(14;5;3;9); /5.7 衍生振荡指标//Chap 9.5TARULE[`902]:{h:y`h;l:y`l;c:y`c;((x 0)<((x 1) mmax c)%c)&((x 2)100*c%(x 3) mavg c)|((x 4)>100*c%(x 5) mavg c)|((x 6)>100*c%(x 7) mavg c)};TAPARA[`908]:(5;1.051;72;60;78;40;80;20);  /公式8(82%,13%)TARULE[`913]:{h:y`h;l:y`l;c:y`c;(1<=(x 0) msum (x 1)>c %(x 2) mavg c)&((x 3)c%(x 5) mavg c)};TAPARA[`913]:(3;0.67;48;1.06;0.8;8);  /公式13(97%,85%)//Chap 10/10.1 对称重演判强弱TARULE[`28]:{c:y`c;s0:(x 0)mdev c;s1:(x 1)mdev c;s2:(x 2)mdev c;s3:(x 3)mdev c;crossup[s0;s1]&(s1>s2)&(s2>s3)}; TAPARA[`28]:(5 10 20 30); /10.2 二八法则选择异动股票/10.3 魔鬼定律/10.4 墨菲法则TARULE[`REVTHINK]:{m:x 0;c:y`c;m=m msum cprev (x 0) mmax h};TAPARA[`OCARM]:(enlist 90);            /10.7 奥卡姆剃刀交易系统/10.8 彼得原理:上/下分形判超买/卖TARULE[`AOMARK]:{h:y`h;l:y`l;{(y mavg x)-z mavg x}[;x 0;x 1] 0.5*h+l};TAPARA[`AOMARK]:(5 34 0); /10.9 大盘监测:AO动量
q)show d:{select fsym,date,close,future from x where sig} ungroup select date,sig:APPLYTA[`913] `o`h`l`c!(open;high;low;close),close,future:-20 xprev close by fsym from EODXfsym        date       close     future------------------------------------------000001.XSHG 1992.10.27 450.28    440.04000004.XSHE 1991.06.29 1.366736  1.114619000004.XSHE 1991.07.02 1.300389  1.088081000004.XSHE 1996.12.23 4.729922  4.817513q)count d920q)select count i by signum future-close from dfuture| x------| ----1    | 2510     | 11     | 668

接口示例

通达信日线数据导入

设kdb+数据文件表保存在c:/db/EOD,通达信行情软件的根目录在 c:/jcb_lh_yf,则运行以下代码读取通达信日线数据并追加到kdb+文件表

tdxeod:{[x]`date`fsym xasc raze `XSHG`XSHE{raze{[x;y]s:-6#-4_ string x;fs:`$s,".",string y;z:$[any ("I"$s) within/:(30000 39999;580000 589999;150000 159999;160000 169999;180000 189999;500000 509999;510000 519999);1e-3;1e-2];`date`fsym xcols update fsym:fs from flip `date`open`high`low`close`volume`amount!{[x;y]("D"$string x 0;`real$y*x 1;`real$y*x 2;`real$y*x 3;`real$y*x 4;`real$x 6;x 5)}[;z] ("iiiiiei ";4 4 4 4 4 4 4 4) 1: x}[;x] each (` sv) each y,/:key y}' (` sv) each x,/:(`Vipdoc`sh`lday;`Vipdoc`sz`lday)};appeod:{[x;y]x upsert {[x;y]delete from x where date<=@[{exec last date from x};y;0Nd]}[;x] y;};EOD:tdxeod[`:c:/jcb_lh_yf];appeod[`:c:/db/EOD;EOD];

dbf文件导入

q)dbfread:{[x]h:()!();h[`ver`nrec`hlen`rlen`ftag]:first each("x ihh b";1 3 4 2 2 2 1) 1: (x;0;15);if[h[`ftag];:()];f:("sc xx ";11 1 4 1 1 14) 1: (x;32;h[`hlen]-33);flip (f 0)!("S"^("CN"!"SF")f 1) {x$y}' (" ",(count f 1)#"*";1,`int$f 2) 1: (x;h[`hlen];h[`nrec]*h[`rlen])}; /[dbfhandle],f:fields def[字段名;类型(BCDGN);字段长度;字段精度]q)t:dbfread `:s:/show2003.dbf

odbc接口

kdb+访问odbc源

  • 安装odbc选件(见上)
  • 在odbc管理器中创建odbc源
  • 代码示例
\l odbc.kdsn:`sql123`sa`pawword;h:.odbc.open dsn;e:.odbc.eval h;e "use db";r:e "select * from dbo..test"; 

kdb+作为odbc源

  • 安装kdb+32位odbc驱动程序
  • 在odbc管理器中创建kdb+源(在win64系统中打开32位odbc管理器需使用%SystemRoot%\sysWOW64\odbcad32.exe)

gnuplot接口

tmpdir:{$[`l32=.z.o;"/tmp/";"/tmp/"]};rn:{[]n:string first 1?`8;tmpdir[],n};                                  /生成随机文件名(带路径,不带后缀)gplot:{[x;y;z](`$":",y,".cmd") 0: $[z;("set terminal png transparent nocrop enhanced font arial 8 size 840,640";"set output '",y,".png'");()],("set autoscale";"set grid"),x,enlist enlist "q";system $[.z.o in `l32`l64;"gnuplot ";"start \\bin\\gnuplot "],$[z;"";"-persist "],y,".cmd";$[z;y,".png";()]}; /[plot命令行;临时文件名;是否] 执行gnuplot绘图pd:{[x;y;e;f]z:rn[];(`$":",z,".dat") 0: $[0=type x;$[0=type x 0;({x,("";""),y}/) {{" " sv x} each string flip x} each x;{" " sv x} each string flip x];string x];gp:$[0=type y 0;{(til count x),'(0^prev sums x),'x} count each y;enlist 0,0,count x];if[not 0=type y 0;y:enlist y];gplot[e,{[x;y;z;w]u:z,".dat";x:x[(w 1)+til w 2];y:y w 0;"plot ", $[(0=type x 0); "," sv {[x;y;z;w]x+:w 1;"'",y,"' i ",(string x)," ",(z x&-1+count z)}[;u;$[0=type y;y;enlist y];w] each til count x;"'",u,"' ",y]}[x;y;z;] each gp;z;f]}; /[数据描述;格式描述;前缀语句;文件输出标志]调用gnuplot制图,gp:根据style分组pb:pd[;"with boxes";enlist "set key off";0b];pc:pd[;"with p";enlist "set key off";0b];pl:pd[;"w lp ps 0.4 pt 6";enlist "set key off";0b]; /[数据描述] pb:画饼图;pc:画点图;pl:画线图.[x]:1.y;2.(x;y).3.((x1;y1);(x2;y2);...)pbf:pd[;"with boxes";enlist "set key off";1b];pcf:pd[;"with p";enlist "set key off";1b];plf:pd[;"w lp ps 0.4 pt 6";enlist "set key off";1b]; /文件输出版本pl2y:pd[;("w lp ps 0.4 pt 6 axes x1y1";"w lp ps 0.4 pt 6 axes x1y2");("set y2tics";"set key bot center outside");0b];plyn:{pl {(til count x;x)} each x;};plyn01:{pl {[x]n:count x;((til n)%(n-1);x)} each x;};

Matlab引擎接口(在kdb+内部调用Matlab引擎计算)

#include "engine.h"#include "kcomm.h"Z Engine *ep=NULL;K1(eng_Open){C buf[SHORTBUFLEN];if(NULL!=ep)R ki(-2);kstrncpy(buf,x,sizeof(buf));ep=engOpen(buf);if(NULL==ep)R ki(-1);R ki(0);}K1(eng_Close){int r=-1;if(NULL==ep)R ki(r);r=engClose(ep);ep=NULL;R ki(r);}K1(eng_Eval){int r=-1;C buf[LONGBUFLEN];if(NULL==ep)R ki(r);kstrncpy(buf,x,sizeof(buf));r=engEvalString(ep,buf);R ki(r);}K1(eng_Get){mxArray *pm=NULL;K L,Row;size_t M,N;int i=0,j=0;double *pd=NULL;if(NULL==ep)R (K)0;pm=engGetVariable(ep,xs);if(NULL==pm)R (K)0;if(0==mxIsDouble(pm))R (K)0;M=mxGetM(pm);N=mxGetN(pm);pd=mxGetPr(pm);if(NULL==pd)R (K)0;L=knk(0);for(i=0;ifor(j=0;jint r=-1,M=0,N=0,i=0,j=0;double *pd=NULL;K Row;if(NULL==ep)R ki(r);M=y->n;Row=kK(y)[0];N=Row->n;pm=mxCreateDoubleMatrix(M,N,mxREAL);pd=mxGetPr(pm);for(i=0;ifor(j=0;j
mlopen:`:qmatlab 2:(`eng_Open;1);mlclose:`:qmatlab 2:(`eng_Close;1); mleval:`:qmatlab 2:(`eng_Eval;1);mlget:`:qmatlab 2:(`eng_Get;1);mlput:`:qmatlab 2:(`eng_Put;2); 

tcp/udp网络接口

int closesock(int s){int r=0;#if defined(WIN32)||defined(WIN64)r=closesocket(s);#elser=close(s);#endifR r;}K1(udpsend){int n=0;struct sockaddr_in si_other;int s, i, slen=sizeof(si_other);char buf[BUFLEN];if ((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1)R ki(-2);memset((char *) &si_other, 0, slen);si_other.sin_family = AF_INET;si_other.sin_port = htons(kK(x)[1]->h);kstrncpy((char *)&buf,kK(x)[0],BUFLEN);#if defined(WIN32)||defined(WIN64)if(-1==(si_other.sin_addr.s_addr = inet_addr(buf)))R ki(-3);#elseif(inet_aton(buf, &si_other.sin_addr)==0) R ki(-3);#endifn=sendto(s,kC(xz), xz->n, 0, (struct sockaddr*)&si_other, slen);closesock(s);R ki(n);}K1 (getsockbuf){int s=x->i,r1=0,r2=0,n1=0,n2=0,s1=sizeof(n1),s2=sizeof(n2);printf("s=%d\n",s);r1=getsockopt(s,SOL_SOCKET,SO_RCVBUF,(void*)&n1,(int *)&s1);r2=getsockopt(s,SOL_SOCKET,SO_SNDBUF,(void*)&n2,(int *)&s2);return knk(7,ki(n1),ki(n2),ki(s1),ki(s2),ki(r1),ki(r2),ki(ERRNO));}K1 (setsockbuf){int s=0,n=16777216,r1=0,r2=0;printf("n=%d,t=%d\n",x->n,x->t);if(0>x->t){s=x->i;}else{s=kI(x)[0];n=kI(x)[1];}printf("s=%d,n=%d\n",s,n);r1=setsockopt(s,SOL_SOCKET,SO_RCVBUF,(const char*)&n,sizeof(int));r2=setsockopt(s,SOL_SOCKET,SO_SNDBUF,(const char*)&n,sizeof(int));return knk(3,ki(r1),ki(r2),ki(ERRNO));}K sockcallback(I s){struct timeval tv={0,0};fd_set RS,WS,ES;struct sockaddr_in sin;int r=0,slen=sizeof(sin);char buf[BUFF128K];char addr[SYMSIZE];memset(buf,0,sizeof(buf));memset(addr,0,sizeof(addr));FD_ZERO(&RS);FD_SET(s,&RS);FD_ZERO(&WS);FD_SET(s,&WS);r=select(s+1,&RS,&WS,NULL,&tv);if(r==0){R ki(0);}if(r<0){r=-ERRNO;r0(k(0,"sockcberr",ki(s),ki(r),0));R ki(r);}if(FD_ISSET(s,&WS)){r0(k(0,"sockcbsend",ki(s),0));}if(FD_ISSET(s,&RS)){#if defined(WIN32)||defined(WIN64)r=recvfrom(s, buf, sizeof(buf),0, (struct sockaddr *)&sin, &slen);#elser=recvfrom(s, buf, sizeof(buf), MSG_DONTWAIT, (struct sockaddr *)&sin, &slen);#endifstrncpy(addr,inet_ntoa(sin.sin_addr),sizeof(addr));if(r<0)r=-ERRNO;r0(k(0,"sockcbrecv",ki(s),kp(addr),ki(ntohs(sin.sin_port)),ki(r),((r>0)?kpn(buf,r):kp("")),0));if(0==r) {sd0(s);closesock(s);}}R ki(r);}K listencallback(I s){struct sockaddr_in sin;int r,slen=sizeof(sin);char buf[BUFLEN];r=accept(s,(struct sockaddr *)&sin, &slen);if(0sizeof(buf));r0(k(0,"listencb",ki(s),ki(r),kp(buf),ki(ntohs(sin.sin_port)),0));sd1(-r,sockcallback);}R ki(r);}K1(sockcheck){int s=x->i;R sockcallback(s);}K2(tcpsend){int s=x->i,r=0,n=y->n,e=0;r=send(s,kC(y),n,0);if(r>0){R ki(r);}else{e=ERRNO;//sprintf(buf,"r=%d,errno=%d",r,e);perror(buf);R ki(-e);}}K1(tcprecv){char buf[BUFLEN];int s=x->i,r=0,e=0;if(s<=0) R ki(-1);r=recv(s,buf,sizeof(buf),0);if(r>0){R kpn(buf,r);}else if(r=0){closesock(s);R ki(0);}else{e=ERRNO;//sprintf(buf,"r=%d,errno=%d",r,e);perror(buf);R ki(-e);}}I opensock(S ip,I port,I mode,I blen){int n=0,e=0,flag=1;struct sockaddr_in si_other;int s, flags, slen=sizeof(si_other),r;int sockmode=mode; /*0:UDP,1:TCP client async,2:TCP server async,3:TCP client sync,4:TCP server sync*/#if defined(WIN32)||defined(WIN64)u_long iMode = 1;#endifif ((s=socket(AF_INET,((0==sockmode)?SOCK_DGRAM:SOCK_STREAM),(0==sockmode)?IPPROTO_UDP:IPPROTO_TCP))==-1) R -ERRNO;setsockopt(s,IPPROTO_TCP,TCP_NODELAY,(char*)&flag,sizeof(flag));#if defined(WIN32)||defined(WIN64)if(0/*Linux 2.6 autotuning!*/setsockopt(s,SOL_SOCKET,SO_RCVBUF,(char*)&blen,sizeof(blen));setsockopt(s,SOL_SOCKET,SO_SNDBUF,(char*)&blen,sizeof(blen));}if(mode<3) ioctlsocket(s, FIONBIO, &iMode);#elseflags = fcntl(s, F_GETFL);if(mode<3)flags |= O_NONBLOCK;fcntl(s, F_SETFL, flags);#endifmemset((char *) &si_other, 0, slen);si_other.sin_family = AF_INET;si_other.sin_port = htons(port);if(0==strcmp(ip,"")){si_other.sin_addr.s_addr=htonl(INADDR_ANY);}else{#if defined(WIN32)||defined(WIN64)if(-1==(si_other.sin_addr.s_addr = inet_addr(ip)))R (-ERRNO);#elseif(inet_aton(ip, &si_other.sin_addr)==0) R (-ERRNO);#endif}if((1==sockmode)||(3==sockmode)){r=connect(s,(struct sockaddr *)&si_other,slen);#if defined(WIN32)||defined(WIN64)if ((0>r)&&WSAEWOULDBLOCK!=(e=ERRNO)) R (-e);#elseif ((0>r)&&EINPROGRESS!=ERRNO) R (-ERRNO);#endif}else{if(0>setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&flag,sizeof(flag)))R (-ERRNO);if(0>bind(s, (struct sockaddr *)&si_other, slen)) R (-ERRNO);if(0if(0>listen(s,100))R (-ERRNO);}}R s;}K1(sockopen){int s=0,t=xz->i,n=16777216;if(!((-KS)==xx->t)&&((-KI)==xy->t)&&((-KI)==xz->t))R ki(-1234);if(4==x->n){n=xw->i;};s=opensock(xx->s,xy->i,xz->i,n);if(0if(2==t){sd1(-s,listencallback);}else if(2>t){sd1(-s,sockcallback);}}R ki(s);}K1(sockclose){int s=x->i;sd0(s);R ki(closesock(s));}
udpsend:`oslib 2:(`udpsend;1);sockopen:`oslib 2:(`sockopen;1);sockclose:`oslib 2:(`sockclose;1);sockcheck:`oslib 2:(`sockcheck;1);tcpsend:`oslib 2:(`tcpsend;2);tcprecv:`oslib 2:(`tcprecv;1);getsockbuf:`oslib 2:(`getsockbuf;1);setsockbuf:`oslib 2:(`setsockbuf;1);udplisten:{[x]sockopen[x,enlist 0]};tcpconnasync:{[x]sockopen[x,enlist 1]};tcplistenasync:{[x]sockopen[x,enlist 2]};tcpconn:{[x]sockopen[x,enlist 3]};tcplisten:{[x]sockopen[x,enlist 4]};

K4参考

算符 Q一元功能 Q二元功能 + flip + - neg - * first * % reciprocal/ltime % # count # ~ not/hdel ~ _ floor _ ! key/inv !/lsq @ type @ . value . rand/distinct < iasc/hopen < > idesc/hclose > : force monad(-:) : & where & , enlist , ^ null ^ $ string $/mmu | reverse | = group = 0: read0 0: 1: read1 1: 2: asof /: /:,sv \: \:,vs 内部函数 功能 -1! hsym -2! attr -3! .Q.s1 -4! lexical -5! parse -6! eval -7! hcount -8! data>ipc bytes -9! ipc bytes>data -10! 检查整数对应enum类型是否存在 -11! replay log:-11!(-1;x),-11!(-2;x),-11!(n;x) -12! .Q.host -13! .Q.addr -14! " escape -15! md5 -16! 引用计数 -17! flip endian -18! ipc压缩 -19! 文件压缩 -20! .Q.gc -21! 文件压缩统计
基于开源软件的金融计算 最近更新 交易技术 金融市场 Kdb+ GIT仓库 RSS汇集 使用帮助
本页是只读的 参阅其他版本 管理
最后编辑于 2010-11-01 14:47 由 itfin (比较差异)