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

如何用Pandas Pivot Table计算每笔买卖订单的盈亏?

问题描述

我需要计算每行中每个交易标的对(BUY Order、SELL Order)的盈亏,我的DataFrame如下(附截图)。计算逻辑:

  • 每个BROKERCODE对应交易标的的买卖行不一定成对;
  • 部分BROKERCODE针对特定标的仅存在买入或卖出行(如第8、11行);
  • 找到买卖对时,盈亏=ORD_AMT(SELL)-ORD_AMT(BUY);
  • 无配对的行不计算PNL;
  • QTY_FILLED为'0'的行忽略。

我尝试用Pandas PIVOT_TABLE未实现需求,求相关代码片段。

解决方案

先过滤无效数据,再按分组匹配买卖对计算盈亏,代码如下:

import pandas as pd

# 1. 过滤掉QTY_FILLED为0的行(注意如果QTY_FILLED是数值类型,去掉引号)
df = df[df['QTY_FILLED'] != '0'].copy()

# 2. 按经纪商+交易标的分组,这里假设标的字段是SYMBOL,根据实际列名替换
grouped = df.groupby(['BROKERCODE', 'SYMBOL'])

# 3. 定义分组计算盈亏的函数
def calc_pair_pnl(group):
    # 拆分买入、卖出行
    buy_group = group[group['ORDER_TYPE'] == 'BUY'].reset_index(drop=True)
    sell_group = group[group['ORDER_TYPE'] == 'SELL'].reset_index(drop=True)
    
    # 取最小配对数
    pair_num = min(len(buy_group), len(sell_group))
    if pair_num == 0:
        group['PNL'] = None
        return group
    
    # 给配对的订单赋值盈亏
    for i in range(pair_num):
        pnl_val = sell_group.loc[i, 'ORD_AMT'] - buy_group.loc[i, 'ORD_AMT']
        # 对应到原分组的索引
        group.loc[buy_group.index[i], 'PNL'] = pnl_val
        group.loc[sell_group.index[i], 'PNL'] = pnl_val
    
    # 未配对的订单PNL设为None
    unpaired_idx = group.index.difference(buy_group.index[:pair_num].union(sell_group.index[:pair_num]))
    group.loc[unpaired_idx, 'PNL'] = None
    return group

# 4. 应用函数到所有分组,得到结果
result_df = grouped.apply(calc_pair_pnl).reset_index(drop=True)

代码说明

  • 数据过滤:先排除QTY_FILLED为0的无效订单,避免干扰计算;
  • 分组逻辑:按BROKERCODE+交易标的(需替换为你DataFrame中实际的标的列名)分组,确保同一经纪商同一标的的订单放在一起处理;
  • 配对规则:采用按顺序配对(最早的买对应最早的卖),如果需要按金额/数量匹配,可修改buy_group和sell_group的排序规则(比如按成交时间排序);
  • 结果输出:配对的买卖订单会标记相同的盈亏值,未配对的订单PNL字段设为None。

如果你的DataFrame中订单类型字段不是ORDER_TYPE,或者标的字段不是SYMBOL,请自行替换为实际列名。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 08:43:28