快速开始¶
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 守护(崩溃自动拉起,推荐长期运行)¶
需先安装 PM2:npm 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=credit 与 QMT_BRIDGE_TRADING_ENABLED=true 即可,无需改 ecosystem.config.cjs。
定时下载调度器(独立进程,按需):
pm2 start ecosystem.config.cjs --only qmt-scheduler
开机自启(管理员 PowerShell):pm2 startup → pm2 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.md 或 Agent 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,
))