12、盘口深度变化率:深度变化率的计算,深度变化与价格突破,Python实现深度变化率指标

盘口深度,说白了就是挂在买卖盘上的单子厚度。

很多人看盘只看价格涨跌,忽略了深度变化。我个人习惯把深度变化率当作「资金温度计」——它能告诉你,当前的价格波动背后,到底有多少真金白银在支撑。

12.1 深度变化率的计算逻辑

深度变化率,衡量的是某一档位挂单量随时间的变化速度。

公式其实很简单:

深度变化率 = (当前时刻挂单量 - 上一时刻挂单量) / 上一时刻挂单量 × 100%

但实际应用中,我建议分两层计算:

  • 单档深度变化率:盯着买一、卖一这些关键档位
  • 累积深度变化率:把买一到买五(或更深)的挂单量加起来算

为什么要分两层?

嗯,我在实盘中发现一个现象:有时候买一挂单突然减少,但买二到买五却在增加。单看买一你会觉得「有人在撤单,要跌」,但累积深度却在上升——这其实是主力在「假撤真吸筹」。单档和累积结合起来看,才能避免被误导。

核心要点: 深度变化率 > 0 表示资金在流入该方向,< 0 表示资金在流出。 但要注意,这个「资金」可能是挂单,不一定是成交。

12.2 深度变化与价格突破的关系

我做了大量回测后发现一个规律:

  • 深度积累 → 价格突破:当买盘深度持续增加,卖盘深度持续减少,价格往往会在某个临界点向上突破
  • 深度衰减 → 假突破:价格冲高但买盘深度却在下降,这种突破大概率是假的

为什么会这样?

你想想看,如果真有大资金要拉升,它会在买盘上挂大量托单。这些托单就是「护城河」。护城河越宽,价格越稳。反之,如果价格涨了但护城河在变窄,说明主力在边拉边撤——这就是典型的诱多。

我的经验: 当深度变化率连续3个周期 > 5%,且价格处于关键支撑/阻力位附近时,突破概率会显著提升。 我一般会在这个位置提前布局。

12.3 Python实现深度变化率指标

代码实现上,我习惯用pandas来处理时间序列数据。下面是一个完整的实现:

import pandas as pd
import numpy as np
from typing import Dict, List

class DepthChangeRate:
    """
    盘口深度变化率计算器
    支持单档和累积两种模式
    """
    
    def __init__(self, window: int = 3):
        """
        :param window: 计算变化率的时间窗口(周期数)
        """
        self.window = window
        self.depth_history = []  # 存储历史深度数据
        
    def add_snapshot(self, bid_depth: Dict[str, float], 
                     ask_depth: Dict[str, float]) -> None:
        """
        添加一个快照数据
        :param bid_depth: 买盘深度,格式 {'买一': 100.0, '买二': 200.0, ...}
        :param ask_depth: 卖盘深度,格式 {'卖一': 150.0, '卖二': 250.0, ...}
        """
        snapshot = {
            'bid_total': sum(bid_depth.values()),
            'ask_total': sum(ask_depth.values()),
            'bid_level1': bid_depth.get('买一', 0),
            'ask_level1': ask_depth.get('卖一', 0),
            'timestamp': pd.Timestamp.now()
        }
        self.depth_history.append(snapshot)
        
        # 只保留最近 window+1 个数据
        if len(self.depth_history) > self.window + 1:
            self.depth_history.pop(0)
    
    def calculate_change_rate(self) -> Dict[str, float]:
        """
        计算深度变化率
        :return: 包含各维度变化率的字典
        """
        if len(self.depth_history) < 2:
            return {}
        
        current = self.depth_history[-1]
        previous = self.depth_history[0]  # window 个周期前的数据
        
        # 计算变化率
        bid_total_rate = (current['bid_total'] - previous['bid_total']) / \
                         previous['bid_total'] * 100 if previous['bid_total'] != 0 else 0
        
        ask_total_rate = (current['ask_total'] - previous['ask_total']) / \
                         previous['ask_total'] * 100 if previous['ask_total'] != 0 else 0
        
        bid_level1_rate = (current['bid_level1'] - previous['bid_level1']) / \
                          previous['bid_level1'] * 100 if previous['bid_level1'] != 0 else 0
        
        ask_level1_rate = (current['ask_level1'] - previous['ask_level1']) / \
                          previous['ask_level1'] * 100 if previous['ask_level1'] != 0 else 0
        
        return {
            'bid_total_rate': round(bid_total_rate, 2),
            'ask_total_rate': round(ask_total_rate, 2),
            'bid_level1_rate': round(bid_level1_rate, 2),
            'ask_level1_rate': round(ask_level1_rate, 2),
            'depth_imbalance': round(bid_total_rate - ask_total_rate, 2)
        }
    
    def detect_breakout_signal(self) -> str:
        """
        检测突破信号
        :return: 'up', 'down', 'neutral'
        """
        rates = self.calculate_change_rate()
        if not rates:
            return 'neutral'
        
        # 买盘深度增加 + 卖盘深度减少 = 向上突破信号
        if (rates['bid_total_rate'] > 5 and 
            rates['ask_total_rate'] < -3):
            return 'up'
        
        # 卖盘深度增加 + 买盘深度减少 = 向下突破信号
        if (rates['ask_total_rate'] > 5 and 
            rates['bid_total_rate'] < -3):
            return 'down'
        
        return 'neutral'


