如何将非向量化Kdb+ symbol函数适配到表update操作?
问题描述
我编写的测试代码可以正常生成IBM250109C24000格式的期权代码:
expryDt:{[ed] (2_string ed) except "."}; // 生成格式化的期权代码 symbol:{[tkr;expiryDate;typ;strike] if[not typ in `CALL`PUT`CE`PE; show "typ参数错误,必须是CALL/PUT/CE/PE中的一种"; exit 1]; r: $[(typ=`CALL) or (typ=`CE); string `C; string `P]; "" sv (string tkr; expryDt[expiryDate]; r; string strike) }; // 单例测试 tkr:`IBM; expiryDate:2025.01.09; typ:`CALL; strike:24000i; show symbol[tkr;expiryDate;typ;strike]; // 输出 "IBM250109C24000" 正常
但将这个非向量化的symbol函数应用到表的update操作时失败:
t:([] ticker:`IBM`IBM`IBM; expiryDate:2025.01.09 2025.01.09 2025.01.09; typ:`CALL`PUT`CE; strike:24000 24000 24000; secType:`OPT`OPT`OPT); show t; t:update symbol:symbol[ticker;expiryDate;typ;strike] from t where secType=`OPT; // 报错
报错信息:
"IBM250109C24000" ticker expiryDate typ strike secType ------------------------------------- IBM 2025.01.09 CALL 24000 OPT IBM 2025.01.09 PUT 24000 OPT IBM 2025.01.09 CE 24000 OPT 'type [3] tv_options.q:5: symbol:{[tkr;expiryDate;typ;strike] if[not typ in `CALL`PUT`CE`PE; show "typ参数错误,必须是CALL/PUT/CE/PE中的一种"; exit 1]; ^ r: $[(typ=`CALL) or (typ=`CE); string `C; string `P];
请问如何修改symbol函数使其支持向量化,从而在表的update操作中正常运行?
解决方案
问题出在原函数的if判断和$条件分支都是标量逻辑,无法处理列表输入。要改成向量化版本,需要做以下调整:
- 将标量的
if检查改为向量化的合法性校验; - 替换标量条件分支
$为向量化的?运算符; - 使用映射版本的字符串拼接函数处理列表输入。
修改后的代码:
expryDt:{[ed] (2_string ed) except "."}; // 向量化版本的期权代码生成函数 symbol:{[tkr;expiryDate;typ;strike] // 向量化校验typ参数合法性 badTyp:where not typ in `CALL`PUT`CE`PE; if[0<count badTyp; show "typ参数错误,位置", string badTyp, "的值非法,必须是CALL/PUT/CE/PE中的一种"; exit 1]; // 用向量化条件选择生成C/P标记 r: ?[(typ=`CALL)|(typ=`CE); string `C; string `P]; // 逐行拼接字符串 "" sv' (string tkr; expryDt[expiryDate]; r; string strike) };
关键修改点说明
- 合法性校验:用
where not typ in ...定位所有非法输入的位置,再判断是否存在非法值,适配列表输入场景; - 条件分支:替换标量条件运算符
$为向量化的?,对列表中每个元素单独判断,返回对应结果; - 字符串拼接:使用
sv'(sv的映射版本),逐行处理每组输入元素完成拼接,而非将整个列表作为单一输入。
测试验证
用原表测试:
t:([] ticker:`IBM`IBM`IBM; expiryDate:2025.01.09 2025.01.09 2025.01.09; typ:`CALL`PUT`CE; strike:24000 24000 24000; secType:`OPT`OPT`OPT); t:update symbol:symbol[ticker;expiryDate;typ;strike] from t where secType=`OPT; show t;
输出结果:
ticker expiryDate typ strike secType symbol --------------------------------------------------- IBM 2025.01.09 CALL 24000 OPT IBM250109C24000 IBM 2025.01.09 PUT 24000 OPT IBM250109P24000 IBM 2025.01.09 CE 24000 OPT IBM250109C24000
内容的提问来源于stack exchange,提问作者marital_weeping
相关产品推荐
相关产品推荐

