MetaTrader MCP Server实时行情推送:WebSocket Tick流设计与实现指南
MetaTrader MCP Server实时行情推送:WebSocket Tick流设计与实现指南
MetaTrader MCP Server 是一个让 AI 助手通过 MetaTrader 5(MT5)平台进行交易的开源 MCP 服务器。除了 MCP 与 REST 接口,项目还内置了 WebSocket 行情服务(metatrader-quote-server),它会把 MT5 终端里的实时 Tick 报价——Bid/Ask、点差、成交量——以 JSON 消息持续推送到任意 WebSocket 客户端,非常适合做行情看板、交易机器人前端和实时监控。本文带你快速启动这项实时行情推送能力,并拆解 Tick 流背后的设计细节。
🚀 快速开始:三条命令启动实时行情推送
先安装 PyPI 上的发布包:
pip install metatrader-mcp-server
然后一行命令启动 WebSocket 行情服务器(记得把账号换成你自己的 MT5 登录信息):
metatrader-quote-server --login YOUR_LOGIN --password YOUR_PASSWORD --server YOUR_SERVER
服务默认监听 ws://0.0.0.0:8765。用任意 WebSocket 客户端连接即可收到推送,例如:
websocat ws://localhost:8765
连接成功后,你会先收到一条 connected 消息,随后每当报价发生变化就会收到一条 tick 消息。启动入口实现在 src/metatrader_quote/cli.py,包内的命令注册见 pyproject.toml。
⚙️ 配置速查:端口、品种与轮询间隔
行情服务支持两种配置方式:命令行参数与 QUOTE_ 前缀的环境变量,优先级为:CLI 参数 > 环境变量 > 默认值。
| 参数 | 环境变量 | 默认值 | 说明 |
|---|---|---|---|
--host |
QUOTE_HOST |
0.0.0.0 |
WebSocket 绑定地址 |
--port |
QUOTE_PORT |
8765 |
监听端口 |
--symbols |
QUOTE_SYMBOLS |
XAUUSD,USOIL,GBPUSD,USDJPY,EURUSD,BTCUSD |
逗号分隔的推送品种 |
--poll-interval |
QUOTE_POLL_INTERVAL_MS |
100 |
Tick 轮询间隔(毫秒) |
默认配置定义在 src/metatrader_quote/config.py。两个实用技巧:
- 不传
--symbols时,服务会推送账户里全部可用品种,适合"全市场监控"场景; - 调大
--poll-interval可以降低对 MT5 终端的压力,对精度要求不高的场景建议设为 200~500ms。
📨 消息协议:三类 JSON 消息
Tick 流只使用三类消息,协议简单清晰:
① 连接确认(connected)——携带品种列表与轮询间隔:
{"type": "connected", "symbols": ["XAUUSD", "EURUSD"], "poll_interval_ms": 100}
② 报价更新(tick)——bid、ask 或 volume 任一变化即推送:
{"type": "tick", "symbol": "XAUUSD", "bid": 2345.67, "ask": 2345.89, "spread": 0.22, "spread_points": 22, "volume": 1234, "time": "2026-03-14T10:30:45+00:00"}
③ 错误提示(error)——品种不存在或数据不可用时:
{"type": "error", "symbol": "INVALID", "message": "Symbol not found or data unavailable"}
每条 tick 消息还附带了 bid_string/ask_string(按品种精度格式化的字符串价格)和 buy_point_value/sell_point_value(每点盈亏价值),方便前端直接渲染、策略直接计算。
🔍 设计与实现:让 Tick 流稳定轻量的四个关键
核心实现集中在 src/metatrader_quote/server.py 的 QuoteServer 类,值得学习的细节有四个:
1️⃣ 变更检测,只推"真的变了"的报价
_tick_changed 会对比上一轮缓存,只有 bid、ask 或 volume 发生实际变化才触发广播。盘后、周末或行情平稳时,网络流量趋近于零,客户端不会被无意义的重复数据刷屏。
2️⃣ 缓存最新 Tick,后连接者"秒开"
服务端持续把每个品种的最新报价缓存在 _last_ticks 中。新客户端连上后,_handler 会先把 connected 消息、再把全部缓存报价补发过去——新接入的页面不需要空等下一个变化,首屏即有数据。
3️⃣ 单线程执行器,串行化所有 MT5 调用
MT5 Python SDK 并非线程安全,多个协程并发查询容易出问题。QuoteServer 用一个 max_workers=1 的 ThreadPoolExecutor,把 get_symbol_price、get_symbol_info 等调用全部丢进同一条线程串行执行(见 _poll_ticks),在 asyncio 事件循环与同步 SDK 之间做了干净的分隔。
4️⃣ 异步广播,支持任意多客户端
_broadcast 用 asyncio.gather 把同一份消息并发发给所有在线连接,并容忍个别客户端掉线(return_exceptions=True)。这意味着一个 MT5 连接可以同时喂饱 N 个行情看板,而不会占用 N 份终端资源。
此外,服务启动时会预先加载各品种的 digits(价格小数位)与 point(最小变动单位),从而能准确计算 spread_points 并生成与 MT5 界面一致的格式化价格字符串,逻辑见 _load_symbol_meta。
📁 核心源码文件索引
想深入阅读或二次开发,可以从这些文件入手:
- 行情服务端核心:src/metatrader_quote/server.py
- 命令行入口:src/metatrader_quote/cli.py
- 默认配置(QUOTE_ 环境变量):src/metatrader_quote/config.py
- 底层行情获取封装:src/metatrader_client/market/get_symbol_price.py、docs/metatrader_client/market/get_symbol_price.md
- K 线等其余行情工具文档:docs/metatrader_client/_market.md
💡 典型应用场景
- 实时看板:前端通过 WebSocket 订阅
tick消息,渲染价格跳动卡片; - 策略信号源:把
spread_points与买卖价差纳入策略,点差过大时暂停开仓; - 监控告警:监听
error消息,品种数据异常时第一时间告警; - AI 交易联动:与同项目的 MCP Server(见 src/metatrader_mcp/server.py)配合,AI 负责下单,行情流负责盯盘。
⚠️ 安全提示:
metatrader-quote-server默认绑定0.0.0.0且不带鉴权,公网部署时请配合防火墙限制 IP、反向代理或 SSH 隧道;本地使用建议加--host 127.0.0.1。
总结:MetaTrader MCP Server 的 WebSocket Tick 流用"变更检测 + 缓存补发 + 单线程串行化 + 异步广播"四个设计点,把 MT5 的同步 SDK 包装成了一条轻量、稳定、支持多客户端的实时行情推送管道——一条命令即可让你的交易工具接上 MT5 的实时脉搏。
