miniqmt和xtquant行情数据接口使用指南

介绍如何使用xtquant库通过miniqmt获取股票和ETF的行情数据,包括历史下载、实时订阅与回调机制
xtquant
miniqmt
行情数据
回调函数
实时订阅
数据流
Published

2025-09-26

1 行情

  • 1, etf不存在复权概念
from xtquant import xtdata
import time
import os
import pandas as pd
import numpy as np
from diskcache import Cache
cache = Cache(os.path.expanduser('~/.jupyter_cache'))
C:\Users\gkxk\AppData\Roaming\Python\Python313\site-packages\xtquant\__init__.py:8: UserWarning:

pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html. The pkg_resources package is slated for removal as early as 2025-11-30. Refrain from using this package or pin to Setuptools<81.

1.1 基础可用的函数

# 下载历史行情数据
help(xtdata.download_history_data)
Help on function download_history_data in module xtquant.xtdata:

download_history_data(
    stock_code,
    period,
    start_time='',
    end_time='',
    incrementally=None
)
    :param stock_code: str 品种代码,例如:'000001.SZ'
    :param period: str 数据周期
    :param start_time: 开始时间,支持以下格式:
        - str格式: YYYYMMDD/YYYYMMDDhhmmss 或 ''
            例如:'20230101' '20231231235959'
            空字符串代表全部,自动扩展到完整范围
        - datetime.datetime对象c
    :param end_time: str 结束时间 格式同开始时间
    :param incrementally: 是否增量下载
        bool: 是否增量下载
        None: 使用start_time控制,start_time为空则增量下载
# 获取行情数据
help(xtdata.get_market_data)
Help on function get_market_data in module xtquant.xtdata:

get_market_data(
    field_list=[],
    stock_list=[],
    period='1d',
    start_time='',
    end_time='',
    count=-1,
    dividend_type='none',
    fill_data=True
)
    获取历史行情数据
    :param field_list: 行情数据字段列表,[]为全部字段
        K线可选字段:
            "time"                #时间戳
            "open"                #开盘价
            "high"                #最高价
            "low"                 #最低价
            "close"               #收盘价
            "volume"              #成交量
            "amount"              #成交额
            "settle"              #今结算
            "openInterest"        #持仓量
        分笔可选字段:
            "time"                #时间戳
            "lastPrice"           #最新价
            "open"                #开盘价
            "high"                #最高价
            "low"                 #最低价
            "lastClose"           #前收盘价
            "amount"              #成交总额
            "volume"              #成交总量
            "pvolume"             #原始成交总量
            "stockStatus"         #证券状态
            "openInt"             #持仓量
            "lastSettlementPrice" #前结算
            "askPrice1", "askPrice2", "askPrice3", "askPrice4", "askPrice5" #卖一价~卖五价
            "bidPrice1", "bidPrice2", "bidPrice3", "bidPrice4", "bidPrice5" #买一价~买五价
            "askVol1", "askVol2", "askVol3", "askVol4", "askVol5"           #卖一量~卖五量
            "bidVol1", "bidVol2", "bidVol3", "bidVol4", "bidVol5"           #买一量~买五量
    :param stock_list: 股票代码 "000001.SZ"
    :param period: 周期 分笔"tick" 分钟线"1m"/"5m"/"15m" 日线"1d"
        Level2行情快照"l2quote" Level2行情快照补充"l2quoteaux" Level2逐笔委托"l2order" Level2逐笔成交"l2transaction" Level2大单统计"l2transactioncount" Level2委买委卖队列"l2orderqueue"
        Level1逐笔成交统计一分钟“transactioncount1m” Level1逐笔成交统计日线“transactioncount1d”
        期货仓单“warehousereceipt” 期货席位“futureholderrank” 互动问答“interactiveqa”
    :param start_time: 起始时间 "20200101" "20200101093000"
    :param end_time: 结束时间 "20201231" "20201231150000"
    :param count: 数量 -1全部/n: 从结束时间向前数n个
    :param dividend_type: 除权类型"none" "front" "back" "front_ratio" "back_ratio"
    :param fill_data: 对齐时间戳时是否填充数据,仅对K线有效,分笔周期不对齐时间戳
        为True时,以缺失数据的前一条数据填充
            open、high、low、close 为前一条数据的close
            amount、volume为0
            settle、openInterest 和前一条数据相同
        为False时,缺失数据所有字段填NaN
    :return: 数据集,分笔数据和K线数据格式不同
        period为'tick'时:{stock1 : value1, stock2 : value2, ...}
            stock1, stock2, ... : 合约代码
            value1, value2, ... : np.ndarray 数据列表,按time增序排列
        period为其他K线周期时:{field1 : value1, field2 : value2, ...}
            field1, field2, ... : 数据字段
            value1, value2, ... : pd.DataFrame 字段对应的数据,各字段维度相同,index为stock_list,columns为time_list
