结论摘要

本文将深入探讨订单簿(Order Book)微观结构的核心建模方法,重点解析信息非对称性如何影响价格发现机制。我将从限价订单簿的数学建模出发,结合 Python 代码实现真实市场数据的处理流程,并分享使用 HolySheep AI API 构建订单簿分析系统的实战经验。订单簿微观结构是理解市场深度、流动性分布和信息传递机制的基础,适合量化交易员、风险分析师和对高频数据建模感兴趣的开发者。

订单簿微观结构基础概念

订单簿是金融市场上买卖双方挂单信息的实时记录,包含价格、挂单量、订单时间等维度。从微观结构视角看,订单簿反映了市场参与者的供需博弈,是价格发现的直接载体。

订单簿的核心数据结构

一个标准的订单簿包含以下关键字段:
# Python 订单簿数据结构定义
from dataclasses import dataclass
from typing import List, Optional
from collections import deque
import time

@dataclass
class Order:
    """订单对象"""
    order_id: str
    price: float
    volume: float
    side: str  # 'bid' or 'ask'
    timestamp: float
    participant_id: Optional[str] = None

@dataclass
class OrderBookLevel:
    """订单簿档位"""
    price: float
    volume: float
    order_count: int

class OrderBook:
    """订单簿模拟器"""
    
    def __init__(self, symbol: str, max_levels: int = 10):
        self.symbol = symbol
        self.max_levels = max_levels
        self.bids: List[OrderBookLevel] = []  # 买单列表(价格从高到低)
        self.asks: List[OrderBookLevel] = []  # 卖单列表(价格从低到高)
        self.trades: deque = deque(maxlen=1000)  # 成交记录
        self.mid_price: float = 0.0
        self.spread: float = 0.0
        self._last_update: float = 0.0
    
    def update_bid(self, price: float, volume: float, order_count: int = 1):
        """更新买单档位"""
        # 找到对应价格的位置
        for i, level in enumerate(self.bids):
            if abs(level.price - price) < 1e-8:
                if volume == 0:
                    self.bids.pop(i)
                else:
                    self.bids[i] = OrderBookLevel(price, volume, order_count)
                break
        else:
            if volume > 0:
                self.bids.append(OrderBookLevel(price, volume, order_count))
        
        # 保持价格排序
        self.bids.sort(key=lambda x: x.price, reverse=True)
        self.bids = self.bids[:self.max_levels]
        self._update_market_state()
    
    def update_ask(self, price: float, volume: float, order_count: int = 1):
        """更新卖单档位"""
        for i, level in enumerate(self.asks):
            if abs(level.price - price) < 1e-8:
                if volume == 0:
                    self.asks.pop(i)
                else:
                    self.asks[i] = OrderBookLevel(price, volume, order_count)
                break
        else:
            if volume > 0:
                self.asks.append(OrderBookLevel(price, volume, order_count))
        
        self.asks.sort(key=lambda x: x.price)
        self.asks = self.asks[:self.max_levels]
        self._update_market_state()
    
    def _update_market_state(self):
        """更新市场状态指标"""
        if self.bids and self.asks:
            self.mid_price = (self.bids[0].price + self.asks[0].price) / 2
            self.spread = self.asks[0].price - self.bids[0].price
        self._last_update = time.time()
    
    def get_imbalance(self, levels: int = 5) -> float:
        """
        计算订单簿不平衡度
        返回值范围 [-1, 1],正值表示买方压力大,负值表示卖方压力大
        """
        bid_vol = sum(level.volume for level in self.bids[:levels])
        ask_vol = sum(level.volume for level in self.asks[:levels])
        
        if bid_vol + ask_vol == 0:
            return 0.0
        return (bid_vol - ask_vol) / (bid_vol + ask_vol)
    
    def get_microprice(self, levels: int = 5, decay_factor: float = 0.9) -> float:
        """
        计算微观价格(Microprice)
        加权平均价格,考虑订单不平衡度调整
        """
        if not self.bids or not self.asks:
            return self.mid_price
        
        imbalance = self.get_imbalance(levels)
        # Microprice = Mid + imbalance * spread / 2
        microprice = self.mid_price + imbalance * self.spread / 2
        return microprice
    
    def __repr__(self):
        return (f"OrderBook(symbol={self.symbol}, mid={self.mid_price:.2f}, "
                f"spread={self.spread:.4f}, bids={len(self.bids)}, asks={len(self.asks)})")

