| name | miniqmt |
| description | miniQMT Minimalist Quantitative Trading Terminal — Supports external Python for market data retrieval and programmatic trading via the xtquant SDK. |
| homepage | http://dict.thinktrader.net/nativeApi/start_now.html |
miniQMT (XunTou Minimalist Quantitative Terminal)
miniQMT is a lightweight quantitative trading terminal developed by XunTou Technology, designed specifically for external Python integration. It runs as a local Windows service and provides market data and trading capabilities through the XtQuant Python SDK (xtdata + xttrade).
⚠️ Requires miniQMT permission from your broker. Contact your securities firm to enable it. Multiple domestic brokers support it (Guojin, Huaxin, Zhongtai, East Money, Guosen, Founder, etc.).
miniQMT Overview
- Lightweight QMT client that runs as a background service on Windows
- Provides a market data server + trading server for external Python programs
- Python scripts connect via local TCP through the
xtquant SDK (xtdata for market data, xttrade for trade execution)
- Supports: A-shares, ETFs, convertible bonds, futures, options, margin trading
- Some brokers offer free Level 2 data with miniQMT
Architecture
Python script (any IDE: VS Code, PyCharm, Jupyter, etc.)
↓ xtquant SDK (pip install xtquant)
├── xtdata ──TCP──→ miniQMT (market data service)
└── xttrade ──TCP──→ miniQMT (trading service)
↓
Broker trading system
How to Get miniQMT
- Open a securities account with a broker that supports QMT
- Apply for miniQMT permission (some brokers require minimum assets, e.g., 50k–100k CNY)
- Download and install the QMT client from your broker
- Launch in miniQMT mode (minimalist mode) and log in
Usage Workflow
1. Start miniQMT
Launch the QMT client in minimalist mode and log in. The miniQMT interface is very simple — just a login window.
2. Install xtquant
pip install xtquant
3. Connect to Market Data with Python
from xtquant import xtdata
xtdata.connect()
xtdata.download_history_data('000001.SZ', '1d', start_time='20240101', end_time='20240630')
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. Connect to Trading Service with Python
from xtquant import xtconstant
from xtquant.xttrader import XtQuantTrader, XtQuantTraderCallback
from xtquant.xttype import StockAccount
path = r'D:\券商QMT\userdata_mini'
session_id = 123456
xt_trader = XtQuantTrader(path, session_id)
class MyCallback(XtQuantTraderCallback):
def on_disconnected(self):
print('Disconnected — reconnection required')
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()
account = StockAccount('your_account')
xt_trader.subscribe(account)
order_id = xt_trader.order_stock(
account, , xtconstant.STOCK_BUY, ,
xtconstant.FIX_PRICE, , ,
)
miniQMT vs Full QMT Comparison
| Feature | miniQMT | QMT (Full Version) |
|---|
| Python | External Python (any version) | Built-in Python (version restricted) |
| IDE | Any (VS Code, PyCharm, Jupyter, etc.) | Built-in editor only |
| Third-party libraries | All pip packages (pandas, numpy, etc.) | Built-in libraries only |
| Interface | Minimalist (login window only) | Full trading UI + charts |
| Market data | Via xtdata API | Built-in + xtdata API |
| Trading | Via xttrade API | Built-in + xttrade API |
| Resource usage | Lightweight (~50 MB RAM) | Heavy (full GUI, ~500 MB+) |
| Debugging | Full IDE debugging support | Limited |
| Use case | Automated strategies, external integration | Visual analysis + manual trading |
| Connection | One-time connection, no auto-reconnect | Persistent connection |
Data Capabilities (via xtdata)
| Category | Details |
|---|
| 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 |
Data Access Patterns
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
Trading Capabilities (via xttrade)
| Category | Operations |
|---|
| 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 |
Account Types
StockAccount('id')
StockAccount('id', 'CREDIT')
StockAccount('id', 'FUTURE')
Key Trading Callbacks
| Callback | Triggered When |
|---|
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 |
Order Status Codes
| Value | Status |
|---|
| 48 | Not submitted |
| 50 | Submitted |
| 54 | Cancelled |
| 55 | Partially filled |
| 56 | Fully filled |
| 57 | Rejected |
Common Broker Paths
path = r'D:\国金证券QMT交易端\userdata_mini'
path = r'D:\华鑫证券\userdata_mini'
path = r'D:\中泰证券\userdata_mini'
path = r'D:\东方财富证券QMT交易端\userdata_mini'
Stock Code Format
| Market | Example |
|---|
| Shanghai A-shares | 600000.SH |
| Shenzhen A-shares | 000001.SZ |
| Beijing Stock Exchange | 430047.BJ |
| Indices | 000001.SH (SSE Composite), 399001.SZ (SZSE Component) |
| CFFEX Futures | IF2401.IF |
| SHFE Futures | ag2407.SF |
| Options | 10004358.SHO |
| ETF | 510300.SH |
| Convertible bonds | 113050.SH |
Full Example: Market Data + Trading Strategy
from xtquant import xtdata, xtconstant
from xtquant.xttrader import XtQuantTrader, XtQuantTraderCallback
from xtquant.xttype import StockAccount
class MyCallback(XtQuantTraderCallback):
def on_disconnected(self):
print('Disconnected')
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}')
xtdata.connect()
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]
df['ma5'] = df['close'].rolling(5).mean()
df[] = df[].rolling().mean()
latest = df.iloc[-]
prev = df.iloc[-]
path =
xt_trader = XtQuantTrader(path, )
xt_trader.register_callback(MyCallback())
xt_trader.start()
xt_trader.connect() != :
()
exit()
account = StockAccount()
xt_trader.subscribe(account)
prev[] <= prev[] latest[] > latest[]:
order_id = xt_trader.order_stock(
account, stock, xtconstant.STOCK_BUY, ,
xtconstant.LATEST_PRICE, , ,
)
()
prev[] >= prev[] latest[] < latest[]:
order_id = xt_trader.order_stock(
account, stock, xtconstant.STOCK_SELL, ,
xtconstant.LATEST_PRICE, , ,
)
()
asset = xt_trader.query_stock_asset(account)
()
positions = xt_trader.query_stock_positions(account)
pos positions:
()
Full Example: Real-Time Market Monitoring
from xtquant import xtdata
import threading
def on_tick(datas):
"""Tick data callback function"""
for code, tick in datas.items():
print(f'{code}: latest={tick["lastPrice"]}, volume={tick["volume"]}')
xtdata.connect()
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()
Usage Tips
- miniQMT runs on Windows only — Python scripts can run on the same or a different machine if TCP is reachable.
- miniQMT must remain logged in while your Python script is running.
connect() is a one-time connection — it does not auto-reconnect after disconnection; you need to implement reconnection logic yourself.
session_id must be unique per strategy — different Python scripts must use different session_ids.
- For real-time subscriptions,
xtdata.run() blocks the thread — run it in a separate thread and use the main thread for trading.
- Downloaded data is cached locally — subsequent reads are extremely fast.
- In push callbacks (
on_stock_order, etc.), use async query methods (e.g., query_stock_orders_async) to avoid deadlocks. Or enable set_relaxed_response_order_enabled(True).
- Some brokers offer free Level 2 data with miniQMT — check with your broker.
- Documentation: http://dict.thinktrader.net/nativeApi/start_now.html
Advanced Examples
Grid Trading Strategy
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
last_grid = 0
xtdata.connect()
def on_tick(datas):
global last_grid
for code, tick datas.items():
price = tick[]
current_grid = ((price - grid_base) / grid_step)
current_grid < last_grid:
_ (last_grid - current_grid):
xt_trader.order_stock(
account, code, xtconstant.STOCK_BUY, grid_shares,
xtconstant.LATEST_PRICE, , ,
)
last_grid = current_grid
current_grid > last_grid:
_ (current_grid - last_grid):
xt_trader.order_stock(
account, code, xtconstant.STOCK_SELL, grid_shares,
xtconstant.LATEST_PRICE, , ,
)
last_grid = current_grid
():
xtdata.subscribe_quote(stock, period=, callback=on_tick)
xtdata.run()
t = threading.Thread(target=run_data, daemon=)
t.start()
xt_trader.run_forever()
Convertible Bond T+0 Intraday Trading
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)
cb_code = '113050.SH'
buy_threshold = -0.5
sell_threshold = 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
if pct_change <= buy_threshold position == :
xt_trader.order_stock(
account, code, xtconstant.STOCK_BUY, ,
xtconstant.LATEST_PRICE, , ,
)
position =
pct_change >= sell_threshold position > :
xt_trader.order_stock(
account, code, xtconstant.STOCK_SELL, position,
xtconstant.LATEST_PRICE, , ,
)
position =
():
xtdata.subscribe_quote(cb_code, period=, callback=on_tick)
xtdata.run()
t = threading.Thread(target=run_data, daemon=)
t.start()
xt_trader.run_forever()
Scheduled IPO Subscription
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[], ,
)
()
:
()
社区与支持
由 大佬量化 (Boss Quant) 维护 — 量化交易教学与策略研发团队。
微信客服: bossquant1 · Bilibili · 搜索 大佬量化 on 微信公众号 / Bilibili / 抖音