当前位置: 首页 > news >正文

答案

下面这道题可以抽象为跨交易所一价套利(跨所买入→另一所卖出),且每个交易所的一档挂单都带有按成交额计提的费率。思路分三步:


解题思路(算法)

1)费用模型与判定条件

  • 若在交易所 \(A\) 以卖一价(ask)买入、费率 \(f_A\),单位成本
    \(\text{cost}_A=\text{ask}_A\cdot(1+f_A)\)

  • 在交易所 \(B\) 以买一价(bid)卖出、费率 \(f_B\),单位到手收入
    \(\text{rev}_B=\text{bid}_B\cdot(1-f_B)\)

  • 只有当

    \[\text{rev}_B-\text{cost}_A>0 \]

    才存在扣费后的真实套利空间。把 \(\text{ppu}=\text{rev}_B-\text{cost}_A\) 叫做单位净差(per-unit profit)。

2)撮合与更新

  • 对所有 \(A\neq B\) 的组合计算 \(\text{ppu}\),挑选单位净差最大的组合优先成交(贪心)。
  • 成交量取两边可成交量的最小值 \(q=\min(q^{\text{bid}}_B,q^{\text{ask}}_A)\)
  • 成交后把两边的可成交量减去 \(q\),若一侧清零则从候选集合移除。
  • 继续寻找下一笔 \(\text{ppu}>0\) 的组合,直到没有正利润的组合为止。

这样做满足你的第 2 点要求:“某一交易所套利完成后,减少挂单量,继续匹配下一个交易所,直到挂单量清 0”。

3)时间复杂度

  • 共有 \(m\) 个卖出所(bids)与 \(n\) 个买入所(asks),每轮最多评估 \(m\times n\) 个组合,配合堆/排序维护最大 \(\text{ppu}\) 即可,整体规模很小。

代入你给的具体数据

原始一档(价格,数量)与费率(从 key 中拆出):

  • Bids(卖出侧)
    ex1-0.00024: (0.95, 10)
    ex2-0.0005 : (0.98, 10)
    ex3-0.0002 : (1.00, 5)
    ex4-0.00025: (1.02, 4)
    ex5-0 : (0.94, 11)

  • Asks(买入侧)
    ex1-0.00024: (0.96, 50)
    ex2-0.0005 : (1.03, 8)
    ex3-0.0002 : (1.01, 2)
    ex4-0.00025: (1.04, 5)
    ex5-0 : (0.96, 3)

按照上面的规则计算、并按单位净差最大顺序撮合,得到 4 笔可盈利交易(价格单位同原始数据;费率为小数):

步骤 卖出所(Bid) 卖价 卖费 买入所(Ask) 买价 买费 成交量 单位净差 ppu 本笔利润
1 ex4 1.02 0.00025 ex5 0.96 0.0 3 0.0597450 0.1792350
2 ex4 1.02 0.00025 ex1 0.96 0.00024 1 0.0595146 0.0595146
3 ex3 1.00 0.00020 ex1 0.96 0.00024 5 0.0395696 0.1978480
4 ex2 0.98 0.00050 ex1 0.96 0.00024 10 0.0192796 0.1927960
  • 总利润\(0.1792350+0.0595146+0.1978480+0.1927960=\mathbf{0.6293936}\)

撮合后的剩余挂单量

  • Bids:ex1:10,ex2:0,ex3:0,ex4:0,ex5:11
  • Asks:ex1:34,ex2:8,ex3:2,ex4:5,ex5:0

此时市场再也没有正的 \(\text{ppu}\)
\(\max \text{rev}_B = 0.95\cdot(1-0.00024)=0.949772\)(来自 ex1-bid);
\(\min \text{cost}_A = 0.96\cdot(1+0.00024)=0.9602304\)(来自 ex1-ask)。
因为 \(0.949772<0.9602304\),套利结束。


可直接复用的 Python 参考实现

