跨交易所价差套利匹配算法

跨交易所价差套利匹配算法

给出的数据结构

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]
}

key = 交易所名称-手续费value = [价格, 数量]

  • bids = 买单一档报价(该交易所上有人愿意出最高价买入)
  • asks = 卖单一档报价(该交易所上有人愿意出最低价卖出)

以上为两个字典,分别代表当前买单一档报价和卖单一档报价,其中key为:交易所名称-手续费,value为:[价格,数量]
需求:
1.计算有价差套利机会的两个交易所,扣掉手续费后有利润
2.某一交易所套利完成后,减少挂单量,继续匹配下一个交易所,直到挂单量清0

一、套利逻辑与条件

跨所套利的经典做法:在"卖出价(ask)最低"的交易所买,在"买入价(bid)最高"的交易所卖

  • 在交易所 B 以 ask_B 买入 1 单位,实际成本 = ask_B + fee_B(买入付本方手续费);
  • 在交易所 A 以 bid_A 卖出 1 单位,实际所得 = bid_A - fee_A(卖出付本方手续费);

- 套利单位利润

profit=(bidA−feeA)−(askB+feeB)\text{profit} = (\text{bid}_A - fee_A) - (\text{ask}_B + fee_B)profit=(bidAfeeA)(askB+feeB)

- 只有当 text{profit} 0\\text\{profit\} \> 0text{profit}0 时才存在扣费后有利润的套利机会(且必须跨交易所,同一交易所自我对冲无意义)。

说明:key 中的手续费(如 0.00024)为费率,套利单边各付一次,故买方加费、卖方扣费。

二、核心算法

Step 1:找出所有"扣费后仍有利润"的跨所机会

遍历所有 (bid 交易所, ask 交易所) 组合,排除同所,计算扣费后单位利润,取利润 > 0 的,并按单位利润降序排列。

Step 2:贪心按量匹配,每完成一笔扣减挂单,直到挂单清 0

反复执行:

  1. 取当前单位利润最高的机会;
  2. 成交数量 = min(买方挂单量, 卖方挂单量);
  3. 分别扣减两侧挂单量,挂单量减为 0 的报价从盘中移除;
  4. 若无利润为正的机会或任一侧挂单清 0,则停止。

伪代码

def parse(m, sign):
    # m 是 bids 或 asks dict
    # sign=+1 卖出方扣费, sign=-1 买入方加费(便于统一)

def find_profitable(bids, asks):
    opps = []
    for A in bids:          # A 是卖出方(以 bid 卖)
        for B in asks:      # B 是买入方(以 ask 买)
            if A.ex == B.ex: continue
            sell_net = A.price - A.fee
            buy_cost = B.price + B.fee
            if sell_net - buy_cost > 0:
                opps.append(
                    (buy=B, sell=A, unit_profit=sell_net-buy_cost,
                     qty=min(A.qty, B.qty)))
    return sortby(opps, -unit_profit)

def match_all(bids, asks):
    trades = []
    while True:
        opps = find_profitable(bids, asks)
        if not opps: break
        best = opps[0]
        qty = best.qty
        # 扣减买卖双方挂单
        asks[best.buy].qty -= qty
        bids[best.sell].qty -= qty
        # 挂单清0则移除对应报价
        if asks[best.buy].qty == 0: del asks[best.buy]
        if bids[best.sell].qty == 0: del bids[best.sell]
        trades.append(best.with(qty) )
    return trades

三、运行结果(已在本机实际运行验证)

第一步:所有扣费后有利润的跨所套利机会(按利润降序)

在这里插入图片描述

注:ex1 既出现在 bids 又出现在 asks,但跨所套利要求"买、卖在不同交易所",故本表只列出净值严格为正、(买,卖)跨所的配对。

第二步:贪心按量匹配(每笔扣减挂单,直到无法套利/挂单清 0)

笔序买入所卖出所数量单位利润该笔总利润
1ex5 (买)ex4 (卖)30.0597500.179250
2ex1 (买)ex4 (卖)10.0595100.059510
3ex1 (买)ex3 (卖)50.0395600.197800
4ex1 (买)ex2 (卖)100.0192600.192600

共成交 4 笔,总套利利润 = 0.629160

执行细节解释

  • ex4 的卖出端(bid=1.02)只有 4 手,先被利润最高的 ex5(3手)吃掉,剩 1 手被 ex1 吃掉 → ex4 卖单清 0 出局;
  • 之后 ex3(bid=1.00)吃掉 ex1 的 5 手 → ex3 卖单清 0 出局;
  • 最后 ex2(bid=0.98)吃掉 ex1 剩余的 10 手 → ex1 买单清 0;
  • 到此所有"盈利配对"都做满,剩余报价(ex1 asks、ex5 剩余 bids、ex4/ex3/ex2 已清 0 或买不到便宜货)已无正利润跨所组合,算法停止。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值