Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

2233admin/qmtcli

Open more actions menu

Repository files navigation

qmtcli

tests Python License

中文 | English

给 QMT / XtQuant 装一层稳定的接口,让任何语言、任何 Agent 都能安全稳定的调用它。

现状:60+ 条 CLI 子命令;对照官方 xtdata 文档逐条核对 43 个函数(见 docs/xtdata-alignment.md)、对照 xttrader 文档核对 25 组查询/交易接口 (见docs/xttrader-alignment.md);267 个自动化测试全绿, xtquant 全部 fake 掉,CI 不需要真实 QMT 环境;每周由 CI 里的 doc-drift job 自动重新核对一次 是否跟官方文档产生了漂移。

写过 QMT 自动化的人都懂那种别扭:xtquant 只塞在券商客户端安装目录里,直接 import 意味着 你的脚本、Notebook、Agent 全得绑死在那一个 Python 环境上。想换成 Rust/Go 写的行情引擎?想接一个 LLM Agent 帮你盯盘、判断异常、写交易日志?DataFrame 怎么序列化、NaN 怎么处理、每个字段该信谁的 编码,全变成你自己的事。

qmtcli 就是为了把这些活一次做完:本机起一个小进程,喂 JSON 进去,吐 JSON 出来,背后连的还是 你已经登录的那个 QMT 客户端。迅投官方 QMT/XtQuant API(见 新手教程)提供的环境诊断、行情查询、账户 查询和带基础保护的股票委托能力,都能通过这份稳定的 stdin/stdout JSON 契约一一调到。

qmtcli local JSON bridge

qmtcli 不安装或启动 QMT 交易客户端本身,不保存凭据,不绕过券商风控,也不启动网络服务——但 它会自动探测并接好本机已安装的 XtQuant SDK 环境(优先用 venv/pip 里的 xtquant,找不到再退回 QMT 自带的那份,见安装)。使用前需要先在本机安装并登录 QMT。

适合谁

  • 想让 LLM Agent(Claude、GPT、本地模型)直接查行情、看持仓、下单的人——qmtcli 一条 命令接进 ,工具从能力清单自动生成,不用手写第二套注册表。
  • 想用 Rust、Go、Node.js 写量化系统,又不想专门为了调 QMT 起一个 Python 服务的人。
  • 想要一份稳定的 JSON 链接,而不是每次券商升级 QMT 就得重新猜 xtquant 参数和字段变化的人。
  • 需要在 CI 里跑测试,但构建机上根本没装 QMT 的人——测试套件 fake 了 xtquant,CI 不用真实 券商环境也能跑通。

快速演示

发现命令能力:

qmtcli capabilities
qmtcli schema
qmtcli examples

执行一次 JSON 请求:

Get-Content examples\status.json | qmtcli rpc

启动给 Agent 或脚本使用的 JSONL 循环:

qmtcli server

成功响应:

{"ok":true,"data":{}}

失败响应:

{"ok":false,"error":"message"}

如果请求里带 id,响应会原样带回。

为什么需要

QMT 把 xtquant 放在券商客户端安装目录里。直接在交易机上写 Python 脚本时还算方便,但对 Agent 或基于进程的自动化程序来说,直接 import SDK 并不稳定——依赖 QMT 自带的 numpy/pandas 版本, 一次静默升级就可能改变 DataFrame 的序列化方式,或者悄悄丢掉一个字段。qmtcli 把这些不稳定 留在本机、留给一个可以随时重启的子进程,对外只提供一份简单、可测试、跨版本稳定的 JSON 合约:

  • capabilitiesschemaexamples 用于能力发现;
  • rpc 用于 stdin/stdout 单请求;
  • server 用于逐行 JSON 请求;
  • 对只读调用、escape hatch、下单、撤单做明确标记;
  • 测试里 fake xtquant,CI 不需要真实券商环境。

只要一个运行时能启动本地进程并交换 JSON,就能使用它——Python、Rust、Go、Node.js、Shell 脚本, 或 LLM Agent,都能直接对接,不需要任何语言专属的 SDK 或绑定。

