问题描述
解决方案
在 QMT (Quantitative Master Trading) 平台中,如果您希望读取本地存储的行情数据来进行策略回测或研究,主要使用的 API 接口是 ContextInfo.get_local_data。
这个接口允许您直接访问客户端已经下载到本地硬盘的历史行情数据,而不需要实时向服务器请求。这对于需要大量历史数据进行统计分析或在 init 阶段预加载数据的策略非常有用。
核心步骤
-
数据准备(必须步骤):
在使用此函数之前,您必须在 QMT 客户端界面中,点击菜单栏的 【数据管理】 -> 【补充数据】,下载您需要回测的品种和时间段的历史数据。如果本地没有数据,该接口将返回空值。 -
使用
ContextInfo.get_local_data:
该函数通常在init(ContextInfo)中调用,用于一次性获取一段历史数据。
代码实现
以下是一个完整的 Python 策略示例,展示了如何读取本地存储的浦发银行(600000.SH)日线数据,并将其转换为 Pandas DataFrame 格式以便于分析。
# -*- coding: gbk -*-
import pandas as pd
import time
def init(ContextInfo):
"""
初始化函数,策略运行时调用一次
在此处演示如何读取本地数据
"""
print("正在读取本地数据...")
# 1. 设置参数
target_stock = '600000.SH' # 目标股票
start_date = '20230101' # 开始时间 (格式 YYYYMMDD)
end_date = '20231231' # 结束时间 (格式 YYYYMMDD)
period = '1d' # 周期: '1d'日线, '1m'1分钟, 'tick'分笔等
dividend_type = 'front' # 复权方式: 'none'不复权, 'front'前复权, 'back'后复权
# 2. 调用 get_local_data 获取本地数据
# 注意:必须先在客户端【数据管理】中下载对应品种和周期的数据,否则返回为空
local_data_dict = ContextInfo.get_local_data(
stock_code=target_stock,
start_time=start_date,
end_time=end_date,
period=period,
divid_type=dividend_type,
count=-1 # -1 表示获取指定时间段内的所有数据
)
# 3. 数据处理
if local_data_dict:
# 将返回的字典转换为 Pandas DataFrame
# get_local_data 返回格式: {timetag: {open:.., high:.., ...}, ...}
df = pd.DataFrame.from_dict(local_data_dict, orient='index')
# 数据清洗与排序
# 索引是时间戳(毫秒),转换为可读日期格式
df.index.name = 'timetag'
df['datetime'] = pd.to_datetime(df.index, unit='ms') + pd.Timedelta(hours=8) # 调整时区显示
df = df.sort_index() # 按时间排序
# 打印结果查看
print(f"成功获取 {target_stock} 本地数据,共 {len(df)} 条记录。")
print("-" * 30)
print(df[['datetime', 'open', 'high', 'low', 'close', 'volume']].head())
print("-" * 30)
# 在这里可以编写您的向量化回测逻辑
# 例如:计算均线
df['MA5'] = df['close'].rolling(window=5).mean()
print("计算 MA5 均线示例:")
print(df[['datetime', 'close', 'MA5']].tail())
else:
print(f"未获取到 {target_stock} 的本地数据。")
print("请检查:1. 是否在【数据管理】中下载了该品种的历史数据;2. 时间区间是否正确。")
def handlebar(ContextInfo):
"""
行情驱动函数
如果只是做基于本地数据的静态分析,此函数可以留空
"""
pass
函数详解:ContextInfo.get_local_data
- stock_code: 合约代码,如
'600000.SH'。 - start_time: 开始时间,格式
'YYYYMMDD'或'YYYYMMDDHHMMSS'。 - end_time: 结束时间,格式同上。
- period: 周期类型,支持
'tick'(分笔),'1d'(日线),'1m'(1分钟) 等。 - divid_type: 复权方式,
'none'(不复权),'front'(前复权),'back'(后复权)。 - count: 获取条数。设为
-1时,配合start_time和end_time获取区间内所有数据;若大于 0,则以end_time为基准向前取count条。
注意事项
- 数据依赖:
get_local_data完全依赖本地文件。如果您的 QMT 客户端是新安装的或者从未下载过数据,该函数将无法返回数据。 - Tick 数据:如果您将
period设置为'tick',返回的字段会包含买卖五档盘口(askPrice,bidPrice等),数据量较大,读取速度可能会受硬盘性能影响。 - 与
get_market_data的区别:get_local_data:只读本地,速度极快,适合历史回测、盘前分析、AI模型训练数据加载。get_market_data_ex/get_market_data:可从服务器请求缺失数据,适合实盘中获取最新行情。
Q&A
Q: 为什么我运行代码后提示“未获取到本地数据”?
A: 这通常是因为本地没有对应品种的历史数据文件。请在 QMT 客户端顶部菜单栏找到“数据管理”,选择对应的市场(如沪深A股)、周期(如日线),勾选您需要的股票并点击“下载”或“补充数据”。
Q: get_local_data 返回的数据字典里的 Key 是什么?
A: 返回字典的 Key 是时间戳(Timetag),单位是毫秒。在 Python 中可以使用 pandas.to_datetime(index, unit='ms') 将其转换为可读的日期时间格式。
Q: 这个接口支持回测期货数据吗?
A: 支持。只要您在数据管理中下载了期货合约(如 IF00.IF 或 rb2310.SF)的数据,就可以通过此接口读取。注意期货代码后缀(如 .IF, .SF)。