基于Pandas实现股票交易数据FIFO先进先出计算的问题求助
基于Pandas实现交易数据FIFO核算方案
核心实现思路
- 首先对全量交易数据按
datetime升序排序,保证先进先出的时序基础 - 拆分买入、卖出订单为两个独立队列,给买入订单新增
remaining字段标记未匹配的剩余持仓量 - 逐笔遍历卖出订单,从最早的未完全匹配的买入订单中扣减对应交易量,直到该卖出订单的量全部匹配完成
- 已完全匹配的交易订单直接移出匹配队列,不会被二次调用,彻底避免重复使用问题
可运行实现代码
import pandas as pd # 替换为自己的实际数据集 df = pd.read_csv("你的交易数据路径.csv") # 转换时间格式并按时间升序排序,保证FIFO时序 df['datetime'] = pd.to_datetime(df['datetime']) df = df.sort_values('datetime').reset_index(drop=True) # 拆分买卖队列 buy_list = df[df['side'] == 'buy'].copy().reset_index(drop=True) buy_list['remaining_amount'] = buy_list['amount'] # 新增剩余未匹配量字段 sell_list = df[df['side'] == 'sell'].copy().reset_index(drop=True) match_details = [] current_buy_index = 0 # 当前待匹配的最早买入订单索引 for _, sell_row in sell_list.iterrows(): unmatch_sell_amount = sell_row['amount'] # 循环匹配直到当前卖单完全匹配,或没有可匹配的买单 while unmatch_sell_amount > 1e-8 and current_buy_index < len(buy_list): current_buy = buy_list.loc[current_buy_index] # 取可匹配的最小量 match_volume = min(unmatch_sell_amount, current_buy['remaining_amount']) # 记录匹配明细,可按需扩展字段 match_details.append({ "sell_datetime": sell_row['datetime'], "sell_price": sell_row['price'], "buy_datetime": current_buy['datetime'], "buy_price": current_buy['price'], "match_amount": match_volume, "realized_profit": (sell_row['price'] - current_buy['price']) * match_volume }) # 更新剩余未匹配量 unmatch_sell_amount -= match_volume buy_list.loc[current_buy_index, 'remaining_amount'] -= match_volume # 当前买单已完全匹配,移动到下一个最早买单 if buy_list.loc[current_buy_index, 'remaining_amount'] <= 1e-8: current_buy_index += 1 # 转换为DataFrame格式输出 match_result = pd.DataFrame(match_details) print(match_result)
关键特性说明
- 完全遵循FIFO规则,所有交易记录仅会被匹配一次,不会出现
bfill的重复调用问题 - 内置1e-8浮点精度容错逻辑,适配加密货币小数交易量的计算场景
- 输出明细自动关联每笔平仓对应的开仓时间、开仓成本,可直接用于后续收益统计、持仓周期核算
内容的提问来源于stack exchange,提问作者noobisme
相关产品推荐
相关产品推荐

