跳转至

快速开始

QMT Trading Skill 包含两层:QMT Bridge(Windows 上运行 qmt-server)与 Agent Skills(在主力机用自然语言调用 Bridge)。以下先启动 Bridge,再使用 skills/ 工作流。

前提条件

Windows 端(服务端)

  • Python 3.10+
  • QMT 客户端 — 已安装并获得券商账号密码(需联系客户经理开通 miniQMT 权限)
  • xtquant — 通常随 QMT 客户端安装,或 pip install xtquant

网络

  • Windows 和你的主力机在同一局域网下(连同一个路由器 / WiFi)
  • Windows 防火墙放行本项目使用的端口(默认 8000)

1. 安装

git clone https://github.com/atorber/qmt-trading-skill.git
cd qmt-trading-skill

# 安装服务端(含 WebSocket 支持)
pip install -e ".[full]"

# 或者只安装服务端(不含 WebSocket)
pip install -e ".[server]"

如果只需要在远程机器上使用客户端:

# 零依赖安装(仅 HTTP)
pip install -e .

# 含 WebSocket 订阅支持
pip install -e ".[client]"

2. 配置

cp .env.example .env
# 按需编辑 .env

详细配置项请参考 配置参考

3. 启动 QMT 客户端

打开 QMT,勾选 "独立交易" 模式登录,保持窗口运行(可最小化)。

4. 启动 API 服务

# 使用 CLI 命令(推荐)
qmt-server

# 自定义参数
qmt-server --port 8080 --log-level debug

# 启用交易模块
qmt-server --trading --api-key your-secret-key \
    --mini-qmt-path "C:\国金QMT交易端\userdata_mini" \
    --account-id 12345678

也可以使用脚本:

# 前台运行(Ctrl+C 停止)
bash scripts/start.sh

# 后台运行
bash scripts/start-nohup.sh
bash scripts/stop.sh

# Windows
scripts\start.bat
scripts\stop.bat

PM2 守护(崩溃自动拉起,推荐长期运行)

需先安装 PM2npm install -g pm2,并完成 pip install -e ".[server,...]".env 配置。

REM 可选:指定 venv Python
set PM2_PYTHON=C:\path\to\venv\Scripts\python.exe

REM 仅启动 API(读 .env:端口、TRADING_ENABLED、DEFAULT_ACCOUNT 等)
scripts\pm2-start.bat

REM 或手动
pm2 start ecosystem.config.cjs --only qmt-server
pm2 logs qmt-server
pm2 restart qmt-server
scripts\pm2-stop.bat

信用户为默认账户时,在 .env 设置 QMT_BRIDGE_DEFAULT_ACCOUNT=creditQMT_BRIDGE_TRADING_ENABLED=true 即可,无需改 ecosystem.config.cjs

定时下载调度器(独立进程,按需):

pm2 start ecosystem.config.cjs --only qmt-scheduler

开机自启(管理员 PowerShell):pm2 startuppm2 save

日志文件:logs/pm2/。F5 调试仍用 .vscode/launch.json;PM2 用于无断点的后台守护。

每日复盘定时调度(不依赖 Windows 任务计划)

前台常驻,到点自动「生成复盘 + 同步飞书」(需 Bridge、QMT、lark-cli auth 已就绪):

REM 默认每交易日 15:10(.env 可设 DAILY_EVAL_SCHEDULE_TIME)
scripts\daily_eval_scheduler.bat

REM 立即跑一次(测试)
scripts\daily_eval_scheduler.bat --run-now

REM 只生成 Markdown,不上传飞书
scripts\daily_eval_scheduler.bat --run-now --skip-feishu

日志:logs/daily_eval_scheduler.log;状态:reports/daily_eval_scheduler_state.json

5. 验证

在你的 Mac/Linux 浏览器中访问:

http://<Windows局域网IP>:8000/docs

看到 Swagger 文档页面即表示服务正常。也可以用 curl 检查:

curl http://<Windows局域网IP>:8000/api/meta/health

6. Agent Skills(推荐)

仓库提供 Agent Skills:在 Cursor 中用自然语言@skills/qmt-bridge-*/SKILL.md 触发,由 Agent 执行 skills/*/scripts/*.py

pip install -e .
cp .env.example .env
# 编辑 .env:QMT_BRIDGE_API_KEY、端口等
qmt-server --port 8080 --trading   # 示例:启动 Bridge

客户端地址

服务端监听可用 QMT_BRIDGE_HOST=0.0.0.0;Agent 脚本连接请用 127.0.0.1(或局域网 IP),不要写 0.0.0.0

提示词示例:今天账户盈亏多少生成今日交易复盘把今日复盘同步到飞书。完整表见 skills/README.mdAgent Skills复盘报告示例(脱敏):每日复盘报告示例。开发用命令见 开发指南

Python 客户端用法

from qmt_bridge import QMTClient

client = QMTClient(host="192.168.1.100", port=8000)

# 历史 K 线
df = client.get_history("000001.SZ", period="1d", count=60)

# 增强版 K 线,前复权
dfs = client.get_history_ex(
    ["000001.SZ", "600519.SH"],
    dividend_type="front",
    count=60,
)

# 大盘行情一览
indices = client.get_major_indices()

# 实时快照
snapshot = client.get_market_snapshot(["000001.SZ", "600519.SH"])

# 板块
sectors = client.get_sector_list()
stocks = client.get_sector_stocks("沪深A股")

# 财务数据
fin = client.get_financial_data(["000001.SZ"], tables=["Balance"])

# ETF / 期权 / 期货
etfs = client.get_etf_list()
options = client.get_option_list("000300.SH", "20250321")
main_contract = client.get_main_contract("IF.CFE")

# 元数据
markets = client.get_markets()
periods = client.get_periods()
last_date = client.get_last_trade_date("SH")

交易(需要 API Key)

client = QMTClient(host="192.168.1.100", api_key="your-secret-key")

# 下单
order_id = client.place_order(
    stock_code="000001.SZ",
    order_type=23,        # 买入
    order_volume=100,
    price_type=5,         # 最新价
)

# 查询
orders = client.query_orders()
positions = client.query_positions()
asset = client.query_asset()

# 撤单
client.cancel_order(order_id)

WebSocket 实时订阅

import asyncio

def on_tick(data):
    print(data)

# 实时行情
asyncio.run(client.subscribe_realtime(
    stocks=["000001.SZ", "600519.SH"],
    callback=on_tick,
))

# 全市场行情
asyncio.run(client.subscribe_whole_quote(
    codes=["SH", "SZ"],
    callback=on_tick,
))