我有一个代码表,其中包含日期,开始时间,结束时间,我需要从服务器上的nbbo表中提取nbbo。例如
Date starttime endtime sym
2014.05.01 15:10:38.000 15:10:58.000 KT
2014.05.01 15:15:53.000 15:16:23.000 IBM
2014.05.01 15:37:39.000 15:37:59.000 AAPL
理想情况下,我将打开服务器的句柄并通过传入此函数来拉取每行的数据:getnnbo并将其称为:getnnbo[
KT; 2014.05.01; 15:10:38.000; 15:10:58.000]`其中函数定义为
getnbbo:{[sym;dt;starttime;endtime]:h1"select 0.5*(first bid + first ask) from nbbo where date=",string[dt],",sym =`",string[sym], ",linetime within (",string[starttime],",",string[endtime],")"}
当我将其称为getnnbo[
KT时,此功能有效; 2014.05.01; 15:10:38.000; 15:10:58.000]`但我不知道如何对表中的每一行进行操作,因为我必须使用服务器的句柄。
答案 0 :(得分:1)
以下内容适用于您,假设lst
是包含`date`starttime`endtime`sym
列的查找表的名称:
getnbbo ./: flip lst[`sym`date`starttime`endtime]
在上面我们做了以下几点:
lst[`sym`date`starttime`endtime]
- 以正确的顺序提取列值,因此它们与函数args flip lst[...]
- 将列值转换为函数关于您已粘贴的代码的其他一般要点 -
从您的select语句中取以下内容:
0.5*(first bid + first ask)
这实际上是在做你需要的,但偶然。它实际上没有正确确定范围。 Kdb +将从右到左评估这个。所以在上面的表格中它将
bid
列添加到其中这是在这种情况下计算你想要的值,但可能会在不同的场景中绊倒你。
写这个的正确方法是:
0.5 * first[bid] + first[ask]
这将确保评估顺序
ask
bid
或者,如果您赞成括号,您可以按如下方式编写:
0.5 * (first bid)+(first ask)
getnbbo
函数以字符串形式生成查询 - 这对于简单的情况很好,但通常不是很好的做法。通常更好的做法是(1)一个接受参数的函数或(2)切换到一个函数选择语句 - (2)需要更深入地理解Kdb +,我不会在这里进入。< / p>
立即改进是使其成为一个参与争论的函数。所以getnbbo
会成为:
getnbbo:{[handle;sym;dt;starttime;endtime]
getDataFunc:{[s;dt;st;et]
select 0.5*first[bid]+first[ask] from nbbo where date=dt, sym=s, linetime within (st;et)
};
handle(getDataFunc;sym;dt;starttime;endtime)
};
在上面,
getnbbo
func采用与以前相同的args,但我们也传入句柄(不是必需的,但是很好的做法)getnbbo
中,我们定义一个新的参数化函数getDataFunc
,给定参数(args)返回带有适当子句的select语句的结果getDataFunc
发送到远程句柄
进一步阅读:
handle(func;arg1;..;argN)
答案 1 :(得分:0)
我建议不要对服务器上的每一行提出请求,而是立即发送全表(或者如果它很大的话,发送一部分)并从服务器的一个请求中获取数据。这应该会加快进程,因为请求较少,服务器也会花费更少的时间来生成结果,因为通常在列表上进行计算比单个行更快。
所以你的功能应该是下面的东西(只是一个例子)。您可以根据需要对其进行优化/修改。我假设您的股票代码表每个(日期; sym)组合只有一个条目,以便它可以作为主键。
getData:{[tbl] select 0.5*first[bid]+first[ask] from (nbbo ij `date`sym xkey tbl) where linetime within (st;et) }
然后使用服务器句柄在服务器上运行它。 'tbl'是带有代码的输入表。
handle(getData;tbl)
编辑ma3266评论后:
我假设有两个条件:
a)nbbo表在服务器上分区
b)您的输入tbl具有与nbbo相同的日期和符号列名称。否则,您可以使用'xcol'重命名它们。
getData:{tbl:0!tbl; tempNbbo:0!select from nbbo where date in tbl`date,sym in tbl`sym ; select 0.5*first[bid]+first[ask] from (tempNbbo ij `date`sym xkey tbl) where linetime within (starttime;endtime)}
但如果您的输入表包含许多日期的数据,则可能导致大量内存使用。在这种情况下,您可以使用以下函数,它将按日期中断输入表。
getData:{tbl:0!`date xasc tbl; raze { tempNbbo:0!select from nbbo where date in x`date,sym in x`sym ; select 0.5*first[bid]+first[ask] from (tempNbbo ij `date`sym xkey x) where linetime within (starttime;endtime)} each (where differ tbl`date) cut tbl}
在这两个函数中,我首先从输入表中删除主键属性。
另外,检查nbbo的列类型和输入表。这可能会给你输入错误。这个查询对我来说很好。