# 订阅单股行情
help(xtdata.subscribe_quote)
Help on function subscribe_quote in module xtquant.xtdata:

subscribe_quote(
    stock_code,
    period='1d',
    start_time='',
    end_time='',
    count=0,
    callback=None
)
    订阅股票行情数据
    :param stock_code: 股票代码 e.g. "000001.SZ"
    :param period: 周期 分笔"tick" 分钟线"1m"/"5m" 日线"1d"等周期
    :param start_time: 开始时间,支持以下格式:
        - str格式: YYYYMMDD/YYYYMMDDhhmmss,e.g."20200427" "20200427093000"
        - datetime对象
        若取某日全量历史数据,时间需要具体到秒,e.g."20200427093000"
    :param end_time: 结束时间 同“开始时间”
    :param count: 数量 -1全部/n: 从结束时间向前数n个
    :param callback:
        订阅回调函数onSubscribe(datas)
        :param datas: {stock : [data1, data2, ...]} 数据字典
    :return: int 订阅序号
# 获取最新交易日k线数据
# help(xtdata.get_full_kline) -> 基本不会用到

# 获取全推数据
# help(xtdata.get_full_tick) -> level1为3秒一次

# 获取本地行情数据
# help(xtdata.get_local_data) -> 基本不会用到

# 订阅全推行情
# help(xtdata.subscribe_whole_quote) -> 基本不会用到

# 反订阅行情数据
# help(xtdata.unsubscribe_quote) -> 基本不会用到

# 阻塞线程接收行情回调
# help(xtdata.run) -> 没有任何参数的一个简单阻塞, 自己也能实现
  • 1, 使用回调时,必须要同时使用xtdata.run()来阻塞程序,否则程序运行到最后一行就直接结束退出了
  • 2, get_full_tick似乎可能会用到, 和akshare的拿到实时行情是一个意思
  • 3, 行情无需输入用户名密码什么的, miniqmt启动后就能拿到数据

1.1.1 xtquant文档高亮重点内容

// ==UserScript==
// @name         暗色主题 - 行情数据区块高亮
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  给指定的 h4 及其后续内容添加暗色背景,直到下一个 h4
// @match        https://dict.thinktrader.net/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    // 目标 h4 的 ID 列表
    const targetH4Ids = [
        "下载历史行情数据",
        "获取行情数据",
        "订阅单股行情"
    ];

    // 暗色主题样式
    const darkThemeStyle = `
        color: yellow;
        border-bottom: 4px solid yellow;
        border-radius: 4px;
    `;

    // 遍历所有目标 h4
    targetH4Ids.forEach(id => {
        const h4Element = document.querySelector(`h4#${id}`);
        if (!h4Element) return; // 如果找不到就跳过

        // 1. 给当前 h4 添加样式
        h4Element.style.cssText = darkThemeStyle;

        // 2. 找到它后面的所有兄弟元素,直到遇到下一个 h4
        let nextSibling = h4Element.nextElementSibling;
        while (nextSibling && nextSibling.tagName !== "H4") {
            // 给非 h4 元素添加样式(左右边框 + 背景色)
            nextSibling.style.cssText = `
                background-color: #000;
                color: #e0e0e0;
                border-left: 4px solid yellow;
                border-right: 4px solid yellow;
            `;

            // 检查是否是最后一个元素,如果是就加底部边框
            const nextNextSibling = nextSibling.nextElementSibling;
            if (!nextNextSibling || nextNextSibling.tagName === "H4") {
                nextSibling.style.borderBottom = "4px solid yellow";
                nextSibling.style.borderRadius = "0 0 4px 4px";
            }

            nextSibling = nextSibling.nextElementSibling;
        }
    });
})();

1.2 官方的使用示例

# 纳斯达克ETF
code_list = ['513300.SH']
period = "1d"

for code in code_list:
    xtdata.download_history_data(code,period=period,incrementally=True) # 增量下载行情数据到本地

# 读取本地历史行情数据
history_data = xtdata.get_market_data([], code_list,period=period,count=-1)
***** xtdata连接成功 2025-10-06 16:34:13*****
服务信息: {'tag': 'sp3', 'version': '1.0'}
服务地址: 127.0.0.1:58610
数据路径: C:\storage\software\国金QMT交易端模拟\bin.x64/../userdata_mini/datadir
设置xtdata.enable_hello = False可隐藏此消息
  • 这里返回值为{'time': array([[t1, t2, t3, ...]]), 'open': array([[o1, o2, o3, ...]]), ...}格式. 且就算code_list只有一个元素, 内部也是一个一行的dataframe
