深入 MtApi 的 RPC 协议一条 JSON 命令如何在 C# 与 MQL 之间往返【免费下载链接】mtapiMetaTrader API (terminal bridge)项目地址: https://gitcode.com/gh_mirrors/mt/mtapiMtApi是一个 MetaTrader 终端桥接框架terminal bridge它的核心是一条轻量RPC 协议你的 C# 代码把方法调用序列化成JSON经 WebSocket 送达 MetaTrader 终端里运行的 MQL 专家顾问EAMQL 端执行真实交易函数后再用 JSON 把结果原路送回。本文带你完整拆解这条 JSON 命令的往返之旅——从 C# 序列化、分号分隔的消息信封、WebSocket 传输到 MQL 端的 JSON 解析与响应配对。⚡ 一句话总结信封用分号分隔的轻量文本载荷才是 JSON。理解了这一点MtApi 整个协议就通了。一、先看全局C# 到 MQL 的四层桥梁MtApi 并不是直接连接 MT 服务器而是在终端外挂了一个桥分层如下层项目语言/产物职责① 用户层MtApi5C# (.dll)业务 APIBuy/Sell/CopyRates…② 通信层MtClientC# (.dll)WebSocket RPC 客户端③ 服务层MtServiceC (.dll)服务端转发消息④ 桥接层MT5ConnectorC (.dll)导出 C 风格接口给 MQL 调用⑤ 终端层mtapi/MtApi5.mq5MQL5 EA真正执行 MQL 函数消息流向是双向的命令C# → MQL走请求-响应模式事件行情、新 K 线等MQL → C#走推送模式。本文聚焦前者。二、拆解 RPC 协议分号分隔的消息信封2.1 消息类型只有 7 种协议最外层是一个整数消息类型C# 与 C 两端枚举完全一致这是跨语言协议正确性的关键// C# 端定义MtClient/MtMessage.cs#L3-L12 internal enum MessageType { Command 0, Response 1, Event 2, ExpertList 3, ExpertAdded 4, ExpertRemoved 5, ServiceRequest 6 }C 服务端在 mtapi/MtService/MtMessage.h 中有镜像定义分隔符统一为分号MtMessage.h。2.2 线格式wire format长什么样所有消息序列化后都是一行纯文本消息类型;消息体消息体内部再用;分隔字段。以一条Command类型 0为例0;{专家句柄};{命令ID};{命令类型};{JSON载荷}即 mtapi/MtClient/MtMessage.cs 中MtCommand.GetMessageBody()拼出的ExpertHandle;CommandId;CommandType;Payload。而Response类型 1只有三个字段1;{专家句柄};{命令ID};{JSON载荷}MtMessage.cs。一个真实感示例C# 端调用Buy()买 EURUSD线上飞过的字节大致是0;0;42;25;{Volume:0.1,Price:0,Sl:0,Tp:0,Symbol:EURUSD}0→ Command 消息0→ 专家顾问句柄ExpertHandle42→ 自增命令 ID用于配对响应25→ 命令类型Buy 在 mtapi/MtApi5/MtProtocol/Mt5CommandType.cs 中的编号尾部 → 真正的JSON 命令载荷三、一条 JSON 命令的完整往返之旅3.1 出发C# 端序列化 JSON以 mtapi/MtApi5/MtApi5Client.cs 的Buy()为例它把参数塞进字典交给私有方法SendCommandTDictionarystring, object cmdParams new() { { Volume, volume }, { Price, price }, { Sl, sl }, { Tp, tp } }; if (symbol ! null) cmdParams[Symbol] symbol; var response SendCommandFuncResultMqlTradeResult(ExecutorHandle, Mt5CommandType.Buy, cmdParams);SendCommandT的三步MtApi5Client.csJsonConvert.SerializeObject(payload)—— 参数字典 → JSON 字符串交给 mtapi/MtClient/MtRpcClient.cs 的SendCommand()取一个自增commandId登记一个CommandTask再阻塞等待响应默认10 秒超时MtRpcClient的独立发送线程DoWrite()把消息Serialize()后按 ASCII 字节写入 WebSocketMtRpcClient.cs。3.2 中途C 服务端只做搬运工MtServiceC收到文本后按;切开识别出Command用 mtapi/MtService/MtMessage.h 的MtCommand::Parse还原字段再经 mtapi/MT5Connector/MT5Connector.cpp 导出的 C 风格接口转给 MQL 端getCommandType(expertHandle, res, err)—— MQL 端来取命令类型getPayload(expertHandle, res, err)—— MQL 端来取JSON 载荷注意方向是 MQL 在拉取不是 C 在推。3.3 落地MQL 端的轮询与 JSON 解析mtapi/mq5/MtApi5.mq5 中EA 用OnTimer()高频轮询executeCommand()调getCommandType()取命令类型取不到就返回 0 休眠用_executors.TryGetValue(commandType, wrapper)在类型 → 执行器映射表中找到对应函数wrapper.Execute()内部先解析 JSON。EA 内置了一个完整的 JSON 解析器 mtapi/mq5/json.mqh配合一组宏MtApi5.mq5让取值极其简洁string Execute_SymbolInfoDouble() { GET_JSON_PAYLOAD(jo); // 解析出 JSON 载荷 GET_STRING_JSON_VALUE(jo, Symbol, symbol); // 取字符串字段 GET_INT_JSON_VALUE(jo, PropId, prop_id); // 取整型字段 // ...调用 MQL 函数并返回 }GET_*宏会自动检查必填字段缺失时直接返回错误 JSON——参数校验发生在执行之前。3.4 回程JSON 响应 commandId 配对执行器把结果包装成统一信封C# 端对应 mtapi/MtApi5/MtProtocol/Response.cs{ErrorCode:0, ErrorMessage:null, Value: { RetVal:true, Result:{...} }}MQL 调sendResponse(ExpertHandle, response)MtApi5.mq5把 JSON 塞进1;句柄;命令ID;JSON信封原路返回。C# 的接收线程DoReceive()拆包、按commandId查表CommandTask.SetResponse()唤醒那个阻塞在SendCommand里的调用线程——命令 ID 就是请求-响应的回执号这让同一连接上的命令可以任意交错、乱序返回MtRpcClient.cs。最后SendCommandT反序列化ResponseTErrorCode ! 0就抛ExecutionException否则把Value还给你的Buy()。 往返闭环。四、反向通道事件如何从 MQL 推到 C#除了请求-响应协议还有一条推送通道MQL 端用sendEventMT5Connector.cpp发出类型2Event的消息格式为2;{专家句柄};{事件类型};{JSON载荷}。C# 端在 mtapi/MtClient/MtRpcClient.cs 中将其分发为MtEventReceived事件最终变成你在 C# 里订阅的QuoteUpdate、NewBar等回调。也就是说行情推送和 JSON 命令走的是同一条 WebSocket、同一套信封协议。五、这套协议设计的三个聪明之处信封轻、载荷结构化外壳只有几个整数 分号跨 C# / C / MQL 三端解析成本极低复杂数据全部交给 JSON两端都有成熟解析器Newtonsoft json.mqh。枚举双端镜像MessageType、Mt5CommandType在 mtapi/MtApi5/MtProtocol/Mt5CommandType.cs 与 MQL 端严格对应新增 API 只需同步加枚举值 新执行器。命令 ID 配对 超时兜底commandId解耦了发送与接收线程10 秒WaitResponse让终端卡死变成一次可捕获的异常而不是永久挂起。六、源码导航快速上手这套协议想看什么去哪里消息信封与序列化C#mtapi/MtClient/MtMessage.csWebSocket 收发线程mtapi/MtClient/MtRpcClient.cs消息信封与解析Cmtapi/MtService/MtMessage.hMQL↔C 导出接口mtapi/MT5Connector/MT5Connector.cppMQL 端命令轮询执行mtapi/mq5/MtApi5.mq5MQL 端 JSON 取值宏mtapi/mq5/MtApi5.mq5C# 端 JSON 发送核心mtapi/MtApi5/MtApi5Client.cs统一响应结构mtapi/MtApi5/MtProtocol/Response.cs如果你想动手验证可以从 mtapi/Examples/Python/Python_to_MT5/main.py 或 MATLAB 示例 mtapi/Examples/MatLab/AdvancedExample/run.m 入手它们都建立在同一套 RPC 协议之上。读懂上面这条 JSON 命令的来路与归途你就掌握了 MtApi 协议的全部骨架。【免费下载链接】mtapiMetaTrader API (terminal bridge)项目地址: https://gitcode.com/gh_mirrors/mt/mtapi创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考