使用示例

book = OrderBook("BTC-USDT") book.update_bid(42150.5, 2.5, order_count=3) book.update_bid(42149.0, 1.8) book.update_ask(42151.0, 3.2, order_count=5) book.update_ask(42152.5, 1.5) print(f"订单簿状态: {book}") print(f"订单不平衡度: {book.get_imbalance():.4f}") print(f"微观价格: {book.get_microprice():.2f}")

信息非对称性与价格发现机制

信息非对称性的来源

在订单簿微观结构中,信息非对称性主要体现在三个维度:

价格发现的动态过程

知情交易者的订单流会向市场传递私有信息,做市商通过观察订单流的不平衡来调整报价。Glosten 和 Milgrom(1985)提出的价差分解模型指出:
# 信息非对称性建模:价差分解
import numpy as np
from scipy.stats import norm

class AsymmetricInfoModel:
    """
    基于 Glosten-Milgrom 模型的价差分解
    """
    
    def __init__(self, prob_informed: float = 0.3, base_value: float = 100.0):
        self.p_informed = prob_informed  # 知情交易者比例
        self.v = base_value  # 资产基础价值
        self.spread = 0.0
        self.adverse_selection = 0.0
        self.order_processing = 0.0
        self.inventory_cost = 0.0
    
    def compute_spread_components(self, order_flow: int, 
                                  volatility: float = 1.0,
                                  inventory_b担忧: float = 0.2) -> dict:
        """
        分解价差的三个组成部分
        
        Args:
            order_flow: 订单流(正=净买入,负=净卖出)
            volatility: 资产波动率
            inventory_b担忧: 做市商库存担忧系数
        
        Returns:
            包含各组成部分的字典
        """
        # 逆向选择成本(知情交易者导致)
        # 知情交易者更可能在价值上升时买入,下跌时卖出
        prob_buy_informed = 0.5 + 0.5 * np.sign(order_flow)
        
        # 条件期望价值变动
        expected_value_change = (
            self.p_informed * 
            volatility * 
            norm.ppf(prob_buy_informed)
        )
        
        # 逆向选择成本 = E[价值变化 | 订单方向]
        adverse_selection_cost = self.p_informed * volatility * 0.5
        
        # 订单处理成本(固定成本)
        order_processing_cost = 0.01 * self.v
        
        # 库存成本
        net_position = order_flow * 0.1  # 假设每单位订单对应0.1单位持仓
        inventory_cost = abs(net_position) * inventory_b担忧 * volatility
        
        # 总价差
        half_spread = adverse_selection_cost + order_processing_cost + inventory_cost
        total_spread = 2 * half_spread
        
        self.adverse_selection = adverse_selection_cost
        self.order_processing = order_processing_cost
        self.inventory_cost = inventory_cost
        self.spread = total_spread
        
        return {
            'total_spread': total_spread,
            'adverse_selection_cost': adverse_selection_cost,
            'order_processing_cost': order_processing_cost,
            'inventory_cost': inventory_cost,
            'adverse_selection_ratio': adverse_selection_cost / total_spread if total_spread > 0 else 0
        }
    
    def estimate_probability_informed(self, trade_indicator: list) -> float:
        """
        基于交易数据序列估计知情交易者概率
        
        Args:
            trade_indicator: 交易方向序列 [1=买入, -1=卖出, 0=无成交]
        
        Returns:
            估计的知情交易者概率
        """
        # 使用 PIN(Probability of Informed Trading)模型
        buys = sum(1 for t in trade_indicator if t == 1)
        sells = sum(1 for t in trade_indicator if t == -1)
        no_trades = sum(1 for t in trade_indicator if t == 0)
        
        total = len(trade_indicator)
        if total == 0:
            return 0.0
        
        # 简化的 PIN 估计
        alpha = self.p_informed  # 使用先验
        delta = sells / (buys + sells) if (buys + sells) > 0 else 0.5
        
        # 订单到达率(简化假设)
        mu = 0.1  # 知情交易者到达率
        alpha_delta = alpha * delta
        alpha_minus = alpha * (1 - delta)
        
        # 计算似然(需要 MLE,这里用简化版本)
        pin = alpha * (1 - delta) + alpha * delta  # 简化
        
        return pin
    
    def get_optimal_quote(self, position: float, 
                          target_inventory: float = 0.0) -> tuple:
        """
        计算做市商最优报价
        考虑库存偏离和逆向选择风险
        """
        # 库存偏离
        inv_adj = (position - target_inventory) * 0.05
        
        # 基础报价
        base_bid = self.v - self.spread / 2 - inv_adj
        base_ask = self.v + self.spread / 2 - inv_adj
        
        # 考虑订单不平衡的动态调整
        imbalance_担忧 = self.get_order_imbalance_concern()
        quote_spread = self.spread * (1 + imbalance_担忧)
        
        return (base_bid, base_ask, quote_spread)
    
    def get_order_imbalance_concern(self) -> float:
        """计算订单不平衡担忧因子"""
        # 简化:基于知情概率
        return self.p_informed * 0.5

