| name | xtquant |
| description | XtQuant QMT Python SDK — Integrates market data (xtdata) and trading interfaces (xttrade), supporting A-shares, futures, options, and other Chinese securities markets. |
| homepage | http://dict.thinktrader.net/nativeApi/start_now.html |
XtQuant (QMT Python SDK by ThinkTrader)
XtQuant is the Python SDK for the QMT/miniQMT quantitative trading platform, developed by ThinkTrader (XunTou Technology). It contains two core modules:
- xtdata — Market Data Module: real-time quotes, historical K-lines, tick data, Level 2 data, financial data, sector management
- xttrade — Trading Module: order placement, position/order queries, account management, margin trading, futures/options, smart algorithms
⚠️ Requires miniQMT or QMT client running on Windows. XtQuant connects to the QMT process via local TCP. You need QMT/miniQMT access enabled by your broker.
Installation
pip install xtquant
You can also download from the official website: http://dict.thinktrader.net/nativeApi/download_xtquant.html
Architecture Overview
Your Python script (any IDE, any Python version)
↓ (xtquant SDK, pip install)
├── xtdata → miniQMT (market data service, TCP connection)
└── xttrade → miniQMT (trading service, TCP connection)
↓
Broker trading system
Core Module Reference
| Module | Import | Purpose |
|---|
xtdata | from xtquant import xtdata | Market data: K-lines, tick, Level 2, financials, sectors |
xttrader | from xtquant.xttrader import XtQuantTrader | Trading: order placement, queries, callbacks |
xtconstant | from xtquant import xtconstant | Constants: order types, price types, market codes |
xttype | from xtquant.xttype import StockAccount | Account types: STOCK, CREDIT, FUTURE |
Quick Start — Market Data
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'])
Real-Time Quote Subscription
def on_data(datas):
"""Quote data callback function, receives pushed real-time data"""
for stock_code, data in datas.items():
print(stock_code, data)
xtdata.subscribe_quote('000001.SZ', period='tick', callback=on_data)
xtdata.subscribe_whole_quote(['SH', 'SZ'], callback=on_data)
xtdata.run()
Financial Data
xtdata.download_financial_data(['000001.SZ'])
data = xtdata.get_financial_data(['000001.SZ'])
Instrument Info & Sectors
info = xtdata.get_instrument_detail('000001.SZ')
itype = xtdata.get_instrument_type('000001.SZ')
stocks = xtdata.get_stock_list_in_sector('沪深A股')
days = xtdata.get_trading_dates('SH', start_time='20240101', end_time='20240630')
Quick Start — Trading
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')
def on_stock_order(self, order):
print(f'Order update: {order.stock_code} status={order.order_status}')
def on_stock_trade(self, trade):
print(f'Trade update: {trade.stock_code} {trade.traded_volume}@{trade.traded_price}')
def on_order_error(self, order_error):
print(f'Order error: {order_error.error_msg}')
def on_order_stock_async_response(self, response):
print(f'Async order response: order_id=')
xt_trader.register_callback(MyCallback())
xt_trader.start()
connect_result = xt_trader.connect()
account = StockAccount()
xt_trader.subscribe(account)
order_id = xt_trader.order_stock(
account, , xtconstant.STOCK_BUY, ,
xtconstant.FIX_PRICE, , ,
)
positions = xt_trader.query_stock_positions(account)
pos positions:
(pos.stock_code, pos.volume, pos.can_use_volume, pos.market_value)
orders = xt_trader.query_stock_orders(account)
asset = xt_trader.query_stock_asset(account)
()
xt_trader.cancel_order_stock(account, order_id)
xt_trader.run_forever()
Stock Code Format
| Market | Format | Example |
|---|
| Shanghai A-shares | XXXXXX.SH | 600000.SH |
| Shenzhen A-shares | XXXXXX.SZ | 000001.SZ |
| Beijing Stock Exchange | XXXXXX.BJ | 430047.BJ |
| Shanghai Index | XXXXXX.SH | 000001.SH (SSE Composite Index) |
| Shenzhen Index | XXXXXX.SZ | 399001.SZ (SZSE Component Index) |
| CFFEX Futures | XXXX.IF | IF2401.IF (CSI 300 Futures) |
| SHFE Futures | XXXX.SF | ag2407.SF (Silver Futures) |
| DCE Futures | XXXX.DF | m2405.DF (Soybean Meal Futures) |
| ZCE Futures | XXXX.ZF | CF405.ZF (Cotton Futures) |
| INE Futures | XXXX.INE | sc2407.INE (Crude Oil Futures) |
| Shanghai Options | XXXXXXXX.SHO | 10004358.SHO |
| Shenzhen Options | XXXXXXXX.SZO | 90000001.SZO |
| ETF | XXXXXX.SH/SZ | 510300.SH |
| Convertible Bonds | XXXXXX.SH/SZ | 113050.SH |
Data Periods
tick, 1m, 5m, 15m, 30m, 1h, 1d, 1w, 1mon
Supported Asset Types
| Asset | Market Data (xtdata) | Trading (xttrade) |
|---|
| A-shares (Shanghai & Shenzhen) | ✅ K-lines, tick, Level 2, financials | ✅ Buy/Sell |
| ETF | ✅ K-lines, tick, IOPV | ✅ Buy/Sell, Subscribe/Redeem |
| Convertible Bonds | ✅ K-lines, tick | ✅ Buy/Sell |
| Futures | ✅ K-lines, tick | ✅ Open long/Close long/Open short/Close short |
| Options | ✅ K-lines, tick | ✅ Buy/Sell open/close, Exercise |
| Indices | ✅ K-lines, tick | ❌ |
| Funds | ✅ K-lines, tick | ✅ Buy/Sell |
| Margin Trading | ✅ Via credit account | ✅ Full credit trading |
Order Type Constants (xtconstant)
| Category | Constants |
|---|
| Stock | STOCK_BUY (23, buy), STOCK_SELL (24, sell) |
| Credit | CREDIT_FIN_BUY (margin buy), CREDIT_SLO_SELL (short sell), CREDIT_BUY_SECU_REPAY (buy to repay securities), CREDIT_DIRECT_CASH_REPAY (direct cash repayment), etc. |
| Futures | FUTURE_BUY_OPEN (open long), FUTURE_SELL_CLOSE (close long), FUTURE_SELL_OPEN (open short), FUTURE_BUY_CLOSE (close short) |
| Options | STOCK_OPTION_BUY_OPEN (buy to open), STOCK_OPTION_SELL_CLOSE (sell to close), STOCK_OPTION_EXERCISE (exercise), etc. |
| Price Type | FIX_PRICE (11, limit), ANY_PRICE (12, market), LATEST_PRICE (5, latest price), MARKET_PEER_PRICE_FIRST (best counterparty price), etc. |
Account Types
StockAccount('id')
StockAccount('id', 'CREDIT')
StockAccount('id', 'FUTURE')
xtdata Interface Pattern
The market data module follows a unified download → retrieve pattern:
- Subscribe (subscribe):
subscribe_quote, subscribe_whole_quote — real-time push
- Download (download):
download_history_data, download_financial_data — download from server to local cache (synchronous/blocking)
- Retrieve (get):
get_market_data_ex, get_financial_data — read from local cache (fast)
xttrade Callback System
Register an XtQuantTraderCallback subclass to receive real-time push notifications:
| Callback | Data Type | Trigger Event |
|---|
on_stock_order(order) | XtOrder | Order status change |
on_stock_trade(trade) | XtTrade | Trade execution |
on_stock_position(position) | XtPosition | Position change |
on_stock_asset(asset) | XtAsset | Asset change |
on_order_error(error) | XtOrderError | Order placement failure |
on_cancel_error(error) | XtCancelError | Order cancellation failure |
on_disconnected() | — | Connection lost |
on_order_stock_async_response(resp) | XtOrderResponse | Async order response |
Advanced Features
- Smart Algorithm Trading: Execute algorithmic orders such as VWAP via
smart_algo_order_async
- Securities Lending: Query available securities, apply for lending, manage contracts
- Bank-Securities Transfer: Transfer funds between bank and securities accounts
- CTP Internal Transfer: Transfer funds between futures and options accounts
- Custom Sectors: Create, manage, and query custom stock groups
- Level 2 Data: l2quote, l2order, l2transaction, l2quoteaux, l2orderqueue, l2thousand (1000-level order book), limitupperformance (consecutive limit-up tracking), snapshotindex, hfiopv, fullspeedorderbook
Usage Tips
- miniQMT must be running on Windows — xtquant connects via local TCP.
session_id must be unique per strategy — different strategies need different IDs.
connect() is a one-time connection — it does not auto-reconnect after disconnection; you must call it again manually.
- Always call
subscribe(account) to receive trading push callbacks.
- Data is cached locally after download — subsequent reads are extremely fast.
- Use
dividend_type='front' to get forward-adjusted K-line data.
- In push callbacks, use async query methods to avoid deadlocks.
- Documentation: http://dict.thinktrader.net/nativeApi/start_now.html
Advanced Examples
Batch Download Full-Market Daily K-Line Data
from xtquant import xtdata
xtdata.connect()
stock_list = xtdata.get_stock_list_in_sector('沪深A股')
print(f"Total {len(stock_list)} A-shares")
batch_size = 50
for i in range(0, len(stock_list), batch_size):
batch = stock_list[i:i+batch_size]
for stock in batch:
try:
xtdata.download_history_data(stock, '1d', start_time='20240101', end_time='20240630')
except Exception as e:
print(f"Failed to download {stock}: {e}")
print(f"Downloaded {min(i+batch_size, len(stock_list))}/{len(stock_list)}")
data = xtdata.get_market_data_ex(
[], stock_list[:10], period='1d',
start_time='20240101', end_time='20240630',
dividend_type='front'
)
for code, df in data.items():
print(f"{code}: {len(df)} records, latest close={df[].iloc[-]}")
Real-Time Quote Monitoring + Conditional Order Trigger
from xtquant import xtdata, xtconstant
from xtquant.xttrader import XtQuantTrader, XtQuantTraderCallback
from xtquant.xttype import StockAccount
import threading
class MyCallback(XtQuantTraderCallback):
def on_stock_order(self, order):
print(f'Order: {order.stock_code} status={order.order_status} {order.status_msg}')
def on_stock_trade(self, trade):
print(f'Trade: {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, 888888)
xt_trader.register_callback(MyCallback())
xt_trader.start()
xt_trader.connect()
account = StockAccount('your_account')
xt_trader.subscribe(account)
target_stock = '000001.SZ'
buy_price = 10.50
sell_price = 11.50
bought = False
def on_tick():
bought
code, tick datas.items():
price = tick[]
()
price <= buy_price bought:
order_id = xt_trader.order_stock(
account, code, xtconstant.STOCK_BUY, ,
xtconstant.FIX_PRICE, buy_price, ,
)
()
bought =
price >= sell_price bought:
order_id = xt_trader.order_stock(
account, code, xtconstant.STOCK_SELL, ,
xtconstant.FIX_PRICE, sell_price, ,
)
()
bought =
xtdata.connect()
():
xtdata.subscribe_quote(target_stock, period=, callback=on_tick)
xtdata.run()
t = threading.Thread(target=run_data, daemon=)
t.start()
xt_trader.run_forever()
Multi-Stock Moving Average Strategy
from xtquant import xtdata, xtconstant
from xtquant.xttrader import XtQuantTrader, XtQuantTraderCallback
from xtquant.xttype import StockAccount
import pandas as pd
xtdata.connect()
stock_pool = ['000001.SZ', '600036.SH', '601318.SH', '000858.SZ', '300750.SZ']
for stock in stock_pool:
xtdata.download_history_data(stock, '1d', start_time='20240101', end_time='20241231')
signals = {}
for stock in stock_pool:
data = xtdata.get_market_data_ex([], [stock], period='1d',
start_time='20240101', end_time='20241231', dividend_type='front')
df = data[stock]
df['ma5'] = df['close'].rolling(5).mean()
df['ma20'] = df['close'].rolling(20).mean()
if len(df) >= 21:
latest = df.iloc[-1]
prev = df.iloc[-2]
if prev['ma5'] <= prev['ma20'] and latest['ma5'] > latest['ma20']:
signals[stock] =
prev[] >= prev[] latest[] < latest[]:
signals[stock] =
:
signals[stock] =
()
stock, signal signals.items():
()
Retrieve Financial Data and Screen Stocks
from xtquant import xtdata
xtdata.connect()
stock_list = xtdata.get_stock_list_in_sector('沪深A股')
xtdata.download_financial_data(stock_list[:100])
for stock in stock_list[:10]:
data = xtdata.get_financial_data([stock])
if stock in data and 'PershareIndex' in data[stock]:
psi = data[stock]['PershareIndex']
if len(psi) > 0:
latest = psi[-1]
roe = latest.get('du_return_on_equity', 0)
eps = latest.get('s_fa_eps_basic', 0)
print(f"{stock}: ROE={roe}, EPS={eps}")
社区与支持
由 大佬量化 (Boss Quant) 维护 — 量化交易教学与策略研发团队。
微信客服: bossquant1 · Bilibili · 搜索 大佬量化 on 微信公众号 / Bilibili / 抖音