功能

  • 自动发现常见 Windows QMT SDK 路径;优先使用已安装在当前环境(venv/pip)的 xtquant,而不是 QMT 自带的那份(见安装)。
  • statusdoctor 环境诊断,包含 SDK 来源(environment / qmt_bundled / missing)、 xtquant 版本号、xtdc 可用性。
  • 行情命令:交易日历、交易日期、板块、tick、K 线、本地缓存 K 线(local-data)、全推 K 线 (full-kline)、L2 数据、合约/ETF/可转债/新股/指数权重元数据、财务数据。
  • sector 命令族:创建、填充、删除本地自定义板块(create-foldercreateaddremove-stocksremovereset)。
  • watch:仅 CLI 的实时行情流式推送(JSONL 输出到 stdout),基于 subscribe_quote/ subscribe_whole_quote,阻塞直到 Ctrl+C——见CLI 流式推送
  • mcp:stdio MCP 服务,把 qmtcli 命令暴露成 MCP 工具,从 AGENT_CAPABILITIES 生成——见 MCP Server
  • fields:从文档附录提取的静态 xtdata 字段名参考字典(tick、kline、balance 等),完全离线, 不需要 QMT 环境。
  • 感知 pandas 的 JSON 输出:xtdata 返回的 DataFrame/Series 会序列化成逐行记录(时间索引会保留成 普通列),NaN/NaT/pd.NA/numpy 标量都会转成合法的 JSON 值,而不是非法的 NaN token 或读不懂的 对象转储。
  • download 命令用于把数据下载进本地 QMT 缓存(历史行情、财务数据、板块、指数权重、可转债、 ETF 信息、节假日、合约信息)。
  • 账户查询:资产、持仓、委托(支持 --cancelable-only)、成交。
  • 交易查询命令:持仓统计、信用/融资融券查询、新股额度与数据、账号信息/状态、普通柜台资金/持仓 查询——见交易查询命令
  • 固定价 A 股 buysellcancel
  • data-call 调用公开的 xtquant.xtdata 方法。
  • trade-call 调用公开的 XtQuantTrader 方法。
  • 可选的独立 xtdatacenter(xtdc)数据模式,通过 --xtdc-token 开启(实验性)——见 独立数据模式
  • Agent / 脚本协议命令:capabilitiesschemaexamplesrpcserver
  • 定时运行的 doc-drift GitHub Action(每周一次,也支持手动触发)会对照官方文档页面重新核对下面 的对齐矩阵,一旦文档新增的函数还没体现在矩阵里就自动开 issue;见 scripts/check_doc_drift.py

完整的函数对命令覆盖矩阵(对照官方 xtdata 文档xttrader 文档)见 docs/xtdata-alignment.mddocs/xttrader-alignment.md

安装

推荐:用 sdk extra 安装,让 xtquant/pandas/numpy 来自当前环境而不是 QMT 自带的 site-packages;这样券商 QMT 客户端只需要提供本地交易/行情服务,不必再提供 Python SDK 本身:

uv sync --extra dev --extra sdk
pip install -e ".[dev,sdk]"

不装 sdk extra 时的兜底方案仍然可用——找不到已安装的 SDK 时,qmtcli 会回退到 QMT 安装目录自带 的 xtquant/numpy/pandas——但自带版本可能比当前文档旧(比如部分自带版本缺少 get_period_list),而且绝不能让它自带的 numpy 盖过 venv 自己的 numpyqmtcli doctor 会 报告最终生效的来源,字段是 sdk_source。详见 Runtime caveats(英文)。

本地开发:

uv sync --extra dev
uv run qmtcli status

editable pip 安装:

pip install -e .[dev]
qmtcli status

Agent 和脚本用法

发现能力:

qmtcli capabilities
qmtcli schema
qmtcli examples

单次 RPC:

Get-Content examples\status.json | qmtcli rpc
Get-Content examples\data_call.json | qmtcli rpc

JSONL 循环:

.\examples\jsonl_server.ps1

通用集成说明见 examples/agent_tool.md。录制演示的脚本见 docs/demo_storyboard.md

