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

QMT 平台如何实现 Level-2 盘口买卖单失衡量 (OBI) 高频策略?(附 Python 源码)

qmt | 发布时间: 2026/8/1
以下内容由 EasyQuant 生成。

问题描述

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

Title: QMT 高频交易:基于 Level-2 买卖盘口失衡 (OBI) 的日内择时策略

Question: 请帮我编写一个基于 QMT Level-2 盘口买卖单失衡量的日内高频策略

解决方案

QMT 高频交易:基于 Level-2 买卖盘口失衡 (OBI) 的日内择时策略

在日内高频量化交易中,订单簿微观结构(Market Microstructure)包含着极其丰富的微观价格走势信息。**订单簿失衡量(Order Book Imbalance, OBI)**是衡量买卖双方即时力量对比的关键指标。

借助 QMT 平台的 Level-2 行情订阅接口ContextInfo.get_full_tick(),我们可以轻松抓取盘口五档买卖量,实时计算 OBI 指标,并捕捉短期的价格推升或下压趋势。


一、OBI 核心原理

订单簿失衡量(OBI)定义为买方委托总量与卖方委托总量之差占总委托量的比例:

$$OBI = \frac{\sum_{i=1}^{5} BidVol_i - \sum_{i=1}^{5} AskVol_i}{\sum_{i=1}^{5} BidVol_i + \sum_{i=1}^{5} AskVol_i}$$

  • $OBI > 0.3$:表明买盘积极,短期内价格向上微动概率增大;
  • $OBI < -0.3$:表明卖压沉重,短期内价格向下微动概率增大。

二、QMT Python 策略实现源码

以下是基于 QMT Python API 编写的 OBI 高频日内策略源码:

#encoding:gbk
import numpy as np

def init(ContextInfo):
    # 1. 设置交易标的与资金账号
    ContextInfo.stock = '600000.SH'
    ContextInfo.set_universe([ContextInfo.stock])
    ContextInfo.account = '6000000248'
    ContextInfo.set_account(ContextInfo.account)
    
    # 2. 策略参数设置
    ContextInfo.trade_lots = 100        # 单笔交易股数
    ContextInfo.obi_threshold = 0.35    # OBI 触发阈值
    ContextInfo.holding = 0            # 当前持仓标记
    
    # 3. 订阅行情
    ContextInfo.subscribe_quote(ContextInfo.stock, period='tick', dividend_type='none')
    print("OBI 高频策略初始化完成!")

def handlebar(ContextInfo):
    # 仅在最新 Tick 变动时触发计算
    if not ContextInfo.is_last_bar():
        return
    
    # 获取当前最新分笔五档行情
    tick_data = ContextInfo.get_full_tick([ContextInfo.stock])
    if ContextInfo.stock not in tick_data:
        return
        
    data = tick_data[ContextInfo.stock]
    ask_vols = data.get('askVol', [])
    bid_vols = data.get('bidVol', [])
    
    if len(ask_vols) < 5 or len(bid_vols) < 5:
        return
        
    # 1. 计算买卖五档总量与 OBI 指标
    total_bid_vol = sum(bid_vols[:5])
    total_ask_vol = sum(ask_vols[:5])
    total_vol = total_bid_vol + total_ask_vol
    
    if total_vol == 0:
        return
        
    obi = (total_bid_vol - total_ask_vol) / total_vol
    current_price = data.get('lastPrice', 0)
    
    # 2. 信号判定与下单逻辑
    # 买入信号:OBI 超出上限且当前空仓
    if obi > ContextInfo.obi_threshold and ContextInfo.holding == 0:
        print(f"【信号】买盘强劲 (OBI={obi:.2f}),最新价: {current_price},执行买入")
        # 23: 股票买入 | 1101: 单股单账号股数下单 | 5: 最新价 | quickTrade=1 快速下单
        passorder(23, 1101, ContextInfo.account, ContextInfo.stock, 5, -1, ContextInfo.trade_lots, 'OBI_Strategy', 1, ContextInfo)
        ContextInfo.holding = ContextInfo.trade_lots
        
    # 卖出/平仓信号:OBI 跌破下限且持有仓位
    elif obi < -ContextInfo.obi_threshold and ContextInfo.holding > 0:
        print(f"【信号】卖压显现 (OBI={obi:.2f}),最新价: {current_price},执行平仓")
        passorder(24, 1101, ContextInfo.account, ContextInfo.stock, 5, -1, ContextInfo.trade_lots, 'OBI_Strategy', 1, ContextInfo)
        ContextInfo.holding = 0

三、策略要点与 QMT API 避坑指南

  1. get_full_tick 的全量调用:获得五档买卖量(bidVol, askVol)必须使用 get_full_tick(),标准 K 线行情数据不包含实时盘口量。
  2. 即时下单执行(quickTrade=1:在盘口微观高频交易中,传统逐 Bar 结算机制延迟较高,因此调用 passorder 时需设置 quickTrade=1 实现即时发出信号并下单。
  3. Level-2 强化与扩展:若开启 QMT Level-2 增强版权限,可使用 period='l2quoteaux' 订阅获取更精细的委托买卖均价及撤单量(如 avgBidPricewithdrawBidQuantity),进一步提高 OBI 信号预测准确率。