实战应用示例

model = AsymmetricInfoModel(prob_informed=0.25, base_value=42150.0)

场景1:净买入订单流

result1 = model.compute_spread_components(order_flow=10, volatility=50.0) print("=== 净买入场景 ===") print(f"知情交易者比例: {model.p_informed}") print(f"总价差: ${result1['total_spread']:.2f}") print(f" - 逆向选择成本: ${result1['adverse_selection_cost']:.2f} ({result1['adverse_selection_ratio']:.1%})") print(f" - 订单处理成本: ${result1['order_processing_cost']:.2f}") print(f" - 库存成本: ${result1['inventory_cost']:.2f}")

场景2:净卖出订单流

result2 = model.compute_spread_components(order_flow=-10, volatility=50.0) print("\n=== 净卖出场景 ===") print(f"总价差: ${result2['total_spread']:.2f}") print(f"逆向选择成本: ${result2['adverse_selection_cost']:.2f}")

价格冲击模型与滑点估算

订单对价格的冲击是量化策略回测中最重要的误差来源之一。线性冲击模型(Almgren-Chriss 模型)给出了价格冲击与订单规模的定量关系:
# 价格冲击模型与最优执行
import numpy as np
from scipy.optimize import minimize

class PriceImpactModel:
    """
    价格冲击模型
    使用 Almgren-Chriss 框架
    """
    
    def __init__(self, 
                 permanent_impact: float = 0.1,
                 temporary_impact: float = 0.5,
                 volatility: float = 2.0):
        """
        Args:
            permanent_impact: 永久冲击系数(知情程度)
            temporary_impact: 临时冲击系数(流动性)
            volatility: 资产波动率(日频)
        """
        self.gamma = permanent_impact
        self.eta = temporary_impact
        self.sigma = volatility
    
    def permanent_impact(self, trade_rate: float) -> float:
        """永久冲击:影响后续价格"""
        return self.gamma * abs(trade_rate)
    
    def temporary_impact(self, trade_rate: float) -> float:
        """临时冲击:立即执行的滑点"""
        return self.eta * trade_rate
    
    def total_impact(self, trade_rate: float) -> float:
        """总冲击"""
        return self.permanent_impact(trade_rate) + self.temporary_impact(trade_rate)
    
    def estimate_impact_from_trades(self, price_before: float, 
                                    price_after: float,
                                    volume: float) -> dict:
        """从实际交易数据估算冲击系数"""
        price_change = abs(price_after - price_before)
        normalized_change = price_change / price_before
        
        # 临时冲击 = 短期价格变动 / 交易量
        # 永久冲击 = 长期价格变动 - 临时冲击
        estimated_total = normalized_change / volume if volume > 0 else 0
        
        return {
            'estimated_total_impact': estimated_total,
            'price_change_bps': price_change / price_before * 10000,
            'volume': volume
        }
    
    def optimal_execution(self, 
                         shares: float,
                         time_horizon: float,
                         risk_aversion: float,
                         n_periods: int = 100) -> dict:
        """
        Almgren-Chriss 最优执行策略
        
        最小化:执行成本 + 风险惩罚
        
        Args:
            shares: 总执行量
            time_horizon: 执行时间窗口(天)
            risk_aversion: 风险厌恶系数
            n_periods: 离散时间点数
        
        Returns:
            每个时间点的最优交易量
        """
        dt = time_horizon / n_periods
        
        # 协方差矩阵
        cov = self.sigma ** 2 * dt * np.eye(n_periods)
        
        # 目标函数:执行路径的惩罚
        def objective(x):
            # x = 各时间段交易量
            # 临时冲击成本
            temp_cost = self.eta * np.sum(x ** 2)
            # 永久冲击成本
            perm_cost = self.gamma * np.sum(x) ** 2
            # 库存风险
            remaining = shares - np.cumsum(x)
            variance = np.sum(np.array([remaining[i:] ** 2 for i in range(n_periods)]) * dt)
            risk_penalty = risk_aversion * self.sigma ** 2 * variance
            
            return temp_cost + perm_cost + risk_penalty
        
        # 约束:总量等于 shares
        constraints = {'type': 'eq', 'fun': lambda x: np.sum(x) - shares}
        bounds = [(0, shares * 2)] * n_periods
        
        # 初始猜测:均匀分配
        x0 = np.ones(n_periods) * shares / n_periods
        
        result = minimize(objective, x0, method='SLSQP', 
                         bounds=bounds, constraints=constraints)
        
        optimal_trades = result.x
        execution_times = np.linspace(0, time_horizon, n_periods)
        
        return {
            'optimal_trades': optimal_trades,
            'execution_times': execution_times,
            'cumulative_trades': np.cumsum(optimal_trades),
            'expected_cost': result.fun,
            'execution_cost_per_share': result.fun / shares
        }
    
    def simulate_execution(self, shares: float, 
                          impact_coefficient: float = 1.0) -> dict:
        """
        模拟不同执行策略的成本
        
        Args:
            shares: 执行量
            impact_coefficient: 冲击系数调整
        """
        strategies = {
            'TWAP': np.ones(100) * shares / 100,  # 时间加权
            'VWAP': np.ones(100) * shares / 100,  # 成交量加权
            'Aggressive': np.concatenate([
                np.ones(20) * shares * 0.6 / 20,  # 前60%快速
                np.ones(80) * shares * 0.4 / 80   # 后40%缓慢
            ])
        }
        
        results = {}
        for name, trades in strategies.items():
            temp_cost = self.eta * impact_coefficient * np.sum(trades ** 2)
            perm_cost = self.gamma * impact_coefficient * np.sum(trades) ** 2
            total_cost = temp_cost + perm_cost
            
            results[name] = {
                'total_cost': total_cost,
                'cost_bps': total_cost / shares * 10000,
                'avg_slippage_bps': total_cost / shares * 10000
            }
        
        return results

