2. 限价单的添加与价格优先排序

任务目标

实现一个最小订单簿:支持添加限价单,并保证买单按价格从高到低、卖单按价格从低到高排列。相同价格时按到达顺序(时间优先)排列。

数据结构与排序规则

  • 订单用字典表示:{"id": 订单号, "price": 价格, "qty": 数量, "side": "buy"/"sell"}。
  • 订单簿用两个列表:bids(买单)和 asks(卖单)。
  • 排序键:买单 (-price, seq),卖单 (price, seq),seq 为自增到达序号,保证同价时间优先。
add_order(order) side? buy / sell bids 追加 asks 追加 bids: -price 升序 asks: price 升序

完整实现

class OrderBook:
    def __init__(self):
        self.bids = []   # 买单:价格降序
        self.asks = []   # 卖单:价格升序
        self._seq = 0    # 到达序号,用于同价时间优先

    def add_order(self, order_id, price, qty, side):
        if side not in ("buy", "sell"):
            raise ValueError("side must be 'buy' or 'sell'")
        if price <= 0 or qty <= 0:
            raise ValueError("price and qty must be positive")

        self._seq += 1
        order = {"id": order_id, "price": price, "qty": qty,
                 "side": side, "seq": self._seq}

        if side == "buy":
            self.bids.append(order)
            self.bids.sort(key=lambda o: (-o["price"], o["seq"]))
        else:
            self.asks.append(order)
            self.asks.sort(key=lambda o: (o["price"], o["seq"]))
        return order

    def best_bid(self):
        return self.bids[0] if self.bids else None

    def best_ask(self):
        return self.asks[0] if self.asks else None

if __name__ == "__main__":
    ob = OrderBook()
    ob.add_order("B1", 100.0, 10, "buy")
    ob.add_order("B2", 101.5, 5, "buy")
    ob.add_order("B3", 100.0, 8, "buy")   # 与 B1 同价,应排在 B1 之后
    ob.add_order("S1", 102.0, 4, "sell")
    ob.add_order("S2", 101.0, 6, "sell")
    ob.add_order("S3", 102.0, 3, "sell")  # 与 S1 同价,应排在 S1 之后

    print("bids:", [(o["id"], o["price"]) for o in ob.bids])
    print("asks:", [(o["id"], o["price"]) for o in ob.asks])
    print("best_bid:", ob.best_bid()["id"], ob.best_bid()["price"])
    print("best_ask:", ob.best_ask()["id"], ob.best_ask()["price"])

运行与验证

直接运行脚本:python order_book.py。根据代码逻辑可确定预期输出:

bids: [('B2', 101.5), ('B1', 100.0), ('B3', 100.0)]
asks: [('S2', 101.0), ('S1', 102.0), ('S3', 102.0)]
best_bid: B2 101.5
best_ask: S2 101.0

判定通过条件:买单价格严格降序,卖单价格严格升序;同价订单按添加顺序排列(B1 在 B3 前,S1 在 S3 前);best_bid 为最高买价,best_ask 为最低卖价。