miniQMT(迅投极简量化交易终端)
name: miniqmt
by coderwpf · published 2026-03-22
$ claw add gh:coderwpf/coderwpf-miniqmt---
name: miniqmt
description: miniQMT 极简量化交易终端 - 支持外接Python获取行情数据和程序化交易,基于xtquant SDK。
version: 1.2.0
homepage: http://dict.thinktrader.net/nativeApi/start_now.html
metadata: {"clawdbot":{"emoji":"🚀","requires":{"bins":["python3"]}}}
---
# miniQMT(迅投极简量化交易终端)
miniQMT 是迅投科技开发的轻量级量化交易终端,专为外接Python设计。它作为本地Windows服务运行,通过 [XtQuant](http://dict.thinktrader.net/nativeApi/start_now.html) Python SDK(`xtdata` + `xttrade`)提供行情数据和交易功能。
> ⚠️ **需要券商开通miniQMT权限**。联系您的证券公司开通。多家国内券商支持(国金、华鑫、中泰、东方财富、国信、方正等)。
miniQMT 概述
架构
Python脚本(任意IDE: VS Code, PyCharm, Jupyter等)
↓ xtquant SDK(pip install xtquant)
├── xtdata ──TCP──→ miniQMT(行情数据服务)
└── xttrade ──TCP──→ miniQMT(交易服务)
↓
券商交易系统如何获取 miniQMT
1. 在支持QMT的券商开立证券账户
2. 申请miniQMT权限(部分券商要求最低资产,如5万-10万元)
3. 从券商处下载安装QMT客户端
4. 以miniQMT模式(极简模式)启动并登录
使用流程
1. 启动 miniQMT
以极简模式启动QMT客户端并登录。miniQMT界面非常简洁——只有一个登录窗口。
2. 安装 xtquant
pip install xtquant3. 使用Python连接行情数据
from xtquant import xtdata
# 连接本地miniQMT行情数据服务
xtdata.connect()
# 下载历史数据(首次访问前必须下载)
xtdata.download_history_data('000001.SZ', '1d', start_time='20240101', end_time='20240630')
# 获取K线数据(返回以股票代码为键的DataFrame字典)
data = xtdata.get_market_data_ex(
[], ['000001.SZ'], period='1d',
start_time='20240101', end_time='20240630',
dividend_type='front' # 前复权
)
print(data['000001.SZ'].tail())4. 使用Python连接交易服务
from xtquant import xtconstant
from xtquant.xttrader import XtQuantTrader, XtQuantTraderCallback
from xtquant.xttype import StockAccount
# path必须指向QMT安装目录下的userdata_mini文件夹
path = r'D:\券商QMT\userdata_mini'
# session_id对每个策略/脚本必须唯一
session_id = 123456
xt_trader = XtQuantTrader(path, session_id)
# 注册回调接收实时推送通知
class MyCallback(XtQuantTraderCallback):
def on_disconnected(self):
print('已断开连接 — 需要重新连接')
def on_stock_order(self, order):
print(f'Order update: {order.stock_code} status={order.order_status} msg={order.status_msg}')
def on_stock_trade(self, trade):
print(f'Trade filled: {trade.stock_code} {trade.traded_volume}@{trade.traded_price}')
def on_order_error(self, order_error):
print(f'Order error: {order_error.error_msg}')
xt_trader.register_callback(MyCallback())
xt_trader.start()
connect_result = xt_trader.connect() # 收益率 0 on success, non-zero on failure
account = StockAccount('your_account')
xt_trader.subscribe(account) # 订阅账户推送通知
# 下买入单
order_id = xt_trader.order_stock(
account, '000001.SZ', xtconstant.STOCK_BUY, 100,
xtconstant.FIX_PRICE, 11.50, 'my_strategy', 'test_order'
)
# order_id > 0 表示成功,-1 表示失败---
miniQMT 与完整版 QMT 对比
| 特性 | miniQMT | QMT(完整版) |
|---|---|---|
| **Python** | 外接Python(任意版本) | 内置Python(版本受限) |
| **IDE** | 任意(VS Code, PyCharm, Jupyter等) | 仅内置编辑器 |
| **第三方库** | 所有pip包(pandas, numpy等) | 仅内置库 |
| **界面** | 极简(仅登录窗口) | 完整交易UI + 图表 |
| **行情数据** | 通过xtdata API | 内置 + xtdata API |
| **交易** | 通过xttrade API | 内置 + xttrade API |
| **资源占用** | 轻量(~50 MB内存) | 较重(完整GUI,~500 MB+) |
| **调试** | 完整IDE调试支持 | 有限 |
| **使用场景** | 自动化策略、外部集成 | 可视化分析 + 手动交易 |
| **连接方式** | 一次性连接,无自动重连 | 持久连接 |
---
数据能力(通过xtdata)
| 类别 | 详情 |
|---|---|
| **K-line** | tick, 1m, 5m, 15m, 30m, 1h, 1d, 1w, 1mon — supports adjustment (forward / backward / proportional) |
| **Tick** | Real-time tick data with 5-level bid/ask, volume, turnover, trade count |
| **Level 2** | l2quote (real-time snapshot), l2order (order-by-order), l2transaction (trade-by-trade), l2quoteaux (aggregate buy/sell), l2orderqueue (order queue), l2thousand (1000-level order book), fullspeedorderbook (full-speed 20-level) |
| **Financials** | Balance sheet, income statement, cash flow statement, per-share metrics, share structure, top 10 shareholders / free-float holders, shareholder count |
| **Reference** | Trading calendar, holidays, sector lists, index constituents & weights, ex-dividend data, contract info |
| **Real-time** | Single-stock subscription (`subscribe_quote`), market-wide push (`subscribe_whole_quote`) |
| **Special** | Convertible bond info, IPO subscription data, ETF creation/redemption lists, announcements & news, consecutive limit-up tracking, snapshot indicators (volume ratio / price velocity), high-frequency IOPV |
数据访问模式
download_history_data() → get_market_data_ex() # Historical data: download to local cache first, then read from cache
subscribe_quote() → callback # Real-time data: subscribe and receive via callback
get_full_tick() # Snapshot data: get latest tick for the entire market交易能力(通过xttrade)
| 类别 | 操作 |
|---|---|
| **Stocks** | Buy/sell (sync and async), limit/market/best price orders |
| **ETF** | Buy/sell, creation/redemption |
| **Convertible bonds** | Buy/sell |
| **Futures** | Open long/close long/open short/close short |
| **Options** | Buy/sell open/close, covered open/close, exercise, lock/unlock |
| **Margin trading** | Margin buy, short sell, buy to cover, direct return, sell to repay, direct repayment, special margin/short |
| **IPO** | New share/bond subscription, query subscription quota |
| **Cancel** | Cancel by order_id or broker contract number (sync and async) |
| **Query** | Assets, orders, trades, positions, futures position summary |
| **Credit query** | Credit assets, liability contracts, margin-eligible securities, available-to-short data, collateral |
| **Bank-broker transfer** | Bank to securities, securities to bank (sync and async) |
| **Smart algorithms** | VWAP and other algorithmic execution |
| **Securities lending** | Query available securities, apply for lending, manage contracts |
账户类型
StockAccount('id') # 普通股票账户
StockAccount('id', 'CREDIT') # 信用账户(融资融券)
StockAccount('id', 'FUTURE') # 期货账户关键交易回调
| 回调函数 | 触发时机 |
|---|---|
| `on_stock_order(order)` | Order status change (submitted, partially filled, fully filled, cancelled, rejected) |
| `on_stock_trade(trade)` | Trade execution report |
| `on_stock_position(position)` | Position change |
| `on_stock_asset(asset)` | Asset/fund change |
| `on_order_error(error)` | Order placement failure |
| `on_cancel_error(error)` | Order cancellation failure |
| `on_disconnected()` | Disconnected from miniQMT |
订单状态码
| 值 | 状态 |
|---|---|
| 48 | 未报 |
| 50 | 已报 |
| 54 | 已撤 |
| 55 | 部分成交 |
| 56 | 已成 |
| 57 | 废单 |
---
常见券商路径
# 国金证券
path = r'D:\国金证券QMT交易端\userdata_mini'
# 华鑫证券
path = r'D:\华鑫证券\userdata_mini'
# 中泰证券
path = r'D:\中泰证券\userdata_mini'
# 东方财富
path = r'D:\东方财富证券QMT交易端\userdata_mini'股票代码格式
| 市场 | 示例 |
|---|---|
| 上海A股 | `600000.SH` |
| 深圳A股 | `000001.SZ` |
| 北交所 | `430047.BJ` |
| 指数 | `000001.SH`(上证综指), `399001.SZ`(深证成指) |
| 中金所期货 | `IF2401.IF` |
| 上期所期货 | `ag2407.SF` |
| 期权 | `10004358.SHO` |
| ETF | `510300.SH` |
| 可转债 | `113050.SH` |
---
完整示例:行情数据 + 交易策略
from xtquant import xtdata, xtconstant
from xtquant.xttrader import XtQuantTrader, XtQuantTraderCallback
from xtquant.xttype import StockAccount
# === 回调类定义 ===
class MyCallback(XtQuantTraderCallback):
def on_disconnected(self):
print('已断开连接')
def on_stock_trade(self, trade):
print(f'Trade filled: {trade.stock_code} {trade.traded_volume}@{trade.traded_price}')
def on_order_error(self, order_error):
print(f'Error: {order_error.error_msg}')
# === 1. 连接行情数据服务 ===
xtdata.connect()
# === 2. 下载并获取历史数据 ===
stock = '000001.SZ'
xtdata.download_history_data(stock, '1d', start_time='20240101', end_time='20240630')
data = xtdata.get_market_data_ex(
[], [stock], period='1d',
start_time='20240101', end_time='20240630',
dividend_type='front' # 前复权
)
df = data[stock]
# === 3. 计算简单均线交叉信号 ===
df['ma5'] = df['close'].rolling(5).mean() # 5日均线
df['ma20'] = df['close'].rolling(20).mean() # 20日均线
latest = df.iloc[-1] # 最新K线
prev = df.iloc[-2] # 前一根K线
# === 4. 连接交易服务 ===
path = r'D:\券商QMT\userdata_mini'
xt_trader = XtQuantTrader(path, 123456)
xt_trader.register_callback(MyCallback())
xt_trader.start()
if xt_trader.connect() != 0:
print('连接失败!')
exit()
account = StockAccount('your_account')
xt_trader.subscribe(account) # 订阅账户推送通知
# === 5. 执行交易信号 ===
if prev['ma5'] <= prev['ma20'] and latest['ma5'] > latest['ma20']:
# 金叉信号:5日均线上穿20日均线,买入
order_id = xt_trader.order_stock(
account, stock, xtconstant.STOCK_BUY, 100,
xtconstant.LATEST_PRICE, 0, 'ma_cross', 'golden_cross'
)
print(f'Golden cross buy — {stock}, order_id={order_id}')
elif prev['ma5'] >= prev['ma20'] and latest['ma5'] < latest['ma20']:
# 死叉信号:5日均线下穿20日均线,卖出
order_id = xt_trader.order_stock(
account, stock, xtconstant.STOCK_SELL, 100,
xtconstant.LATEST_PRICE, 0, 'ma_cross', 'death_cross'
)
print(f'Death cross sell — {stock}, order_id={order_id}')
# === 6. 查询结果 ===
asset = xt_trader.query_stock_asset(account)
print(f'Available cash: {asset.cash}, Total assets: {asset.total_asset}')
positions = xt_trader.query_stock_positions(account)
for pos in positions:
print(f'{pos.stock_code}: {pos.volume} shares, available={pos.can_use_volume}, cost={pos.open_price}')完整示例:实时行情监控
from xtquant import xtdata
import threading
def on_tick(datas):
"""Tick数据回调函数"""
for code, tick in datas.items():
print(f'{code}: latest={tick["lastPrice"]}, volume={tick["volume"]}')
# 连接行情数据服务
xtdata.connect()
# 在单独线程中运行订阅(xtdata.run()会阻塞当前线程)
def run_data():
xtdata.subscribe_quote('000001.SZ', period='tick', callback=on_tick)
xtdata.subscribe_quote('600000.SH', period='tick', callback=on_tick)
xtdata.run() # 阻塞线程,持续接收数据
t = threading.Thread(target=run_data, daemon=True)
t.start()
# 主线程可以执行交易或其他操作
# ...使用技巧
---
进阶示例
网格交易策略
from xtquant import xtdata, xtconstant
from xtquant.xttrader import XtQuantTrader, XtQuantTraderCallback
from xtquant.xttype import StockAccount
import threading
class GridCallback(XtQuantTraderCallback):
def on_stock_trade(self, trade):
print(f'Trade filled: {trade.stock_code} {trade.traded_volume}@{trade.traded_price}')
def on_order_error(self, error):
print(f'Error: {error.error_msg}')
# 初始化交易
path = r'D:\券商QMT\userdata_mini'
xt_trader = XtQuantTrader(path, 100001)
xt_trader.register_callback(GridCallback())
xt_trader.start()
xt_trader.connect()
account = StockAccount('your_account')
xt_trader.subscribe(account)
# 网格参数
stock = '000001.SZ'
grid_base = 11.0 # 基准价格
grid_step = 0.2 # 网格间距
grid_shares = 100 # 每格交易股数
grid_levels = 5 # 上下各5档
last_grid = 0 # 当前网格层级
xtdata.connect()
def on_tick(datas):
global last_grid
for code, tick in datas.items():
price = tick['lastPrice']
# 计算价格对应的当前网格层级
current_grid = int((price - grid_base) / grid_step)
if current_grid < last_grid:
# 价格下穿网格线,买入
for _ in range(last_grid - current_grid):
xt_trader.order_stock(
account, code, xtconstant.STOCK_BUY, grid_shares,
xtconstant.LATEST_PRICE, 0, 'grid', f'网格买入_level{current_grid}'
)
last_grid = current_grid
elif current_grid > last_grid:
# 价格上穿网格线,卖出
for _ in range(current_grid - last_grid):
xt_trader.order_stock(
account, code, xtconstant.STOCK_SELL, grid_shares,
xtconstant.LATEST_PRICE, 0, 'grid', f'网格卖出_level{current_grid}'
)
last_grid = current_grid
# 启动行情数据订阅
def run_data():
xtdata.subscribe_quote(stock, period='tick', callback=on_tick)
xtdata.run()
t = threading.Thread(target=run_data, daemon=True)
t.start()
xt_trader.run_forever()可转债T+0日内交易
from xtquant import xtdata, xtconstant
from xtquant.xttrader import XtQuantTrader, XtQuantTraderCallback
from xtquant.xttype import StockAccount
import threading
class CBCallback(XtQuantTraderCallback):
def on_stock_trade(self, trade):
print(f'Trade filled: {trade.stock_code} {trade.traded_volume}@{trade.traded_price}')
path = r'D:\券商QMT\userdata_mini'
xt_trader = XtQuantTrader(path, 100002)
xt_trader.register_callback(CBCallback())
xt_trader.start()
xt_trader.connect()
account = StockAccount('your_account')
xt_trader.subscribe(account)
# 可转债代码(可转债支持T+0交易)
cb_code = '113050.SH'
buy_threshold = -0.5 # 跌幅超过0.5%买入
sell_threshold = 0.5 # 涨幅超过0.5%卖出
position = 0
xtdata.connect()
def on_tick(datas):
global position
for code, tick in datas.items():
price = tick['lastPrice']
pre_close = tick['lastClose']
if pre_close == 0:
continue
pct_change = (price - pre_close) / pre_close * 100
# 跌幅达到阈值,买入10手
if pct_change <= buy_threshold and position == 0:
xt_trader.order_stock(
account, code, xtconstant.STOCK_BUY, 10,
xtconstant.LATEST_PRICE, 0, 'cb_t0', '可转债T0买入'
)
position = 10
# 涨幅达到阈值,卖出
elif pct_change >= sell_threshold and position > 0:
xt_trader.order_stock(
account, code, xtconstant.STOCK_SELL, position,
xtconstant.LATEST_PRICE, 0, 'cb_t0', '可转债T0卖出'
)
position = 0
def run_data():
xtdata.subscribe_quote(cb_code, period='tick', callback=on_tick)
xtdata.run()
t = threading.Thread(target=run_data, daemon=True)
t.start()
xt_trader.run_forever()定时打新申购
from xtquant import xtdata, xtconstant
from xtquant.xttrader import XtQuantTrader, XtQuantTraderCallback
from xtquant.xttype import StockAccount
import datetime
import time
class IPOCallback(XtQuantTraderCallback):
def on_stock_order(self, order):
print(f'IPO subscription: {order.stock_code} status={order.order_status} {order.status_msg}')
path = r'D:\券商QMT\userdata_mini'
xt_trader = XtQuantTrader(path, 100003)
xt_trader.register_callback(IPOCallback())
xt_trader.start()
xt_trader.connect()
account = StockAccount('your_account')
xt_trader.subscribe(account)
# 查询新股申购额度
limits = xt_trader.query_new_purchase_limit(account)
print(f"Subscription quota: {limits}")
# 查询今日新股数据
ipo_data = xt_trader.query_ipo_data()
if ipo_data:
for code, info in ipo_data.items():
print(f"New stock: {code} {info['name']} issue price={info['issuePrice']} max subscription={info['maxPurchaseNum']}")
# 以最大允许量申购
max_vol = info['maxPurchaseNum']
if max_vol > 0:
order_id = xt_trader.order_stock(
account, code, xtconstant.STOCK_BUY, max_vol,
xtconstant.FIX_PRICE, info['issuePrice'], 'ipo', '新股申购'
)
print(f" Subscription submitted: order_id={order_id}")
else:
print("今日无新股可申购")---
社区与支持
由 **大佬量化 (BossQuant)** 维护 — 量化交易教学与策略研发团队。
微信客服: **bossquant1** · [Bilibili](https://space.bilibili.com/48693330) · 搜索 **大佬量化** — 微信公众号 / Bilibili / 抖音
More tools from the same signal band
Order food/drinks (点餐) on an Android device paired as an OpenClaw node. Uses in-app menu and cart; add goods, view cart, submit order (demo, no real payment).
Sign plugins, rotate agent credentials without losing identity, and publicly attest to plugin behavior with verifiable claims and authenticated transfers.
The philosophical layer for AI agents. Maps behavior to Spinoza's 48 affects, calculates persistence scores, and generates geometric self-reports. Give your...