所有行情命令(calendarbarssector-stocksdownload 等)现在也能通过 rpc/server 调用,不再局限于 CLI;把对应的 CLI 参数名当 JSON 字段发送即可,例如 {"command":"bars","symbols":["600519.SH"],"period":"1d"}。命令名支持短横线或下划线两种写法 (sector-stockssector_stocks)。

Server 流式推送

只有 server 模式支持 subscribesubscribe_wholeunsubscribe,分别包装了回调式的 xtdata.subscribe_quotesubscribe_whole_quoteunsubscribe_quote

{"command":"subscribe","symbol":"600519.SH","period":"1d"}
{"command":"subscribe_whole","symbols":["600519.SH","000001.SZ"]}
{"command":"unsubscribe","seq":1}

订阅成功会返回 {"ok":true,"data":{"seq":1}},此后 xtquant 每次推送行情都会单独打印一行 JSONL, 带 event 字段而不是 ok,和普通响应交替出现在同一个 stdout 流里:

{"ok":true,"data":{"seq":1}}
{"event":"quote","seq":1,"symbol":"600519.SH","data":{"600519.SH":{"lastPrice":1500.0}}}

单次的 rpc 命令和 CLI 都会拒绝订阅命令,返回 {"ok":false,"error":"subscribe commands require server mode"},因为订阅只有在 server 让进程 常驻时才有意义。

CLI 流式推送(watch)

watchserver 模式 subscribe/subscribe_whole 的仅 CLI 替代方案:直接发起订阅,然后 阻塞在 xtdata.run() 里,每次行情推送打印一行 JSONL,直到被中断(Ctrl+C 会干净地以退出码 0 结束)。不支持通过 rpc/server 调用。

qmtcli watch 600519.SH
qmtcli watch 600519.SH 000001.SZ --period 1m
qmtcli watch 600519.SH 000001.SZ --whole
{"event":"quote","symbol":"600519.SH","data":{"600519.SH":{"lastPrice":1500.0}}}

MCP Server

qmtcli mcp 会启动一个 stdio MCP(Model Context Protocol)服务,把 qmtcli 命令暴露成 MCP 工具。以能力元数据为唯一事实来源:所有工具都从 AGENT_CAPABILITIES 生成,每次工具调用都 走和 rpc/server 相同的 rpc 派发逻辑——没有第二套命令注册表。

安装 mcp extra:

uv sync --extra mcp

直接运行(走 stdio 上的 JSON-RPC;除此之外不会再向 stdout 打印任何内容):

qmtcli mcp

注册进 Claude Code:

claude mcp add qmt -- uv run --directory D:/projects/qmtcli --extra mcp qmtcli mcp

工具名是 qmt_<name>,短横线会替换成下划线,例如 qmt_full_tickqmt_sector_stocksqmt_account_infos。这里没有像 CLI 那样常驻的 --account/--path——每个交易查询/账户类工具 都在每次调用时接受可选的 path/account/account_type 参数。

以下按设计被排除:buysellcancel(下单/撤单)和 trade_call(直接暴露完整 XtQuantTrader 方法面的非受控 escape hatch)——需要下单交易请直接使用 CLI。watch 以及 subscribe/subscribe_whole/unsubscribe 三件套也被排除(分别是仅 CLI、仅 server 的流式推送, 不适合一次性的工具调用)。其余的——statusdoctordata_callfieldsdownload、所有 行情命令,以及所有交易查询(assetpositionsorderstrades 等)——都可以使用。

没有安装 mcp extra 时,qmtcli mcp 会打印 {"ok":false,"error":"mcp extra is not installed; pip install 'qmtcli[mcp]'"} 并以退出码 1 结束。

QMT 路径

可以传 QMT 安装根目录,也可以传 userdata_mini 目录:

qmtcli --path D:\DFZQxtqmt_client_real_win64 doctor
qmtcli --path D:\DFZQxtqmt_client_real_win64\userdata_mini --account ACCOUNT_ID asset