# 输入:两字典 bids, asks;key="交易所-费率",value=[价格, 数量]
def parse_fee(k): return float(k.split('-')[1])
def to_side(d, side):out=[]for k,(p,q) in d.items():ex, fee = k.split('-')[0], parse_fee(k)out.append({'ex': ex, 'fee': fee, 'px': p, 'qty': q, 'side': side})return outdef unit_rev(bi):  # 卖出侧到手return bi['px'] * (1 - bi['fee'])
def unit_cost(aj): # 买入侧成本return aj['px'] * (1 + aj['fee'])def best_pairs(bids, asks):cand=[]for bi in bids:if bi['qty']<=0: continuefor aj in asks:if aj['qty']<=0 or bi['ex']==aj['ex']: continueppu = unit_rev(bi) - unit_cost(aj)if ppu > 0:cand.append((ppu, min(bi['qty'], aj['qty']), bi, aj))cand.sort(key=lambda x:(x[0], x[1]), reverse=True)return canddef arbitrage(bids_dict, asks_dict):B, A = to_side(bids_dict, 'bid'), to_side(asks_dict, 'ask')trades, total = [], 0.0while True:pairs = best_pairs(B, A)if not pairs: breakppu, q, bi, aj = pairs[0]trades.append(dict(sell_ex=bi['ex'], sell_bid=bi['px'], sell_fee=bi['fee'],buy_ex=aj['ex'],  buy_ask=aj['px'],  buy_fee=aj['fee'],qty=q, ppu=ppu, profit=ppu*q))total += ppu*qbi['qty'] -= qaj['qty'] -= qreturn trades, total, B, A

把你题面给出的 bidsasks 直接传给 arbitrage 即可得到上面同样的 4 笔成交与总利润 0.6293936,并且每一笔成交后数量都会按规则减少、直到无利可图为止。


备注与扩展

  • 这里费率按双边各一次计提,且忽略充提/跨所转账时间与资金占用风险;真实交易需再考虑滑点、穿仓、撮合延迟、撤单失败、转账成本等。
  • 若希望稳健而非贪心,可以把阈值设为 \(\text{ppu}>\epsilon\)(例如覆盖潜在滑点),或先以“单位净差/对手量”的综合指标排序。
  • 若要支持多档深度,思路相同:把每档拆成一条记录,统一进入上述撮合循环即可。
http://www.hskmm.com/?act=detail&tid=950

相关文章:

  • datadome OfflineAudioContext
  • AI测试平台自动遍历:低代码也能玩转全链路测试
  • 2025-09-10
  • Codeforces Round 1047 (Div. 3)
  • sentinel-1.8.0 安装
  • 数据结构与算法-27.树-并查集
  • wpf XAML设计器在加载用户控件的时候,提示null引用等直接执行了用户控件里构造函数代码的问题
  • 设计模式-策略
  • Linux中怎么调整系统inode数量?
  • DARPA AI网络挑战赛技术框架全解析:自动化漏洞挖掘与修复系统构建
  • 数据库基本查询语句
  • 【项目实战】基于WS63的鸿蒙星闪红外遥控车(循迹、超声波避障、远程控制、星闪/红外遥控)有教程代码
  • macbook pro怎么安装windows系统
  • XSS与CSRF的联系与区别
  • 异或
  • apche 2.4 开启mod_cache_disk和mod_deflate后,磁盘上缓存的是压缩后的文件
  • 复现tensor2tensor代码时遇到的问题和相关链接
  • macbook pro如何安装windows系统
  • 【ACM出版】第四届公共管理、数字经济与互联网技术国际学术会议(ICPDI 2025)
  • 如何在 Linux 中关闭 Swap(虚拟内存)
  • 再见 Cursor,Qoder 真香!这波要改写 AI 编程格局
  • 三.ubuntu22.04 使用C++部署PyTorch模型
  • alertmanager配置集群模式
  • 《Python数据结构与算法分析》代码
  • AI 是否绑架了云原生创新?
  • Windows 7 局域网打印机共享设置
  • SPFA求负环
  • 磁盘存储器
  • 多变量的递归2-组合总和问题(每个数字可以使用多次)
  • 戴尔Precision 7865 塔式工作站|安装rocky liunx 8.10