问题描述
解决方案
在 QMT (Quantitative Trading Platform) 中,获取多只股票的最新五档盘口(Order Book)和分笔成交快照(Tick Snapshot),主要使用 ContextInfo.get_full_tick() 接口。
该接口可以一次性返回多只股票的最新 Tick 数据,包含买卖五档价格与挂单量、最新成交价、成交量等信息。
核心代码实现
以下是一个完整的策略示例,展示如何在 handlebar 周期内获取并打印多只股票的详细盘口数据。
# -*- coding: gbk -*-
def init(ContextInfo):
# 1. 在初始化函数中定义需要获取数据的股票列表
# 格式为 '代码.市场',例如 '600000.SH' (浦发银行), '000001.SZ' (平安银行)
ContextInfo.stock_list = ['600000.SH', '000001.SZ', '600519.SH']
# 设置定时器或运行周期,这里仅作演示,实际运行时通常由行情驱动
print("策略初始化完成,准备获取Tick数据...")
def handlebar(ContextInfo):
# 2. 判断是否为最后一根K线(实时行情模式下只在最新时刻获取)
if not ContextInfo.is_last_bar():
return
# 3. 调用 get_full_tick 获取多只股票的最新分笔数据
# 返回值是一个字典,Key是股票代码,Value是包含详细数据的字典
tick_data_map = ContextInfo.get_full_tick(ContextInfo.stock_list)
# 4. 遍历并解析数据
for stock_code in ContextInfo.stock_list:
if stock_code in tick_data_map:
data = tick_data_map[stock_code]
# --- 解析基础成交数据 ---
last_price = data.get('lastPrice') # 最新价
total_vol = data.get('volume') # 成交总量(股/份)
total_amount = data.get('amount') # 成交总额(元)
open_int = data.get('openInt') # 持仓量(期货常用)
# --- 解析五档盘口数据 ---
# askPrice/bidPrice 为列表,索引0对应卖一/买一,索引4对应卖五/买五
ask_prices = data.get('askPrice', []) # 卖价五档列表
ask_vols = data.get('askVol', []) # 卖量五档列表
bid_prices = data.get('bidPrice', []) # 买价五档列表
bid_vols = data.get('bidVol', []) # 买量五档列表
# --- 打印输出 ---
print("=" * 40)
print(f"股票: {stock_code} | 最新价: {last_price}")
# 打印卖一到卖五 (倒序打印模拟盘口形状)
if len(ask_prices) >= 5:
for i in range(4, -1, -1):
print(f"卖{i+1}: {ask_prices[i]:.2f} | 量: {ask_vols[i]}")
print("-" * 20)
# 打印买一到买五
if len(bid_prices) >= 5:
for i in range(0, 5):
print(f"买{i+1}: {bid_prices[i]:.2f} | 量: {bid_vols[i]}")
print(f"总成交量: {total_vol} | 总成交额: {total_amount}")
数据结构详解
ContextInfo.get_full_tick(stock_list) 返回的字典结构如下(以单只股票为例):
| 字段 Key | 类型 | 说明 |
|---|---|---|
lastPrice |
number | 最新成交价 |
volume |
number | 成交总量(注意:股票单位通常为股,部分接口可能为手,需实测确认) |
amount |
number | 成交总金额 |
askPrice |
list | 卖价五档,[卖1价, 卖2价, ..., 卖5价] |
bidPrice |
list | 买价五档,[买1价, 买2价, ..., 买5价] |
askVol |
list | 卖量五档,对应卖价的挂单量 |
bidVol |
list | 买量五档,对应买价的挂单量 |
lastClose |
number | 昨收盘价 |
open |
number | 今日开盘价 |
high |
number | 今日最高价 |
low |
number | 今日最低价 |
stockStatus |
number | 股票状态(如停牌等) |
注意事项
- 实时性:
get_full_tick获取的是调用时刻的最新快照。在实盘模式下,handlebar会随行情 Tick 推送触发(如果订阅了全推),或者随主图 K 线更新触发。 - 数据订阅:在实盘运行时,为了保证
handlebar能及时响应非主图品种的 Tick 更新,建议配合ContextInfo.subscribe_quote(stock_code, period='tick')使用,但这通常用于事件驱动的回调模式。上述代码在handlebar中主动查询适用于轮询逻辑。 - 历史回测:在回测模式下,
get_full_tick返回的是回测时间点对应的历史分笔快照(前提是本地下载了 Tick 数据)。如果没有 Tick 数据,回测可能无法获取五档盘口。 - Level-2 数据:如果您的账号开通了 Level-2 权限,QMT 还提供了
get_market_data_ex配合period='l2quoteaux'等参数获取更深度的行情(如十档盘口、逐笔委托等),但标准五档盘口使用get_full_tick即可。
Q&A
Q: get_full_tick 和 get_market_data 有什么区别?
A: get_full_tick 专门用于获取最新的 Tick 快照,包含完整的五档盘口信息,返回格式是字典,读取方便。get_market_data (或 get_market_data_ex) 更通用,可以获取历史序列数据(DataFrame格式),虽然也能获取 Tick,但在获取最新盘口快照时,get_full_tick 效率更高且字段解析更直接。
Q: 如何获取历史的五档盘口数据进行回测?
A: 需要使用 ContextInfo.get_market_data_ex,设置 period='tick',并确保本地已经下载了对应时间段的 Tick 数据。返回的 DataFrame 中会包含 askPrice1...askPrice5 等列。
Q: 为什么获取到的 askPrice 列表是空的?
A: 这通常发生在以下情况:1. 股票停牌;2. 处于非交易时间段且无缓存数据;3. 输入的股票代码格式错误(如忘记加后缀 .SH 或 .SZ)。