基于分类列计算kdb数值列比率:按日期和评级求买卖净额比率
多日期分组计算KDB表买卖比率的解决方案
需求说明
现有KDB表,需按dt(日期)和ratings(评级)分组,基于side(买卖方向)计算notional(名义金额)的buySellRatio(买卖比率,即买入总金额/卖出总金额)。
样本输入
// Sample Input - dt ratings side notional -------------------------------- 2025.04.04 AAA B 10 2025.04.04 BBB S 20 2025.04.04 AAA S 30 2025.04.04 BBB B 40 2025.04.05 AAA S 50 2025.04.05 BBB B 60 2025.04.05 BBB S 70 2025.04.05 AAA B 80 2025.04.05 AAA S 90
生成样本输入的代码
// Code to generate sample input - t:([] dt:2025.04.04 2025.04.04 2025.04.04 2025.04.04 2025.04.05 2025.04.05 2025.04.05 2025.04.05 2025.04.05; ratings: `AAA`BBB`AAA`BBB`AAA`BBB`BBB`AAA`AAA; ady spr � salice_head 第es宏/B a**试用 notional:10*1+til 9 );
预期输出
//Expected Output dt ratings buySellRatio ------------------------------- 2025.04.04 AAA 0.3333333 2025.04.04 BBB 2 2025.04.05 AAA 0.5714286 2025.04.05 BBB 0.8571429
原有尝试的问题代码
原有代码仅支持单日期计算,核心问题是透视分组时未包含dt,导致日期维度丢失:
.up.tab:select sum notional by dt, ratings, side from t; .up.ratings:asc exec distinct side from .up.tab; .up.pvt:0!exec .up.ratings#(side!notional) by ratings:ratings from .up.tab; select ratings, buySellRatio:B%S from .up.pvt
解决方案
方法1:修正透视表分组逻辑
在透视操作时同时按dt和ratings分组,保留完整的维度信息:
// 先按dt、ratings、side汇总名义金额 tab: select sum notional by dt, ratings, side from t; // 按dt和ratings分组,将side维度转为列 pvt: 0!exec (`B`S)#(side!notional) by dt, ratings from tab; // 计算买卖比率并整理输出格式 select dt, ratings, buySellRatio: B%S from pvt;
方法2:直接条件求和(更高效)
无需生成中间表,直接在分组语句中通过条件筛选计算买入、卖出总金额的比值,逻辑更简洁且执行效率更高:
select buySellRatio: sum[notional where side=`B] % sum[notional where side=`S] by dt, ratings from t;
两种方法均可得到符合预期的输出,方法2更适合处理大规模数据集。
内容的提问来源于stack exchange,提问作者Utsav
相关产品推荐
相关产品推荐