实战应用

impact_model = PriceImpactModel( permanent_impact=0.1, # 永久冲击系数 temporary_impact=0.5, # 临时冲击系数 volatility=2.0 # 日波动率2% )

估算10000股执行的冲击

shares = 10000 price = 42150.0 impact = impact_model.total_impact(shares / 1000000) * price # 归一化后 print(f"执行 {shares} 股的估算冲击成本: ${impact:.2f}") print(f"冲击成本 (bps): {impact / price * 10000:.2f} bps")

最优执行策略

optimal = impact_model.optimal_execution( shares=10000, time_horizon=1.0, # 1天执行完毕 risk_aversion=1e-6, # 风险厌恶系数 n_periods=100 ) print(f"\n最优执行策略预期成本: ${optimal['expected_cost']:.2f}") print(f"每shares成本: ${optimal['execution_cost_per_share']:.4f}")

实战:构建订单簿分析系统

系统架构设计

一个完整的订单簿分析系统需要包含以下模块:
# 订单簿数据采集与处理(使用 HolySheep API 进行语义分析)
import json
import asyncio
import aiohttp
from typing import Dict, List, Optional
from datetime import datetime

class OrderBookCollector:
    """订单簿数据采集器"""
    
    def __init__(self, api_key: str, base_url: str = "https://api.holysheep.ai/v1"):
        self.api_key = api_key
        self.base_url = base_url
        self.order_book_snapshot: Dict = {}
        self.update_sequence: List[Dict] = []
        self._session: Optional[aiohttp.ClientSession] = None
    
    async def connect(self, symbol: str):
        """建立 WebSocket 连接(模拟)"""
        # 实际生产环境中,这里应该是交易所的 WebSocket 地址
        # 例如 Binance: wss://stream.binance.com:9443/ws
        self._session = aiohttp.ClientSession()
        print(f"已连接到 {symbol} 订单簿流")
    
    async def fetch_historical_depth(self, symbol: str, 
                                     limit: int = 100) -> Dict:
        """
        获取历史订单簿深度数据
        REST API 调用示例
        """
        # 注意:这是交易所的公开 API,与 HolySheep API 无关
        # 仅用于获取市场数据
        url = f"https://api.binance.com/api/v3/depth"
        params = {'symbol': symbol, 'limit': limit}
        
        async with self._session.get(url, params=params) as resp:
            if resp.status == 200:
                data = await resp.json()
                return {
                    'lastUpdateId': data['lastUpdateId'],
                    'bids': [(float(p), float(q)) for p, q in data['bids']],
                    'asks': [(float(p), float(q)) for p, q in data['asks']],
                    'timestamp': datetime.now().isoformat()
                }
            else:
                raise Exception(f"获取深度数据失败: {resp.status}")
    
    async def analyze_order_book_with_llm(self, 
                                          order_book_data: Dict) -> Dict:
        """
        使用 LLM 分析订单簿特征
        
        HolySheep API 调用示例:
        - 汇率优势:¥1=$1(官方¥7.3=$1),节省>85%
        - 国内直连延迟<50ms
        - 支持微信/支付宝充值
        """
        # 准备分析上下文
        bids = order_book_data['bids'][:10]
        asks = order_book_data['asks'][:10]
        
        bid_prices = [b[0] for b in bids]
        ask_prices = [a[0] for a in asks]
        
        # 计算基础指标
        mid_price = (bid_prices[0] + ask_prices[0]) / 2
        spread = ask_prices[0] - bid_prices[0]
        spread_pct = spread / mid_price * 100
        
        # 深度分析
        depth_analysis = {
            'mid_price': mid_price,
            'spread': spread,
            'spread_bps': spread / mid_price * 10000,
            'top_10_bid_vol': sum(b[1] for b in bids),
            'top_10_ask_vol': sum(a[1] for a in asks),
            'bid_ask_imbalance': (sum(b[1] for b in bids) - sum(a[1] for a in asks)) / 
                                  (sum(b[1] for b in bids) + sum(a[1] for a in asks))
        }
        
        # 构建 LLM 分析 prompt
        analysis_prompt = f"""作为一位专业的量化交易分析师,请分析以下订单簿数据:

当前价格: {mid_price:.2f}
买卖价差: {spread:.4f} ({spread_pct:.4f}%)
买一~买十总量: {depth_analysis['top_10_bid_vol']:.4f}
卖一~卖十总量: {depth_analysis['top_10_ask_vol']:.4f}
订单不平衡度: {depth_analysis['bid_ask_imbalance']:.4f}

买单价格档位(价格, 数量):
{chr(10).join([f"  买{i+1}: {b[0]:.2f}, {b[1]:.4f}" for i, b in enumerate(bids)])}

卖单价格档位(价格, 数量):
{chr(10).join([f"  卖{i+1}: {a[0]:.2f}, {a[1]:.4f}" for i, a in enumerate(asks)])}

请分析:
1. 市场流动性状态(紧松/深度/弹性)
2. 多空力量对比
3. 短期价格走势判断
4. 潜在支撑/阻力位
"""
        
        # 调用 HolySheep API 进行语义分析
        try:
            async with self._session.post(
                f"{self.base_url}/chat/completions",
                headers={
                    "Authorization": f"Bearer {self.api_key}",
                    "Content-Type": "application/json"
                },
                json={
                    "model": "gpt-4.1",  # $8/MTok output
                    "messages": [
                        {"role": "system", "content": "你是一位专业的量化交易分析师,擅长订单簿分析和价格预测。"},
                        {"role": "user", "content": analysis_prompt}
                    ],
                    "temperature": 0.3,
                    "max_tokens": 500
                }
            ) as resp:
                if resp.status == 200:
                    result = await resp.json()
                    analysis = result['choices'][0]['message']['content']
                    depth_analysis['llm_analysis'] = analysis
                    depth_analysis['llm_model_used'] = 'gpt-4.1'
                else:
                    error_text = await resp.text()
                    depth_analysis['llm_analysis'] = f"API调用失败: {error_text}"
        
        except Exception as e:
            depth_analysis['llm_analysis'] = f"分析异常: {str(e)}"
        
        return depth_analysis
    
    async def process_order_book_stream(self, symbol: str):
        """处理实时订单簿流"""
        await self.connect(symbol)
        
        try:
            # 获取初始快照
            snapshot = await self.fetch_historical_depth(symbol, limit=100)
            self.order_book_snapshot = snapshot
            
            # 模拟增量更新处理
            async for update in self._simulate_updates():
                self._apply_update(update)
                
                # 每100个更新进行一次深度分析
                if len(self.update_sequence) % 100 == 0:
                    analysis = await self.analyze_order_book_with_llm(
                        self.order_book_snapshot
                    )
                    print(f"分析结果: {analysis.get('llm_analysis', 'N/A')[:200]}...")
        
        finally:
            await self.close()
    
    def _apply_update(self, update: Dict):
        """应用订单簿更新"""
        # 更新买卖盘
        for price, qty in update.get('b', []):
            self._update_side('bid', float(price), float(qty))
        for price, qty in update.get('a', []):
            self._update_side('ask', float(price), float(qty))
        
        self.update_sequence.append(update)
    
    def _update_side(self, side: str, price: float, qty: float):
        """更新指定方向的订单"""
        key = f"{side}s"  # bids or asks
        if qty == 0:
            # 删除订单
            self.order_book_snapshot[key] = [
                (p, v) for p, v in self.order_book_snapshot[key] 
                if abs(p - price) > 1e-8
            ]
        else:
            # 更新或添加
            found = False
            for i, (p, v) in enumerate(self.order_book_snapshot[key]):
                if abs(p - price) < 1e-8:
                    self.order_book_snapshot[key][i] = (price, qty)
                    found = True
                    break
            if not found:
                self.order_book_snapshot[key].append((price, qty))
        
        # 重新排序
        reverse = (side == 'bid')
        self.order_book_snapshot[key].sort(
            key=lambda x: x[0], reverse=reverse
        )
    
    async def _simulate_updates(self):
        """模拟订单簿更新流"""
        import random
        import time
        
        for _ in range(1000):
            # 模拟更新数据
            update = {
                'e': 'depthUpdate',
                'b': [(42150 + random.uniform(-0.5, 0.5), 
                       random.uniform(0.1, 2.0)) for _ in range(random.randint(1, 5))],
                'a': [(42151 + random.uniform(-0.5, 0.5), 
                       random.uniform(0.1, 2.0)) for _ in range(random.randint(1, 5))]
            }
            yield update
            await asyncio.sleep(0.05)  # 50ms 间隔
    
    async def close(self):
        """关闭连接"""
        if self._session:
            await self._session.close()

使用示例

async def main(): collector = OrderBookCollector( api_key="YOUR_HOLYSHEEP_API_KEY", # 使用 HolySheep API Key base_url="https://api.holysheep.ai/v1" ) try: # 获取实时数据 depth = await collector.fetch_historical_depth("BTCUSDT", limit=20) # 使用 LLM 分析 analysis = await collector.analyze_order_book_with_llm(depth) print("=== 订单簿分析结果 ===") print(f"中间价: {analysis['mid_price']:.2f}") print(f"价差: {analysis['spread']:.4f} ({analysis['spread_bps']:.2f} bps)") print(f"订单不平衡度: {analysis['bid_ask_imbalance']:.4f}") print(f"LLM 分析模型: {analysis.get('llm_model_used', 'N/A')}") print(f"\nLLM 语义分析:\n{analysis.get('llm_analysis', 'N/A')}") except Exception as e: print(f"执行错误: {e}") finally: await collector.close()

运行

asyncio.run(main())

常见报错排查

问题1:订单簿数据不一致(Sequence Gap)

# 错误:WebSocket 订单簿更新序列不连续

错误信息:OrderBookCacheError: gap in sequence. last=123456, new=123789

class OrderBookCache: """ 订单簿缓存处理序列不连续问题 """ def __init__(self, max_snapshots: int = 5): self.snapshots: deque = deque(maxlen=max_snapshots) self.last_update_id: int = 0 self.pending_updates: List[Dict] = [] def apply_snapshot(self, snapshot: Dict) -> bool: """ 应用初始快照,返回是否成功 重要:必须等待 WebSocket 第一条消息的 lastUpdateId >= 快照的 lastUpdateId """ snapshot_id = snapshot['lastUpdateId'] # 检查是否有待处理的更新 if self.pending_updates: # 过滤掉序列号 <= snapshot_id 的更新 valid_updates = [ u for u in self.pending_updates if u['u'] > snapshot_id ] if not valid_updates: # 所有待处理更新都已在快照中覆盖 self.pending_updates = [] else: # 返回 False,提示需要重新同步 return False self.snapshots.append(snapshot) self.last_update_id = snapshot_id return True def apply_update(self, update: Dict) -> Optional[Dict]: """ 应用增量更新,处理序列号不连续 Returns: 处理后的订单簿状态,如果需要重新同步则返回 None """ update_id = update['u'] first_update_id = update.get('U', 0) # 第一个订单 ID final_update_id = update.get('u', 0) # 最后一个订单 ID # 情况1:更新序列号 < 最后更新的ID,丢弃 if update_id <= self.last_update_id: print(f"丢弃过期更新: {update_id} <= {self.last_update_id}") return None # 情况2:首次更新 ID > 最后更新 ID + 1,说明有间隙 if first_update_id > self.last_update_id + 1: # 需要重新获取快照 print(f"检测到序列间隙: last={self.last_update_id}, first={first_update_id}") self.pending_updates.append(update) return None # 情况3:正常顺序更新 return self._do_apply_update(update) def _do_apply_update(self, update: Dict) -> Dict: """执行更新逻辑""" # 处理买单更新 for price, qty in update.get('b', []): self._update_order('bid', float(price), float(qty)) # 处理卖单更新 for price, qty in update.get('a', []): self._update_order('ask', float(price), float(qty)) self.last_update_id = update['u'] return self.get_current_state()