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

QMT 离线数据管理:如何使用 get_local_data 加快策略回测速度?

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

问题描述

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

Title: qmt 离线数据管理:使用 get_local_data 加快策略回测速度

Question: qmt 如何利用本地行情数据进行离线回测以提升计算效率?

解决方案

QMT 离线数据管理:使用 get_local_data 加快策略回测速度

在量化策略开发与验证过程中,策略回测的执行速度直接影响研发迭代效率。网络请求延迟与频繁的实时数据订阅往往是拖慢回测速度的主要瓶颈。通过 QMT(迅投量化交易系统)平台的离线数据管理功能,配合 ContextInfo.get_local_data API 接口,投资者可以直接读取已补充到本地的高清行情数据,实现高效、稳定的纯离线高速回测。


1. 为什么使用本地数据做离线回测?

  1. 极速读取:避开了基于 API 网络请求的数据传输开销,直接从本地存储读取历史 Bar 或 Tick 数据。
  2. 降低系统开销:在回测过程中关闭动态数据订阅(subscribe=False),避免多标的推流带来的内存与 CPU 计算资源占用。
  3. 稳定可复现:不受网络波动影响,保证不同时间运行回测结果完全一致。

2. 准备工作:在 QMT 客户端补充本地数据

在使用 get_local_data 前,必须先将所需标的与周期的历史数据下载补充至本地:

  1. 打开 QMT 客户端,进入菜单栏的 【数据管理】(或【操作】->【数据管理】)。
  2. 选择需要回测的市场(如沪深 A 股、期货等)、品种以及对应的周期(如日线、1分钟线、Tick分笔数据)。
  3. 设置时间范围并点击 【补充数据】,等待历史数据下载完成。

3. ContextInfo.get_local_data 接口详解

3.1 接口定义与参数说明

ContextInfo.get_local_data(stock_code, start_time='', end_time='', period='1d', divid_type='none', count=-1)
  • stock_code: 合约代码,如 '600000.SH'。缺省时默认为当前主图代码。
  • start_time / end_time: 开始与结束时间,格式为 'YYYYMMDD''YYYYMMDDhhmmss'
  • period: K 线周期,可选值包括:
    • 'tick':分笔数据
    • '1m', '5m', '15m', '30m':分钟线
    • '1d':日线
  • divid_type: 除复权处理,可选 'none'(不复权)、'front'(前复权)、'back'(后复权)、'front_ratio''back_ratio'
  • count: 获取数据条数。大于或等于 0 时,若指定了时间范围则以 end_time 为基准向前取 count 条;缺省时取全部匹配数据。

3.2 返回值结构

接口返回一个 Python dict 字典:

  • Key: 时间戳毫秒数 timetag
  • Value: 行情数据字典 valuedict
    • 周期不为 'tick':包含 'open', 'high', 'low', 'close', 'volume', 'amount'
    • 周期为 'tick':包含 'lastPrice', 'amount', 'volume', 'openInt', 'askPrice', 'bidPrice' 等盘口分笔明细。

4. 离线回测示例代码

以下示例展示了如何在 QMT Python 策略中使用 get_local_data 读取本地日线数据,并实现快速指标计算:

#coding:gbk
import pandas as pd

def init(ContextInfo):
    # 设置股票池
    ContextInfo.stocks = ['600000.SH', '000001.SZ']
    ContextInfo.set_universe(ContextInfo.stocks)
    print("策略初始化完成,准备读取本地数据...")

def handlebar(ContextInfo):
    # 仅在最后一根 Bar 上一次性进行本地数据计算,以实现最高回测效率
    if not ContextInfo.is_last_bar():
        return
    
    start_date = '20230101'
    end_date = '20231231'
    
    for stock in ContextInfo.stocks:
        # 从本地离线数据库获取历史日线行情
        local_dict = ContextInfo.get_local_data(
            stock_code=stock,
            start_time=start_date,
            end_time=end_date,
            period='1d',
            divid_type='front'
        )
        
        if not local_dict:
            print(f"{stock} 本地无数据,请先通过 QMT 数据管理补充下载!")
            continue
            
        # 将返回的 dict 转为 Pandas DataFrame
        df = pd.DataFrame.from_dict(local_dict, orient='index')
        df.index = pd.to_datetime(df.index, unit='ms') # 转化时间戳
        
        # 输出统计信息
        close_price = df['close'].iloc[-1]
        max_high = df['high'].max()
        print(f"[{stock}] 本地读取成功! 数据条数: {len(df)}, 最新收盘价: {close_price}, 区间最高价: {max_high}")

5. 提升离线回测速度的最佳实践

  1. 配合快速计算设置:在【策略编辑器】的【基本信息】面板中设置 快速计算(指定 N 个 K 线),限制系统加载的主图 Bar 数量,减少 handlebar 触发频率。
  2. 批量预加载:在 init() 初始化函数中提前调用 get_local_data,将策略所需的离线数据一次性加载至内存字典或 Pandas DataFrame 中,避免在 handlebar 中重复读取硬盘。
  3. 精准补充数据:仅补充策略实际依赖的周期(如只用到 5 分钟线则无需下载 Tick 数据),以减小本地数据库文件大小并提高查询吞吐速度。