首页 / 交易学院 / 小布知识库 / MQL5-RPC:用 XML-RPC 让 MQL5 调用远程服务、搞定跨语言通信
MQL5-RPC:用 XML-RPC 让 MQL5 调用远程服务、搞定跨语言通信
🌐

MQL5-RPC:用 XML-RPC 让 MQL5 调用远程服务、搞定跨语言通信

MQL5 编程 难度 · 高阶 2011 14 分钟阅读
XML-RPC远程调用HTTPMQL5-RPC跨语言

有时候 EA 不能只靠自己:要查外部行情服务、要把锦标赛结果拉来分析、要和用别的语言写的后台通信。MQL5 没有内置 REST 客户端,但可以用 WinInet 发 HTTP。XML-RPC 就是在 HTTP 之上、用 XML 编码参数的轻量远程调用协议,刚好适合这类场景。

一、XML-RPC 是什么

XML-RPC = XML Remote Procedure Call。它用 XML 对参数编解码、用 HTTP 传输,调用另一台机器或另一个程序暴露的“远程方法”。任何实现了 XML-RPC 协议栈、能联网的语言都能互相调用——甚至可以用它调用本机另一种语言写的方法。本协议简单、成熟,是打通 MQL5 与外部世界的低门槛方案。

MQL5-RPC 框架是作者从零实现的 XML-RPC 客户端,基于 WinInet 思路但更完整。它目前覆盖大部分调用子集(base64 待补),已经能让你从 MetaTrader 5 发起大批量 XML-RPC 调用。

二、XML-RPC 数据模型

规范定义六种基本类型:int、double、boolean、string、datetime、base64,外加两种复合类型:array(数组,可含任意基本类型)和 struct(结构,名称-值对,像关联数组/对象属性)。数组元素塞在 <value><array><data> 里,结构用 <member><name>+<value> 表达。

<!-- 一个 struct 示例 -->
<value>
  <struct>
    <member><name>AccountHolder</name><value><string>John Doe</string></value></member>
    <member><name>Age</name><value><int>77</int></value></member>
    <member><name>Equity</name><value><double>1000000.0</double></value></member>
  </struct>
</value>

三、请求与响应结构

请求由报头 + 有效负荷组成:报头指定 POST 方法、路径、Host、Content-Type: text/xml 和长度;有效负荷是 XML,根元素必须是 <methodCall>,内含 <methodName> 和若干 <params>。响应根元素是 <methodResponse>,成功时含 <params>,失败时含 <fault>。注意 XML-RPC 没 standardize 错误码,错误信息因实现而异。

<!-- 请求:调用 multiply(8654.41, 7234.00) -->
POST /xmlrpc HTTP/1.1
Content-Type: text/xml
Content-Length: 188
<?xml version="1.0"?>
<methodCall>
  <methodName>multiply</methodName>
  <params>
    <param><value><double>8654.41</double></value></param>
    <param><value><double>7234.00</double></value></param>
  </params>
</methodCall>
<!-- 成功响应 -->
<methodResponse><params><param><value><double>62606001.94</double></value></param></params></methodResponse>

四、MQL5-RPC 框架的数据模型

作者实现里最难的一步,是给 MQL5 建一套数据模型。设计原则是“对用户尽量简单”:请求参数统一用 CObject* 指针数组(指向各类 CArrayXxx)。标准库已有 CArrayInt/Double/String,作者补了 CArrayBool、CArrayDatetime、CArrayMqlRates,完成基本类型与结构数组。数组只含一个元素时,XML 里就包成单个 <value>。

// 把多种数组加进参数列表(节选)
CArrayObj* params = new CArrayObj;
CArrayInt*    arrInt    = new CArrayInt;    arrInt.Add(1001); arrInt.Add(1002);
CArrayDouble* arrDouble = new CArrayDouble; arrDouble.Add(1001.0);
CArrayString* arrString = new CArrayString; arrString.Add("s1001.0");
CArrayDatetime* arrDt   = new CArrayDatetime; arrDt.Add(TimeCurrent());
CArrayBool*   arrBool  = new CArrayBool;   arrBool.Add(false); arrBool.Add(true);
params.Add(arrInt); params.Add(arrDouble); params.Add(arrString);
params.Add(arrDt);  params.Add(arrBool);

五、实战一:调用外部 Forex 网站服务

第一个例子是用 MQL5-RPC 客户端去调用某个外部 Forex 网站暴露的 XML-RPC 网络服务——比如查询报价、历史或分析接口。只要对方服务遵循 XML-RPC 规范,你用 CArrayXxx 组装参数、指定 methodName,框架就把请求发出去并解析返回。这是把“外部数据”拉进 EA 的最直接方式。

六、实战二:自建 XML-RPC 服务器分析锦标赛

第二个例子是自己写个 XML-RPC 服务器,用来解析、分析并实时提供 2011 年自动交易锦标赛的结果。客户端(也是 MQL5)连上来请求方法,服务器算好返回。因为服务器在独立线程跑,不论多少客户端连入都不阻塞、不拖慢 MetaTrader 5 或你的交易策略——这是把重计算挪出终端的好范式。

XML-RPC 走 HTTP,容易被防火墙/代理拦。生产环境注意:目标服务要允许你的服务器 IP、路径要对、Content-Length 必须算准;自建服务器记得用异步线程,别让网络 I/O 卡住 OnTick。

七、小结

XML-RPC 给 MQL5 开了一扇“调用外部世界”的门:用 HTTP+XML 把参数和方法名传出去,把结果解回来。MQL5-RPC 框架把 CArrayXxx + CObject* 封装好,让你不必手搓 XML。两个实战——调外部 Forex 服务、自建锦标赛分析服务器——展示了“拉数据”和“搬重计算”两类典型用法。当你需要 EA 和别的系统对话时,它比纯 WinInet 文本收发更结构化、更省心。

常见问题

XML-RPC 用 XML 编码参数、走 HTTP POST,调用的是“具名方法”(methodCall/methodName),结构固定;REST 多用 JSON、靠 URL+HTTP 动词(GET/POST…)表达资源操作,更灵活轻量。MQL5 没有内置 REST 客户端,但用 WinInet 发 HTTP 同样能调 REST;XML-RPC 胜在协议简单、请求/响应格式统一,适合固定方法的远程调用。
可以,通过 WinInet(#import WinInet.dll 或文章里的 MQL5-RPC 框架)发 HTTP POST。XML-RPC 本质就是在 HTTP 之上用 XML 包装参数,所以“能发 HTTP”是前提。纯文本收发要自己拼/解析报文,用 XML-RPC 框架则省去这步。
框架覆盖 int、double、boolean、string、datetime 基本类型,以及 array 和 struct 复合类型;额外提供 CArrayBool、CArrayDatetime、CArrayMqlRates 来映射 MQL5 特有结构。base64 类型作者写明将在后续版本补充。单元素数组在 XML 里会包成单个 <value>。
用 MQL5-RPC:把参数按类型放进 CArrayInt/CArrayDouble/CArrayString 等,统一加进 CArrayObj* params,指定 methodName,框架负责生成 <methodCall> 并通过 WinInet 发出,再把 <methodResponse> 解析回来。你只需关心“传什么、调哪个方法”。
失败响应在 <fault> 里返回字符串(XML-RPC 没统一错误码,信息因实现而异)。排查顺序:确认目标服务可达且路径正确、Content-Length 算准、methodName 拼对、参数类型匹配;被防火墙/代理拦截时请求根本到不了服务端,要先排除网络层。