如果不传 --path,会检查这些默认路径:

  • D:\DFZQxtqmt_client_real_win64
  • D:\DFZQxtqmt_client_test_win64
  • C:\DFZQxtqmt_client_real_win64
  • C:\DFZQxtqmt_client_test_win64

预期 SDK 位置:

<QMT root>\bin.x64\Lib\site-packages\xtquant

常用命令

诊断:

qmtcli status
qmtcli doctor
python -m qmtcli status

行情:

qmtcli calendar SH
qmtcli trading-dates SH --count 5
qmtcli sector-list
qmtcli sector-stocks 沪深A股
qmtcli full-tick 600519.SH 000001.SZ
qmtcli bars 600519.SH --period 1d --count 100
qmtcli local-data 600519.SH --period 1d --count 100
qmtcli full-kline 600519.SH --period 1m
qmtcli instrument-detail 600519.SH
qmtcli instrument-type 600519.SH
qmtcli divid-factors 600519.SH
qmtcli holidays
qmtcli period-list
qmtcli ipo-info
qmtcli cb-info 123001.SZ
qmtcli etf-info
qmtcli index-weight 000300.SH
qmtcli financials 600519.SH --tables Balance

静态字段名参考字典(完全离线,不需要 QMT 环境):

qmtcli fields
qmtcli fields tick
qmtcli fields balance

L2 命令需要券商的 Level-2 行情权限,且不在官方 xtdata 文档页范围内:

qmtcli l2-quote 600519.SH
qmtcli l2-order 600519.SH
qmtcli l2-transaction 600519.SH

把数据下载进本地 QMT 缓存;这些命令在 SDK 下载完成后返回,本身不会打印行情数据—— 行情数据请用上面的读取命令:

qmtcli download history 600519.SH --period 1d
qmtcli download financials 600519.SH --tables Balance
qmtcli download sectors
qmtcli download index-weight
qmtcli download cb
qmtcli download etf
qmtcli download holidays
qmtcli download history-contracts

管理本地自定义板块(只修改本地板块定义;danger: mutates_local_data):

qmtcli sector create-folder MyGroup --parent 我的自定义板块
qmtcli sector create MySector --parent 我的自定义板块
qmtcli sector add MySector 600519.SH 000001.SZ
qmtcli sector remove-stocks MySector 600519.SH
qmtcli sector reset MySector 600519.SH
qmtcli sector remove MySector

账户和交易命令需要 --account

qmtcli --account ACCOUNT_ID asset
qmtcli --account ACCOUNT_ID positions
qmtcli --account ACCOUNT_ID orders
qmtcli --account ACCOUNT_ID orders --cancelable-only
qmtcli --account ACCOUNT_ID trades
qmtcli --account ACCOUNT_ID buy 600519.SH 100 1500.00
qmtcli --account ACCOUNT_ID sell 600519.SH 100 1500.00
qmtcli --account ACCOUNT_ID cancel ORDER_ID

交易查询命令

这些命令包装了具名的 XtQuantTrader 查询方法;完整映射见 docs/xttrader-alignment.md(英文)。大部分需要 --account

qmtcli --account ACCOUNT_ID position-statistics
qmtcli --account ACCOUNT_ID credit-detail
qmtcli --account ACCOUNT_ID stk-compacts
qmtcli --account ACCOUNT_ID credit-subjects
qmtcli --account ACCOUNT_ID credit-slo-code
qmtcli --account ACCOUNT_ID credit-assure
qmtcli --account ACCOUNT_ID ipo-limit
qmtcli --account ACCOUNT_ID com-fund
qmtcli --account ACCOUNT_ID com-position

ipo-dataaccount-infosaccount-status 包装的 XtQuantTrader 方法本身不带账户参数,所以这 三个命令的 --account 是可选的——qmtcli 仍会连接 QMT 会话,只是跳过订阅账户:

qmtcli ipo-data
qmtcli account-infos
qmtcli account-status

Escape Hatches

data-call 调用公开的 xtquant.xtdata 方法:

qmtcli data-call get_stock_list_in_sector --args "[\"沪深A股\"]"
qmtcli data-call get_cb_info --args "[\"123001.SZ\"]"

