🚀 AI 一键生成 qmt 策略代码

QMT 高频因子:如何利用 Level-2 数据统计大单资金流向?

qmt | 发布时间: 2025/12/20
以下内容由 EasyQuant 生成。

问题描述

如何获取 Level-2 的逐笔大单统计数据?

解决方案

在 QMT 中,获取 Level-2 的逐笔大单统计数据主要通过设置周期参数 period'l2transactioncount' 来实现。

这可以通过两种方式完成:

  1. 使用 get_market_data_ex 主动获取历史或当前数据。
  2. 使用 subscribe_quote 订阅实时推送数据。

注意:使用此功能通常需要您的资金账号开通了 Level-2 行情权限,且在客户端“数据管理”中下载了相应数据(如果是回测)。

以下是具体的实现代码和说明。

方法一:主动获取数据 (get_market_data_ex)

这种方法适用于在策略的 handlebar 周期内获取最近的大单统计数据。

# -*- coding: gbk -*-

def init(ContextInfo):
    # 设置股票池,这里以贵州茅台为例
    ContextInfo.set_universe(['600519.SH'])

def handlebar(ContextInfo):
    # 仅在最后一根K线(实时行情或回测结束点)运行,避免历史回测时重复打印
    if not ContextInfo.is_last_bar():
        return

    # 获取当前股票池中的股票代码
    stock_list = ContextInfo.get_universe()
    
    # 调用 get_market_data_ex 获取 Level-2 逐笔成交统计
    # period 参数必须设置为 'l2transactioncount'
    # count 设置为 -1 表示获取所有可用数据,或者设置为具体数值如 10 获取最近 10 条
    l2_data = ContextInfo.get_market_data_ex(
        fields=[],  # 传空列表代表获取所有字段
        stock_code=stock_list,
        period='l2transactioncount',
        count=5,   # 获取最近5条记录
        dividend_type='none'
    )

    # 打印获取到的数据
    for code, df in l2_data.items():
        print(f"====== {code} Level-2 大单统计数据 ======")
        if not df.empty:
            # 打印最后一条数据(最新时刻)
            print(df.tail(1))
            
            # 示例:访问特定字段,如大单动向(ddx)和资金博弈净流入(zjbyNetInflow)
            # 注意:字段名区分大小写,具体字段请参考文档附录
            last_row = df.iloc[-1]
            print(f"时间: {last_row.name}")
            print(f"大单动向(ddx): {last_row.get('ddx', 'N/A')}")
            print(f"资金博弈净流入: {last_row.get('zjbyNetInflow', 'N/A')}")
        else:
            print("无数据 (请确认是否拥有L2权限或已下载数据)")

方法二:实时订阅推送 (subscribe_quote)

这种方法适用于实盘交易,当有新的 Level-2 统计数据生成时,会立即触发回调函数。

# -*- coding: gbk -*-

def on_l2_data(datas):
    """
    Level-2 数据推送回调函数
    datas: {code: dataframe} 结构
    """
    for code, df in datas.items():
        print(f"收到 {code} 的 Level-2 推送:")
        # 打印最新的一行数据
        print(df.tail(1))
        
        # 可以在这里编写基于 L2 数据的实时逻辑
        # 例如监控主力资金流入
        if not df.empty:
            net_inflow = df.iloc[-1]['zjbyNetInflow']
            print(f"当前资金净流入: {net_inflow}")

def init(ContextInfo):
    # 订阅浦发银行的 Level-2 逐笔成交统计
    # period='l2transactioncount' 是关键
    ContextInfo.subscribe_quote(
        '600000.SH', 
        period='l2transactioncount', 
        callback=on_l2_data
    )
    print("已发起 Level-2 数据订阅...")

def handlebar(ContextInfo):
    # 实时模式下,主要逻辑在回调函数中处理,这里可以留空
    pass

数据字段说明

获取到的 DataFrame 包含丰富的统计字段,以下是一些核心字段的含义(完整列表请参考 QMT API 文档附录 6.6.2):

  • 资金流向类:
    • zjbyNetInflow: 资金博弈净流入
    • zjbyMost: 超大单流入
    • zjbyBig: 大单流入
    • zjbyMedium: 中单流入
    • zjbySmall: 小单流入
  • 指标类:
    • ddx: 大单动向
    • ddy: 涨跌动因
    • ddz: 大单差分
  • 成交统计类:
    • bidNumber: 主买单总单数
    • offNumber: 主卖单总单数
    • bidBigVolmue: 主买大单成交量
    • offBigVolmue: 主卖大单成交量

常见问题排查

  1. 返回数据为空
    • 请检查账号是否购买了 Level-2 行情服务。
    • 如果是回测或获取历史数据,请确保在 QMT 客户端的【数据管理】中下载了对应时间段的“Level2数据”。
    • 检查 period 拼写是否严格为 'l2transactioncount'
  2. 字段报错
    • Level-2 数据的字段名通常是驼峰命名法(如 zjbyNetInflow),请确保大小写完全一致。

Q&A

Q: 如何判断我是否有 Level-2 数据权限?
A: 您可以在 QMT 客户端的行情界面查看个股,如果能看到十档行情(买一到买十),通常意味着您拥有 Level-2 权限。如果只能看到五档,则无法获取 l2transactioncount 数据。

Q: l2transactioncount 数据的更新频率是多少?
A: 这取决于交易所的推送频率,通常是快照级别的统计,大约每 3 秒更新一次(与 Level-2 快照同步)。

Q: 回测模式下可以使用 Level-2 数据吗?
A: 可以,但必须提前下载历史 Level-2 数据。由于 L2 数据量巨大,下载耗时较长,建议只下载所需品种和时间段的数据。