3. 订单取消功能实现

任务说明

在已有订单簿基础上,新增 cancel(order_id) 方法:按订单 ID 查找订单,判断其买卖方向,从对应列表(bids 或 asks)中移除,并返回被取消的订单;若 ID 不存在则返回 None。

数据结构与取消流程

cancel(order_id) 输入订单ID 遍历 bids + asks 查找匹配 order_id 从对应列表移除 返回被取消订单 未找到 返回 None

完整代码

from dataclasses import dataclass, field

@dataclass
class Order:
    order_id: int
    side: str          # "buy" 或 "sell"
    price: float
    qty: int

class OrderBook:
    def __init__(self):
        self.bids = []   # 买单列表
        self.asks = []   # 卖单列表

    def add(self, order: Order):
        if order.side == "buy":
            self.bids.append(order)
        elif order.side == "sell":
            self.asks.append(order)
        else:
            raise ValueError(f"未知方向: {order.side}")

    def cancel(self, order_id: int):
        """按订单ID取消订单,返回被取消的订单;不存在返回 None。"""
        for book in (self.bids, self.asks):
            for i, order in enumerate(book):
                if order.order_id == order_id:
                    book.pop(i)
                    return order
        return None

    def snapshot(self):
        return {
            "bids": [(o.order_id, o.price, o.qty) for o in self.bids],
            "asks": [(o.order_id, o.price, o.qty) for o in self.asks],
        }

if __name__ == "__main__":
    ob = OrderBook()
    ob.add(Order(1, "buy", 100.0, 10))
    ob.add(Order(2, "buy", 99.5, 5))
    ob.add(Order(3, "sell", 101.0, 8))
    ob.add(Order(4, "sell", 102.0, 3))

    print("取消前:", ob.snapshot())

    removed = ob.cancel(2)
    print("取消订单2:", removed)
    print("取消后:", ob.snapshot())

    missing = ob.cancel(999)
    print("取消不存在的999:", missing)

运行与验证

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

  • 取消前 bids 含订单 1、2,asks 含订单 3、4;
  • cancel(2) 返回订单 2,之后 bids 只剩订单 1,asks 不变;
  • cancel(999) 返回 None,两个列表均不变。

通过条件:被取消订单从对应列表消失、另一侧列表不受影响、返回值与订单 ID 一致;对不存在的 ID 返回 None 且列表长度不变。