trade-call 在连接账户后调用公开的 XtQuantTrader 方法。默认会把 StockAccount 对象 放在位置参数最前面:

qmtcli --account ACCOUNT_ID trade-call query_stock_orders
qmtcli --account ACCOUNT_ID trade-call some_method --args "[1,2]" --kwargs "{\"flag\":true}"
qmtcli --account ACCOUNT_ID trade-call method_without_account --no-account

_ 开头的私有方法名会被阻止。

独立数据模式(xtdc,实验性)

--xtdc-token(或环境变量 QMTCLI_XTDC_TOKEN)会开启独立 xtdatacenter 数据模式:在执行任何命令 之前,qmtcli 会先调用 xtquant.xtdatacenter.set_token().init(),这样 xtdata 调用就能走 迅投投研的独立数据服务,而不必依赖本地 QMT 客户端:

$env:QMTCLI_XTDC_TOKEN = "YOUR_TOKEN"
qmtcli calendar SH

qmtcli --xtdc-token YOUR_TOKEN --xtdc-port 58620 calendar SH

这需要有效的迅投投研数据 token,且目前是实验性功能——只验证到 init() 调用成功,还没有走通 端到端的真实数据链路。--xtdc-port(默认 58620)已经接入命令行,但还没有对接到具体的 xtdatacenter 调用上。qmtcli doctor 会用 xtdc_available 字段报告 xtquant.xtdatacenter 模块本身 是否可导入。详见 Runtime caveats(英文)。

JSON 请求示例

{"command":"status"}
{"command":"data_call","method":"get_stock_list_in_sector","args":["沪深A股"]}
{"command":"buy","account":"ACCOUNT_ID","symbol":"600519.SH","volume":100,"price":1500.0}

server 模式下一行输入对应一行输出。请求里的 id 会被带回。

安全边界

  • 本地使用:server 只读 stdin、写 stdout,不打开 socket。
  • 不下载或自动安装券商软件。
  • 不保存账号密码或登录凭据。
  • 不自动重试下单。
  • capabilities 会标记下单和撤单能力为危险动作;download 因为写入本地 QMT 缓存,被标记为 downloads_datasector 因为创建/修改本地自定义板块,被标记为 mutates_local_data
  • A 股委托数量必须是正的 100 倍数。
  • 委托价格必须大于 0。
  • 阻止调用 _ 开头的 xtdata / XtQuantTrader 方法。
  • 账户权限、风控检查和最终成交仍由 QMT 和券商控制。

命令帮助

qmtcli --help
qmtcli capabilities --help
qmtcli schema --help
qmtcli examples --help
qmtcli data-call --help
qmtcli download --help
qmtcli sector --help
qmtcli fields --help
qmtcli trade-call --help
qmtcli watch --help
qmtcli rpc --help
qmtcli server --help
qmtcli mcp --help

开发

uv run --extra dev pytest -q
uv run --extra dev ruff check .
uv build

从文档附录重新生成静态 fields 字典,并检查对齐矩阵是否和官方文档产生了漂移(CI 里每周也会自动 跑一次,见 .github/workflows/doc-drift.yml):

python scripts/extract_doc_fields.py
python scripts/check_doc_drift.py

给代码 Agent 的项目说明见 AGENTS.md

当前仓库保留了 PyPI 打包元数据,但不在当前工作流中发布。

反馈

如果 qmtcli 帮你省下了对接 QMT 的麻烦,欢迎点个 star——这是让更多人发现它最直接的方式。 用出问题、缺了什么命令、想接的 Agent 框架不顺手,也欢迎开 issue 或直接提 PR。

About

本地 JSON CLI,桥接已登录的 QMT/XtQuant 客户端,供脚本与 Agent 调用。Local JSON CLI bridging a logged-in QMT/XtQuant client for scripts and agents.

Topics

Resources

Contributing

Stars

Watchers

Forks

Releases

Packages

Used by

Contributors

Languages

Morty Proxy This is a proxified and sanitized view of the page, visit original site.