外汇交易匹配问题求助:单笔买入与多笔卖出交易的匹配实现
解决FX交易匹配轧差中的多笔组合匹配问题
首先把你的交易数据整理成清晰的表格,方便后续分析:
| 序号 | 买入币种(Buy Currency) | 卖出币种(Sell Currency) | 买入金额(Buy Amount) | 卖出金额(Sell Amount) |
|---|---|---|---|---|
| 1 | CHF | USD | 50000 | 61000 |
| 2 | USD | CHF | 20999 | 20000 |
| 3 | USD | CHF | 34000 | 30000 |
| 4 | CHF | AUD | 400 | 356 |
| 5 | AUD | CHF | 378 | 400 |
| 6 | USD | CHF | 34000 | 30000 |
从你描述的需求来看,核心是要找到单笔买入交易对应的同反向货币对的多笔卖出交易组合,并且组合金额刚好匹配轧差要求。你已经完成了基础的币种校验和金额匹配逻辑,现在卡在多笔组合的货币对验证上,我来给你梳理下解决思路和代码实现:
已完成逻辑回顾
你已经实现的这几个基础逻辑很扎实:
- 交叉校验买入/卖出币种的重叠性:
[i for i in df['Buy Currency'].unique() if i in df['Sell Currency'].unique()] - 避免单一买入币种的无效循环:
assert len(set(df['Buy Currency'])) != 1 - 快速定位精确匹配的单笔金额:
[amt for amt in df['Buy Amount'].astype(int).tolist() if amt in df['Sell Amount'].astype(int).tolist()]
核心瓶颈破解思路
你提到用itertools.combinations时无法验证货币对,其实只需要在生成组合前,先筛选出目标交易的反向货币对交易,再在这个子集里找金额组合就可以了。具体来说:
- 对于目标交易(比如CHF→USD,买入50000 CHF),反向交易必须是USD→CHF(买入USD,卖出CHF),这些交易的卖出金额就是CHF的数量,正好对应目标的买入金额
- 然后在这些反向交易里,找任意数量的组合,使得它们的卖出金额之和等于目标的买入金额
完整实现代码
我基于你的需求写了可直接运行的代码,包含注释说明:
import pandas as pd import itertools # 初始化你的交易数据 data = [ [1, "CHF", "USD", 50000, 61000], [2, "USD", "CHF", 20999, 20000], [3, "USD", "CHF", 34000, 30000], [4, "CHF", "AUD", 400, 356], [5, "AUD", "CHF", 378, 400], [6, "USD", "CHF", 34000, 30000] ] df = pd.DataFrame(data, columns=["ID", "Buy Currency", "Sell Currency", "Buy Amount", "Sell Amount"]) def find_matching_hedge_combinations(target_trade): """ 查找能与目标交易轧差的反向交易组合 :param target_trade: 目标交易的行对象(比如df.iloc[0]) :return: 符合条件的交易ID组合列表 """ # 提取目标交易的核心信息:买入币种、卖出币种、需要匹配的买入金额 target_buy_ccy = target_trade["Buy Currency"] target_sell_ccy = target_trade["Sell Currency"] target_match_amount = target_trade["Buy Amount"] # 第一步:筛选出所有反向货币对的交易 # 反向交易的定义:买入目标的卖出币种,卖出目标的买入币种 eligible_trades = df[ (df["Buy Currency"] == target_sell_ccy) & (df["Sell Currency"] == target_buy_ccy) ] if eligible_trades.empty: return [] # 没有符合条件的反向交易 valid_combinations = [] # 尝试从1笔到N笔的所有组合长度 for combo_size in range(1, len(eligible_trades)+1): # 生成该长度下的所有交易组合 for trade_combo in itertools.combinations(eligible_trades.iterrows(), combo_size): # 计算组合中所有交易的卖出金额之和(因为卖出的是目标买入币种) total_sold_amount = sum([trade[1]["Sell Amount"] for trade in trade_combo]) if total_sold_amount == target_match_amount: # 提取组合中的交易ID,存入结果 combo_ids = [trade[1]["ID"] for trade in trade_combo] valid_combinations.append(combo_ids) return valid_combinations # 测试第1笔交易 print("第1笔交易的匹配组合:", find_matching_hedge_combinations(df.iloc[0])) # 输出:第1笔交易的匹配组合: [[2, 3], [2, 6]] # 测试第4笔交易 print("第4笔交易的匹配组合:", find_matching_hedge_combinations(df.iloc[3])) # 输出:第4笔交易的匹配组合: [[5]]
代码细节说明
- 反向交易筛选:通过Pandas的布尔索引,精准过滤出和目标交易货币对完全反向的交易,确保后续组合只在有效范围内生成
- 组合遍历:用
itertools.combinations生成所有可能的交易组合,从单笔到多笔,覆盖所有潜在的轧差可能 - 金额校验:对每个组合的卖出金额求和,和目标交易的买入金额对比,匹配则记录交易ID
优化建议
如果你的交易数据量较大,可以做以下优化:
- 限制组合的最大长度(比如最多3笔),减少不必要的计算
- 加入金额容错阈值(比如
abs(total_sold_amount - target_match_amount) < 0.01),适应实际交易中的微小误差 - 对反向交易按金额排序,优先尝试金额大的组合,提升匹配效率
内容的提问来源于stack exchange,提问作者WLC
相关产品推荐
相关产品推荐

