🚀 AI 一键生成 ptrade 策略代码
立即体验

ptrade Level-2 高频策略:解析买卖五档委托量构建盘口压力指标(OFI)

ptrade | 发布时间: 2026/7/26
以下内容由 EasyQuant 生成。

问题描述

请根据以下 SEO 主题生成完整页面内容:

Title: ptrade Level-2 高频策略:基于买卖盘口委托量不平衡(OFI)的微观结构交易

Question: 如何在 ptrade 中利用 get_snapshot 或 get_gear_price 解析买卖五档委托量并构建盘口压力指标?

解决方案

ptrade Level-2 高频策略:基于买卖盘口委托量不平衡(OFI)的微观结构交易

在微观结构高频交易中,买卖盘口(Order Book)的实时动态蕴含着短期价格走势的关键信号。订单流不平衡(Order Flow Imbalance, OFI)及盘口压力指标是评估买卖双方力量对比的核心工具。本文将详细介绍如何在 ptrade 平台中利用 get_snapshotget_gear_price API 获取并解析买卖五档委托量,构建微观盘口压力指标,并实现自动下单。


1. 核心接口与数据结构解析

ptrade 提供了多种获取实盘盘口数据的函数,其中最常用于 Level-2 盘口分析的是 get_snapshotget_gear_price

1.1 get_snapshot(security)

获取指定标的的实时行情快照,返回一个字典。在开通 Level-2 权限后,其 bid_grp(委买档位)和 offer_grp(委卖档位)包含多档委托价格、委托量以及第一档的委托队列。

  • 结构示例:
    {
        '600570.SS': {
            'last_px': 41.89,
            'bid_grp': {
                1: [41.88, 1200, 10, {1: 200, 2: 1000}], # [价格, 委托总量, 委托笔数, 委托明细队列]
                2: [41.87, 2300, 5],
                ...
            },
            'offer_grp': {
                1: [41.89, 4400, 8, {}],
                ...
            }
        }
    }
    

1.2 get_gear_price(sids)

专门用于高效获取指定代码的档位行情价格与委托量。

  • 结构示例:
    {
        'bid_grp': {1: [价格, 委托量, 委托笔数], 2: [价格, 委托量, 委托笔数], ...},
        'offer_grp': {1: [价格, 委托量, 委托笔数], 2: [价格, 委托量, 委托笔数], ...}
    }
    

2. 盘口压力指标(OFI/Order Book Imbalance)计算原理

简化的多档盘口不平衡加权指标计算公式如下:

$$\text{Pressure Ratio} = \frac{\sum_{i=1}^{N} w_i \cdot V_{\text{bid}, i} - \sum_{i=1}^{N} w_i \cdot V_{\text{offer}, i}}{\sum_{i=1}^{N} w_i \cdot V_{\text{bid}, i} + \sum_{i=1}^{N} w_i \cdot V_{\text{offer}, i}}$$

其中:

  • $V_{\text{bid}, i}$、$V_{\text{offer}, i}$ 分别为第 $i$ 档的买量和卖量。
  • $w_i$ 为衰减权重(离最新价越近权重越高,如 $w_i = \frac{1}{i}$)。
  • 指标区间为 $[-1, 1]$:越接近 $1$ 说明买盘支撑极强,价格短期趋于上涨;越接近 $-1$ 说明卖压极大,价格容易下跌。

3. ptrade 策略实现源码

以下策略在 tick_data(3秒触发周期)或 run_interval 定时任务中运行,实时解析 Level-2 盘口压力并进行高频下单。

import numpy as np

def initialize(context):
    g.security = '600570.SS'
    set_universe(g.security)
    # 交易场景可设置开启 Level-2 参数校验
    set_parameters(tick_data_no_l2="0")

def tick_data(context, data):
    security = g.security
    
    # 1. 获取最新 Level-2 快照
    snapshot = get_snapshot(security)
    if not snapshot or security not in snapshot:
        return
    
    sec_data = snapshot[security]
    bid_grp = sec_data.get('bid_grp', {})
    offer_grp = sec_data.get('offer_grp', {})
    
    if not bid_grp or not offer_grp:
        return
    
    # 2. 计算五档加权盘口压力
    weighted_bid_vol = 0.0
    weighted_offer_vol = 0.0
    
    for level in range(1, 6):
        # 离盘口越近,权重越高 (1.0, 0.5, 0.33, 0.25, 0.20)
        weight = 1.0 / level
        
        if level in bid_grp:
            bid_vol = bid_grp[level][1]  # 索引1为委托量
            weighted_bid_vol += bid_vol * weight
            
        if level in offer_grp:
            offer_vol = offer_grp[level][1]
            weighted_offer_vol += offer_vol * weight
            
    total_vol = weighted_bid_vol + weighted_offer_vol
    if total_vol == 0:
        return
        
    # 计算不平衡指标 (-1 到 1)
    pressure_index = (weighted_bid_vol - weighted_offer_vol) / total_vol
    
    # 3. 交易信号判断与执行
    current_price = sec_data.get('last_px', 0)
    position = get_position(security).amount
    
    # 当买盘压力极大 (指标 > 0.6) 且空仓时买入
    if pressure_index > 0.6 and position == 0:
        log.info(f"[高频信号] 盘口买压显著,指标值: {pressure_index:.2f},买一档下单")
        # 使用 order_tick 按买一档价格下单
        order_tick(security, 100, priceGear='1')
        
    # 当卖盘压力极大 (指标 < -0.6) 且有持仓时卖出
    elif pressure_index < -0.6 and position > 0:
        log.info(f"[高频信号] 盘口卖压显著,指标值: {pressure_index:.2f},卖一档下单")
        order_tick(security, -position, priceGear='-1')

def handle_data(context, data):
    pass

4. 实盘部署注意事项

  1. 数据准确性校验:盘前集合竞价期间(9:15-9:25),get_snapshot 返回的部分字段(如成交量、最新价)可能为 0,需增加判断保护。
  2. 限价单精度处理:若直接传入 limit_price 委托,股票价格需保留 2位小数,可转债/ETF 保留 3位小数,避免柜台废单。
  3. 撤单与挂单管理:高频策略应配合 get_open_orders()cancel_order() 定期清理长期未成交的挂单,防止资金冻结。