如何用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
相关产品推荐
相关产品推荐

