ContextInfo.get_market_data_ex 是 QMT 内置 Python 中用于获取历史 K 线行情数据的核心函数,支持多品种、多周期、多复权方式的数据查询,返回以证券代码为键、pandas DataFrame 为值的字典。该函数是 get_market_data 的增强版本,提供了更灵活的参数控制和更丰富的返回数据。
QMT get_market_data_ex 函数原型与适用环境
【事实】 函数原型:
ContextInfo.get_market_data_ex(
field_list,
stock_list,
period,
start_time,
end_time,
count,
dividend_type,
fill_data
)
【事实】 适用环境与权限要求:
| 环境 | 是否支持 | 说明 |
|---|---|---|
| 回测环境 | 支持 | 从本地已下载的历史数据中读取 |
| 模拟信号环境 | 支持 | 从本地已下载的历史数据中读取 |
| 仿真交易环境 | 支持 | 从本地已下载的历史数据中读取 |
| 真实交易环境 | 支持 | 从本地已下载的历史数据中读取 |
| 所需权限 | 行情权限 | 需在客户端中开通行情权限并下载对应数据 |
QMT get_market_data_ex 参数详解
field_list — 字段列表
【事实】 field_list 为 list 类型,指定要获取的数据字段。
| 取值 | 含义 |
|---|---|
['time'] |
时间戳 |
['open'] |
开盘价 |
['high'] |
最高价 |
['low'] |
最低价 |
['close'] |
收盘价 |
['volume'] |
成交量 |
['amount'] |
成交额 |
None 或 [] |
获取所有可用字段 |
【建议】 如需获取全部字段,传 None 或空列表即可,无需逐个列出。
stock_list — 证券代码列表
【事实】 stock_list 为 list 类型,指定要查询的证券代码列表,格式为 代码.市场,如 ['600000.SH', '000001.SZ']。
period — 周期
【事实】 period 为 str 类型,指定 K 线周期。
| 值 | 含义 |
|---|---|
'1d' |
日线 |
'1m' |
1 分钟线 |
'5m' |
5 分钟线 |
'15m' |
15 分钟线 |
'30m' |
30 分钟线 |
'60m' |
60 分钟线 |
'tick' |
Tick 数据 |
'1s' |
1 秒线(部分版本支持) |
start_time — 开始时间
【事实】 start_time 为 str 类型,指定数据查询的起始时间。
| 格式 | 示例 | 说明 |
|---|---|---|
YYYYMMDD |
'20240101' |
日期 |
YYYYMMDDHHMMSS |
'20240101093000' |
精确到秒 |
end_time — 结束时间
【事实】 end_time 为 str 类型,指定数据查询的截止时间,格式同 start_time。
count — 数据数量
【事实】 count 为 int 类型,指定要获取的数据条数。设为 -1 表示不限制数量,返回 start_time 到 end_time 之间的所有数据。
【解释】 当 count 为正数时,从 end_time 开始向前取 count 条数据。count 与 start_time/end_time 的优先级以当前客户端版本为准。
dividend_type — 复权方式
【事实】 dividend_type 为 str 类型,指定复权方式。
| 值 | 含义 |
|---|---|
'none' |
不复权 |
'front' |
前复权 |
'back' |
后复权 |
'front_ratio' |
比例前复权 |
'back_ratio' |
比例后复权 |
【建议】 策略回测通常使用前复权('front'),以保证价格序列的连续性。
fill_data — 填充缺失数据
【事实】 fill_data 为 bool 类型,指定是否对缺失数据进行填充。
| 值 | 含义 |
|---|---|
True |
填充缺失数据(停牌期间用前收盘价填充) |
False |
不填充,缺失数据行保留为空 |
QMT get_market_data_ex 返回值说明
【事实】 返回值为 dict 类型,以证券代码为键,以 pandas DataFrame 为值。
【事实】 DataFrame 的列包含 field_list 指定的字段,以及 time 列(时间戳索引)。
【事实】 如果某证券代码无数据,对应的值为空 DataFrame。
返回值结构示例:
{
'600000.SH': DataFrame(
columns=['time', 'open', 'high', 'low', 'close', 'volume', 'amount'],
...
),
'000001.SZ': DataFrame(
columns=['time', 'open', 'high', 'low', 'close', 'volume', 'amount'],
...
)
}
【解释】 DataFrame 的索引为时间戳,可通过 df.index 获取时间序列。每个 DataFrame 的行数取决于 count 和 start_time/end_time 的设置。
QMT get_market_data_ex 示例代码
获取单品种日线数据
# -*- coding: utf-8 -*-
def handlebar(ContextInfo):
if not ContextInfo.is_last_bar():
return
# 获取 600000.SH 最近 20 根日线数据
data = ContextInfo.get_market_data_ex(
field_list=[], # 获取所有字段
stock_list=['600000.SH'], # 证券代码列表
period='1d', # 日线
start_time='', # 不指定开始时间
end_time='', # 不指定结束时间
count=20, # 获取 20 根
dividend_type='front', # 前复权
fill_data=True # 填充缺失数据
)
df = data.get('600000.SH')
if df is not None and len(df) > 0:
print(f'获取到 {len(df)} 根 K 线')
print(df[['time', 'open', 'high', 'low', 'close', 'volume']].tail())
获取多品种分钟数据
def handlebar(ContextInfo):
if not ContextInfo.is_last_bar():
return
# 获取多品种 5 分钟线数据
stocks = ['600000.SH', '000001.SZ', '000002.SZ']
data = ContextInfo.get_market_data_ex(
field_list=['close', 'volume'],
stock_list=stocks,
period='5m',
start_time='20240101',
end_time='20240301',
count=-1, # 不限制数量
dividend_type='front',
fill_data=True
)
for stock in stocks:
df = data.get(stock)
if df is not None and len(df) > 0:
print(f'{stock}: {len(df)} 根 K 线, '
f'最新收盘价: {df["close"].iloc[-1]}')
获取指定时间范围的数据
def handlebar(ContextInfo):
if not ContextInfo.is_last_bar():
return
# 获取 2024 年上半年的日线数据
data = ContextInfo.get_market_data_ex(
field_list=[],
stock_list=['600000.SH'],
period='1d',
start_time='20240101',
end_time='20240630',
count=-1,
dividend_type='front',
fill_data=False
)
df = data.get('600000.SH')
if df is not None and len(df) > 0:
print(f'数据范围: {df.index[0]} ~ {df.index[-1]}')
print(f'数据条数: {len(df)}')
print(f'最高价: {df["high"].max()}')
print(f'最低价: {df["low"].min()}')
print(f'平均成交量: {df["volume"].mean():.0f}')
计算 MA 均线指标
def handlebar(ContextInfo):
if not ContextInfo.is_last_bar():
return
# 获取 60 根日线计算均线
data = ContextInfo.get_market_data_ex(
field_list=['close'],
stock_list=['600000.SH'],
period='1d',
start_time='',
end_time='',
count=60,
dividend_type='front',
fill_data=True
)
df = data.get('600000.SH')
if df is not None and len(df) >= 20:
close = df['close']
ma5 = close.rolling(5).mean()
ma10 = close.rolling(10).mean()
ma20 = close.rolling(20).mean()
print(f'MA5: {ma5.iloc[-1]:.2f}')
print(f'MA10: {ma10.iloc[-1]:.2f}')
print(f'MA20: {ma20.iloc[-1]:.2f}')
# 金叉判断
if ma5.iloc[-1] > ma10.iloc[-1] and ma5.iloc[-2] <= ma10.iloc[-2]:
print('MA5 上穿 MA10,金叉信号')
QMT get_market_data_ex 注意事项
【事实】 使用该函数前需要确保历史数据已下载到本地:
def init(ContextInfo):
# 在策略初始化时下载历史数据
ContextInfo.do_download_history_data('600000.SH', '1d', '20240101', '20240630')
【建议】
1. 获取数据前务必调用 do_download_history_data 确保数据已下载,否则可能返回空 DataFrame
2. fill_data=True 会在停牌期间填充数据,可能影响指标计算的准确性,按需选择
3. 回测环境中数据来源为本地缓存,盘中实时环境中最新一根 Bar 的数据可能尚未更新
4. Tick 周期('tick')数据量较大,建议限制查询时间范围
5. 多品种查询时,不同品种的数据条数可能不同(如上市时间不同),需分别处理
【事实】 回测环境与实盘环境的差异:
| 对比项 | 回测环境 | 实盘环境 |
|---|---|---|
| 数据来源 | 本地已下载的历史数据 | 本地已下载的历史数据 + 实时更新 |
| 最新 Bar | 不含未来数据 | 可能包含未完成的当前 Bar |
| 数据完整性 | 仅包含已下载的数据 | 随行情更新 |
| Tick 数据 | 需提前下载 | 实时推送 |
QMT get_market_data_ex 相关函数
| 函数 | 说明 | 链接 |
|---|---|---|
ContextInfo.get_market_data |
获取市场数据(基础版) | 行情与数据获取 |
ContextInfo.get_history_data |
获取历史数据序列 | 行情与数据获取 |
ContextInfo.do_download_history_data |
下载历史数据 | 行情与数据获取 |
ContextInfo.subscribe_quote |
订阅实时行情 | subscribe_quote |
ContextInfo.get_full_tick |
获取全推 Tick 数据 | get_full_tick |
QMT get_market_data_ex 来源与更新时间
【事实】 本页面内容基于 QMT 官方文档整理。
| 项目 | 值 |
|---|---|
| 数据来源 | QMT 官方文档 |
| 更新时间 | 2026-08-04 |
| 验证时间 | 2026-08-04 |
| 适用版本 | 以当前客户端版本为准 |