1. 基于订单簿不平衡的做市价差动态调整

任务目标

实现一个订单簿不平衡驱动的做市策略核心逻辑:根据订单簿买卖盘深度不平衡度,动态调整买卖报价相对中间价的偏移(价差),在提供流动性的同时控制库存风险。策略输入为订单簿快照(买一/卖一价格与数量),输出为调整后的买价与卖价。

核心逻辑

不平衡度定义为 imbalance = bidVol / (bidVol + askVol),取值范围 [0,1]。当买单深度显著大于卖单时(imbalance 接近 1),说明卖方流动性不足,做市商应提高卖价(减少卖出风险敞口),同时可适当降低买价以吸引成交、积累库存;反之亦然。价差偏移量由不平衡度与目标库存共同决定。

完整实现

import math

class OrderBookSnapshot:
    def __init__(self, bid_price, bid_vol, ask_price, ask_vol):
        self.bid_price = bid_price
        self.bid_vol = bid_vol
        self.ask_price = ask_price
        self.ask_vol = ask_vol

class MarketMakingStrategy:
    def __init__(self, spread_base=0.01, max_offset=0.005, target_inventory=0.0,
                 inventory_penalty=0.001, position=0.0):
        self.spread_base = spread_base          # 基础价差(价格)
        self.max_offset = max_offset            # 最大单边偏移量
        self.target_inventory = target_inventory  # 目标库存(正=多头)
        self.inventory_penalty = inventory_penalty  # 库存偏离惩罚系数
        self.position = position                # 当前净库存(正=净多头)

    def compute_imbalance(self, book: OrderBookSnapshot) -> float:
        total_vol = book.bid_vol + book.ask_vol
        if total_vol == 0:
            return 0.5
        return book.bid_vol / total_vol

    def inventory_offset(self) -> float:
        """库存偏移:库存偏离目标越远,报价越偏向降低库存方向"""
        return (self.target_inventory - self.position) * self.inventory_penalty

    def calculate_quotes(self, book: OrderBookSnapshot):
        mid_price = (book.bid_price + book.ask_price) / 2.0
        imbalance = self.compute_imbalance(book)

        # 不平衡偏移:买单多时提高卖价,降低买价(偏移方向相反)
        imbalance_offset = (imbalance - 0.5) * 2 * self.max_offset

        # 总偏移 = 不平衡偏移 + 库存偏移
        total_offset = imbalance_offset + self.inventory_offset()
        total_offset = max(-self.max_offset, min(self.max_offset, total_offset))

        half_spread = self.spread_base / 2.0
        bid_price = mid_price - half_spread + total_offset
        ask_price = mid_price + half_spread + total_offset

        return round(bid_price, 4), round(ask_price, 4)

    def update_position(self, trade_price: float, trade_qty: float, side: str):
        """side: 'buy' 表示我们买入(库存增加),'sell' 表示我们卖出(库存减少)"""
        if side == 'buy':
            self.position += trade_qty
        elif side == 'sell':
            self.position -= trade_qty

运行与验证

# 验证脚本
if __name__ == "__main__":
    # 场景1:买卖深度均衡,无库存
    book1 = OrderBookSnapshot(100.0, 10, 100.1, 10)
    mm = MarketMakingStrategy()
    bid1, ask1 = mm.calculate_quotes(book1)
    print(f"均衡场景: bid={bid1}, ask={ask1}")
    # 预期: 价差中心=100.05, 偏移≈0, bid≈100.00, ask≈100.10

    # 场景2:买单深度远大于卖单(imbalance≈0.83)
    book2 = OrderBookSnapshot(100.0, 50, 100.1, 10)
    bid2, ask2 = mm.calculate_quotes(book2)
    print(f"买单倾斜场景: bid={bid2}, ask={ask2}")
    # 预期: 偏移为正(约+0.0033),bid≈100.003, ask≈100.103

    # 场景3:库存为净多头,应降低报价以卖出减库存
    mm.position = 20  # 净多头20
    bid3, ask3 = mm.calculate_quotes(book1)
    print(f"净多头库存场景: bid={bid3}, ask={ask3}")
    # 预期: 偏移为负(约-0.02被截断到-0.005),bid≈99.995, ask≈100.095

    # 场景4:更新库存后重新计算
    mm.update_position(100.05, 5, 'sell')  # 卖出5,库存从20降到15
    bid4, ask4 = mm.calculate_quotes(book1)
    print(f"减仓后: bid={bid4}, ask={ask4}")

验证方法:运行上述脚本,观察输出是否符合以下判定条件:

  • 场景1中买卖价差约为 spread_base(0.01),且买卖价围绕中间价对称分布;
  • 场景2中卖价相对场景1上移(因买单深度大,卖方流动性不足,提高卖价),买价相对下移,价差扩大;
  • 场景3中买卖报价整体下移(偏移为负),使报价更具吸引力以促成卖出、降低净多头库存;
  • 场景4中库存减少后,负向偏移幅度较场景3收窄。

若输出满足上述逻辑关系,则策略核心实现正确。实际部署时需将 calculate_quotes 接入交易所订单簿推送流,并在每次成交后调用 update_position 更新库存。