# 使用示例
if __name__ == '__main__':
    dcr = DepthChangeRate(window=3)
    
    # 模拟数据
    snapshots = [
        ({'买一': 100, '买二': 200}, {'卖一': 150, '卖二': 250}),
        ({'买一': 120, '买二': 220}, {'卖一': 140, '卖二': 240}),
        ({'买一': 150, '买二': 250}, {'卖一': 130, '卖二': 230}),
        ({'买一': 180, '买二': 280}, {'卖一': 120, '卖二': 220}),
    ]
    
    for bid, ask in snapshots:
        dcr.add_snapshot(bid, ask)
    
    print("深度变化率:", dcr.calculate_change_rate())
    print("突破信号:", dcr.detect_breakout_signal())
避坑指南: 我曾经在实盘中发现,某些交易所的深度数据更新频率不一致。 有的100ms推送一次,有的500ms。如果直接用原始数据计算变化率,结果会失真。 我的做法是:先对深度数据进行时间对齐,统一到相同的时间间隔再计算。

12.4 深度变化率的可视化

光看数字不够直观。我习惯把深度变化率画成曲线,和价格走势叠加在一起看。

import matplotlib.pyplot as plt

def plot_depth_change_rate(depth_rates: List[Dict], prices: List[float]):
    """
    绘制深度变化率与价格对比图
    """
    fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(12, 8))
    
    # 提取数据
    timestamps = [r['timestamp'] for r in depth_rates]
    bid_rates = [r['bid_total_rate'] for r in depth_rates]
    ask_rates = [r['ask_total_rate'] for r in depth_rates]
    
    # 上子图:深度变化率
    ax1.plot(timestamps, bid_rates, label='买盘深度变化率', color='green')
    ax1.plot(timestamps, ask_rates, label='卖盘深度变化率', color='red')
    ax1.axhline(y=0, color='gray', linestyle='--')
    ax1.set_ylabel('变化率 (%)')
    ax1.legend()
    ax1.set_title('盘口深度变化率')
    
    # 下子图:价格
    ax2.plot(timestamps, prices, label='价格', color='blue')
    ax2.set_ylabel('价格')
    ax2.legend()
    ax2.set_title('价格走势')
    
    plt.tight_layout()
    plt.show()

这张图能帮你一眼看出:价格突破时,深度变化率是否在配合。如果价格创新高但买盘深度变化率在下降——嗯,小心了。

12.5 核心知识体系

我把本章的核心逻辑画成了一张图,方便你理解:

盘口深度变化率核心逻辑 原始深度数据 深度变化率计算 突破信号 单档深度变化率 关注买一/卖一 敏感但易被操纵 累积深度变化率 关注买一到买五总和 更稳定,反映真实意图 深度不平衡率 买盘变化率 - 卖盘变化率 正值偏多,负值偏空 核心结论 深度积累 → 价格突破 | 深度衰减 → 假突破

这张图把整个流程串起来了:从原始深度数据出发,经过单档和累积两种计算方式,最终输出突破信号。记住,深度变化率不是孤立指标,它需要和价格走势配合使用。

实战建议: 我个人习惯把深度变化率阈值设为 ±5%。超过这个范围,说明资金态度发生了明显变化。 如果同时配合成交量放大,那基本就是一波行情的起点。

无相订单流研究社 微信Lucian808555