You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在kdb/q中实现FIFO规则下的PnL计算

直接解决思路:用FIFO持仓队列跟踪计算PnL

不用生成分配矩阵,直接通过跟踪持仓队列逐笔处理交易,就能精准计算每笔开仓单的PnL,完全符合你的规则:

核心逻辑

  1. 用队列记录未平仓的开仓仓位,严格遵循FIFO顺序(先开仓的先平仓)
  2. 每笔平仓交易(反向交易)从队列头部开始匹配,计算对应开仓单的PnL,平仓单自身PnL为0
  3. 若反向交易的数量超过现有持仓,超出部分作为新的反向开仓加入队列,后续被平仓时再计算PnL

具体步骤(对应你的交易数据)

初始化:

  • 持仓队列:空
  • 每笔交易的PnL初始为0
  • 净持仓量:0

1. 处理Id=1(Buy 6 @10.0)

  • 净持仓为0,直接作为多头开仓加入队列:[(Id1, 6, 10.0, 0.0)]
  • 净持仓变为6
  • Id1的PnL暂记0,后续平仓时更新

2. 处理Id=2(Sell 5 @11.0)

  • 从队列头部取Id1的6份多头,平仓5份:
    • 计算PnL:5*(11.0-10.0)=5.0,加到Id1的PnL中(Id1现在PnL=5.0)
    • Id1剩余未平仓数量:6-5=1,更新队列元素为(Id1,1,10.0,5.0)
  • 净持仓变为6-5=1
  • Id2的PnL=0.0

3. 处理Id=3(Buy4 @10.0)

  • 净持仓为1(多头),新增多头开仓加入队列:[(Id1,1,10.0,5.0), (Id3,4,10.0,0.0)]
  • 净持仓变为1+4=5
  • Id3的PnL暂记0

4. 处理Id=4(Sell3 @12.0)

  • 先平队列头部的Id1剩余1份:
    • PnL:1*(12.0-10.0)=2.0,加到Id1的PnL中(Id1现在PnL=5+2=7.0)
    • Id1剩余数量为0,从队列移除
  • 剩余平仓量3-1=2,平队列头部的Id3的4份:
    • PnL:2*(12.0-10.0)=2.0,加到Id3的PnL中(Id3现在PnL=2.0)
    • Id3剩余数量4-2=2,更新队列元素为(Id3,2,10.0,2.0)
  • 净持仓变为5-3=2
  • Id4的PnL=0.0

5. 处理Id=5(Sell8 @9.0)

  • 先平队列头部的Id3剩余2份多头:
    • 这部分按你的规则不计入Id5的PnL,仅作为平仓现有持仓处理
    • Id3剩余数量为0,从队列移除
  • 剩余卖出量8-2=6,作为空头开仓加入队列:[(Id5,6,9.0,0.0)]
  • 净持仓变为2-8=-6(空头)
  • Id5的PnL暂记0,后续平仓时更新

6. 处理Id=6(Buy7 @8.0)

  • 从队列头部取Id5的6份空头,平仓6份:
    • 计算PnL:6*(9.0-8.0)=6.0,加到Id5的PnL中(Id5现在PnL=6.0)
    • Id5剩余数量为0,从队列移除
  • 剩余买入量7-6=1,作为多头开仓加入队列:[(Id6,1,8.0,0.0)]
  • 净持仓变为-6+7=1(多头)
  • Id6的PnL=0.0(剩余1份资产)

最终结果(完全匹配你的期望)

IdVerbQtyPricePnL
1Buy610.07.0
2Sell511.00.0
3Buy410.02.0
4Sell312.00.0
5Sell89.06.0
6Buy78.00.0(剩余1份资产)

内容的提问来源于stack exchange,提问作者Pap

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 12:03:24