df = pd.DataFrame({k: v.squeeze(0) for k, v in history_data.items()})
print(df)
                   time   open   high    low  close   volume       amount  \
20240530  1716998400000  1.722  1.723  1.715  1.717  1147389  197178032.0   
20240531  1717084800000  1.701  1.713  1.699  1.713  1180885  201524147.0   
20240603  1717344000000  1.720  1.723  1.715  1.720  1921837  330476180.0   
20240604  1717430400000  1.720  1.721  1.714  1.716   620769  106668071.0   
20240605  1717516800000  1.725  1.730  1.723  1.729   913487  157834741.0   
...                 ...    ...    ...    ...    ...      ...          ...   
20250904  1756915200000  2.099  2.099  2.092  2.094  2363893  495212539.0   
20250905  1757001600000  2.113  2.118  2.113  2.117  2376351  502701515.0   
20250908  1757260800000  2.115  2.116  2.112  2.113  1650252  348847553.0   
20250909  1757347200000  2.115  2.120  2.113  2.119  2108937  446304333.0   
20250910  1757433600000  2.123  2.129  2.122  2.128  1738874  369720487.0   

          settelementPrice  openInterest  preClose  suspendFlag  
20240530               0.0            15     1.738            0  
20240531               0.0            15     1.717            0  
20240603               0.0            15     1.713            0  
20240604               0.0            15     1.720            0  
20240605               0.0            15     1.716            0  
...                    ...           ...       ...          ...  
20250904               0.0            15     2.086            0  
20250905               0.0            15     2.094            0  
20250908               0.0            15     2.117            0  
20250909               0.0            15     2.113            0  
20250910               0.0            15     2.119            0  

[314 rows x 11 columns]
  • 需要转化才能使用
# 订阅
if False:
    for i in code_list:
        xtdata.subscribe_quote(i,period=period,count=-1) # 设置count = -1来取到当天所有实时行情

    # 等待订阅完成
    time.sleep(1)

    # 获取订阅后的行情
    kline_data = xtdata.get_market_data([],code_list,period=period)
    print(kline_data)

    # 获取订阅后的行情,并以固定间隔进行刷新,预期会循环打印3次
    for i in range(3):
        # 这边做演示,就用for来循环了,实际使用中可以用while True
        kline_data = xtdata.get_market_data([],code_list,period=period)
        print(kline_data)
        time.sleep(3) # 三秒后再次获取行情
  • 如果需要盘中的实时行情,需要向服务器进行订阅后才能获取
  • 可订阅后直接在需要时获取
# 如果不想用固定间隔触发,可以以用订阅后的回调来执行
# 这种模式下当订阅的callback回调函数将会异步的执行,每当订阅的标的tick发生变化更新,callback回调函数就会被调用一次
# 本地已有的数据不会触发callback
    
# 定义的回测函数
    ## 回调函数中,data是本次触发回调的数据,只有一条
if False:
    def f(data):
        print(data)
        code_list = list(data.keys())    # 获取到本次触发的标的代码
        print(code_list)

        # kline_in_callabck = xtdata.get_market_data([],code_list,period = period)    # 在回调中获取klines数据
        # print(kline_in_callabck)

    for i in code_list:
        xtdata.subscribe_quote(i,period=period,count=-1,callback=f) # 订阅时设定回调函数

    # 使用回调时,必须要同时使用xtdata.run()来阻塞程序,否则程序运行到最后一行就直接结束退出了。
    xtdata.run()
  • 可在回调函数中拿到数据, 在tick更新时拿到数据

1.3 数据类型

  • level1数据
    • tick - 分笔数据
    • 1m - 1分钟线
    • 5m - 5分钟线
    • 15m - 15分钟线
    • 30m - 30分钟线
    • 1h - 1小时线
    • 1d - 日线
    • 1w - 周线
    • 1mon - 月线
    • 1q - 季度线
    • 1hy - 半年线
    • 1y - 年线
  • 时间范围是[start_time, end_time]区间(包含前后边界)中最后不多于count个数据
    • 通常以[start_time = ’‘, end_time =’’, count = -1]表示完整数据范围
  • k线数据
    • ‘time’ #时间戳
    • ‘open’ #开盘价
    • ‘high’ #最高价
    • ‘low’ #最低价
    • ‘close’ #收盘价
    • ‘volume’ #成交量
    • ‘amount’ #成交额
    • ‘settelementPrice’ #今结算
    • ‘openInterest’ #持仓量
    • ‘preClose’ #前收价
    • ‘suspendFlag’ #停牌标记 0 - 正常 1 - 停牌 -1 - 当日起复牌

2 交易