MQL5-RPC来自 MQL5 的远程过程调用:针对乐趣及获利的网络服务访问及 XML-RPC 自动交易锦标赛分析程序(基础篇)
📘

MQL5-RPC来自 MQL5 的远程过程调用:针对乐趣及获利的网络服务访问及 XML-RPC 自动交易锦标赛分析程序(基础篇)

第 1/3 篇

◍ 用 MQL5 直接拉取 XML-RPC 做锦标赛分析

MQL5 环境里可以通过 WebRequest 发起 XML-RPC 调用,把远程自动交易锦标赛的数据拉回 MT5 本地做统计。对做价格行为研究的人来说,这等于把线上赛的数据源变成了可复算的样本库,而不是只看排行榜截图。

  • 年 5 月那篇原始示例里,作者 investeo 就用这套办法访问了当时锦标赛的远程接口,累计被社区查看 2749 次、评论 17 条,说明这类玩法在早期就有明确需求。外汇与贵金属品种波动大、杠杆高,用历史赛果做样本推算时务必当作高风险参考,别直接当实盘信号。

本质上就是让 EA 或脚本替你跑远程过程调用:传参、收 XML、本地解析。下面这段是当时示例里最关键的请求骨架,注意 User-Agent 和 Content-Type 必须按服务端要求带。

MQL5 / C++
class="type">class="kw">string endpoint="http:class=class="str">"cmt">// championship.mql5.com/rpc";
class="type">class="kw">string post="<?xml version=\"class="num">1.0\"?><methodCall><methodName>competition.results</methodName><params></params></methodCall>";
class="type">char post_data[],result[];class="type">class="kw">string hdr="User-Agent: MT5\r\nContent-Type: text/xml\r\n";
class="type">int res=WebRequest("POST",endpoint,hdr,class="num">3000,post_data,result);

「MQL5-RPC 框架是什么」

最近几周搭建的 MQL5-RPC 框架,核心由三部分组成:XML-RPC 访问基础、MQL5 端实施说明,以及两个可直接跑的真实用例。 第一个用例是对外部 Forex 网站网络服务的远程过程调用,第二个则是连到自建 XML-RPC 服务器,专门解析并分析 2011 年自动交易锦标赛的赛果数据。 如果你想知道怎么在 MT5 里实时拉取并拆解那届锦标赛的多维统计,这套框架能省掉大量重复造轮子的工作。外汇与贵金属自动化分析属高风险操作,回测与实盘表现可能存在显著偏差。

先搞清 XML-RPC 是哪路协议

XML-RPC 全名是 XML Remote Procedure Call,本质是一套用 XML 给参数做编解码、从而远程调用外部方法的网络协议。它跑在 HTTP 之上,传输层就是普通 web 请求,这一点决定了它在 MT5 里走的是 80/443 端口,不需要额外开防火墙策略。 所谓外部方法,指的是另一台机器或同机另一个进程里暴露出来的远程过程,只要调用方也实现了 XML-RPC 协议栈、且网络可达,任何语言都能发起请求。 一个值得记下的点:它不仅能跨机器,也能在同机调用另一种语言写的服务。后面第二部分会专门拆同机异语言调用的做法,本文先只把协议边界说清。

◍ XML-RPC 的数据类型怎么塞进 MT5 通信

XML-RPC 只定义了六种基础类型加两种复合类型,基础类是 int(32 位整数,范围 -2,147,483,648 到 2,147,483,647)、double、boolean、string、datetime.iso8601 与 base64;复合类则是 array 和 struct。做 MT5 客户端时,你发出的请求体和收到的响应体都得严格落在这套类型里,否则远端服务会直接拒收。 array 不要求元素同型,外层是 value 包 array,array 里再套 data,data 下挂多个 value。下面这段代码就是一个四整数数组加一个五字符串数组的实例,注意 -3456 这种负值也照常走 int 标签。 struct 用来传名称-值对,相当于关联数组或对象属性:value 内放 struct,struct 内放若干 member,每个 member 由 name 和 value 组成。行情推送里若想带「品种名+买价+卖价」这类字段,用 struct 比纯 array 更不易解析错位。 熟悉这套数据模型后,下一步就是把它拼成请求与响应结构——那才是 MQL5 写 XML-RPC 客户端的落地起点。外汇与贵金属接口调用存在断连、滑点等高风险,参数序列化前建议先在本地打印报文核对类型。

MQL5 / C++
<span class="tag">&lt;<span class="title">value</span><span>&gt;</span></span>
&nbsp;&nbsp; <span class="tag">&lt;<span class="title">array</span><span>&gt;</span></span>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;<span class="title">data</span><span>&gt;</span></span>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="tag">&lt;<span class="title">value</span><span>&gt;</span></span><span class="tag">&lt;<span class="title">class="type">int</span><span>&gt;</span></span>class="num">111<span class="tag">&lt;/<span class="title">class="type">int</span><span>&gt;</span></span><span class="tag">&lt;/<span class="title">value</span><span>&gt;</span></span>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="tag">&lt;<span class="title">value</span><span>&gt;</span></span><span class="tag">&lt;<span class="title">class="type">int</span><span>&gt;</span></span>class="num">222<span class="tag">&lt;/<span class="title">class="type">int</span><span>&gt;</span></span><span class="tag">&lt;/<span class="title">value</span><span>&gt;</span></span>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="tag">&lt;<span class="title">value</span><span>&gt;</span></span><span class="tag">&lt;<span class="title">class="type">int</span><span>&gt;</span></span>-class="num">3456<span class="tag">&lt;/<span class="title">class="type">int</span><span>&gt;</span></span><span class="tag">&lt;/<span class="title">value</span><span>&gt;</span></span>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="tag">&lt;<span class="title">value</span><span>&gt;</span></span><span class="tag">&lt;<span class="title">class="type">int</span><span>&gt;</span></span>class="num">666<span class="tag">&lt;/<span class="title">class="type">int</span><span>&gt;</span></span><span class="tag">&lt;/<span class="title">value</span><span>&gt;</span></span>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;/<span class="title">data</span><span>&gt;</span></span>
&nbsp;&nbsp; <span class="tag">&lt;/<span class="title">array</span><span>&gt;</span></span>
<span class="tag">&lt;/<span class="title">value</span><span>&gt;</span></span>
<span class="tag">&lt;<span class="title">value</span><span>&gt;</span></span>
&nbsp;&nbsp; <span class="tag">&lt;<span class="title">array</span><span>&gt;</span></span>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;<span class="title">data</span><span>&gt;</span></span>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="tag">&lt;<span class="title">value</span><span>&gt;</span></span><span class="tag">&lt;<span class="title">class="type">class="kw">string</span><span>&gt;</span></span>MQL5<span class="tag">&lt;/<span class="title">class="type">class="kw">string</span><span>&gt;</span></span><span class="tag">&lt;/<span class="title">value</span><span>&gt;</span></span>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="tag">&lt;<span class="title">value</span><span>&gt;</span></span><span class="tag">&lt;<span class="title">class="type">class="kw">string</span><span>&gt;</span></span>is <span class="tag">&lt;/<span class="title">class="type">class="kw">string</span><span>&gt;</span></span><span class="tag">&lt;/<span class="title">value</span><span>&gt;</span></span>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="tag">&lt;<span class="title">value</span><span>&gt;</span></span><span class="tag">&lt;<span class="title">class="type">class="kw">string</span><span>&gt;</span></span>a<span class="tag">&lt;/<span class="title">class="type">class="kw">string</span><span>&gt;</span></span><span class="tag">&lt;/<span class="title">value</span><span>&gt;</span></span>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="tag">&lt;<span class="title">value</span><span>&gt;</span></span><span class="tag">&lt;<span class="title">class="type">class="kw">string</span><span>&gt;</span></span>great<span class="tag">&lt;/<span class="title">class="type">class="kw">string</span><span>&gt;</span></span><span class="tag">&lt;/<span class="title">value</span><span>&gt;</span></span>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="tag">&lt;<span class="title">value</span><span>&gt;</span></span><span class="tag">&lt;<span class="title">class="type">class="kw">string</span><span>&gt;</span></span>language.<span class="tag">&lt;/<span class="title">class="type">class="kw">string</span><span>&gt;</span></span><span class="tag">&lt;/<span class="title">value</span><span>&gt;</span></span>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;/<span class="title">data</span><span>&gt;</span></span>
&nbsp;&nbsp; <span class="tag">&lt;/<span class="title">array</span><span>&gt;</span></span>
<span class="tag">&lt;/<span class="title">value</span><span>&gt;</span></span>
<span class="tag">&lt;<span class="title">value</span><span>&gt;</span></span>
&nbsp;&nbsp; <span class="tag">&lt;<span class="title">class="kw">struct</span><span>&gt;</span></span>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;<span class="title">member</span><span>&gt;</span></span>

「把账户画像塞进 XML 结构」

MQL5 的序列化机制允许把自定义 struct 直接写成 XML 节点,每个字段对应一个 member 块。下面这段片段演示了三个基础类型的落地方式:字符串、整型、双精度浮点。 AccountHolder 字段用 string 承载,值为 John Doe;Age 用 int 写入 77;Equity 用 double 记录 1000000.0。这种写法在把交易账户元数据导出给外部分析脚本时很实用,节点名即字段名,类型标签决定了解析端的强类型还原。 开 MT5 建个同构 struct 跑 Serialize 看输出,能确认你本地编译器生成的 XML 缩进与标签顺序是否和这段一致。外汇与贵金属交易含高杠杆风险,这类序列化只解决数据传输,不暗示任何仓位安全性。

MQL5 / C++
    <member>
        <name>AccountHolder</name>
        <value><class="type">class="kw">string>John Doe</class="type">class="kw">string></value>
    </member>
    <member>
        <name>Age</name>
        <value><class="type">int>class="num">77</class="type">int></value>
    </member>
    <member>
        <name>Equity</name>
        <value><class="type">class="kw">double>class="num">1000000.0</class="type">class="kw">double></value>
    </member>
 </class="kw">struct>
</value>

XML-RPC 报头与有效负荷的拼装方式

一次 XML-RPC 调用分两层:HTTP 报头 + XML 有效负荷。报头里必须写死 POST 方法、相对路径(如 /xmlrpc)、HTTP 1.1、User-Agent、Host、Content-Type: text/xml,以及以字节计数的 Content-Length。上面例子里 Content-Length 是 188,少算一个换行服务器就会拒收。 有效负荷的根节点只能是 methodCall,里面挂 methodName 和 params。methodName 填服务端暴露的函数名,params 下每个 param 包一个 value,类型按 double / int / string 等标签显式声明。例子中 multiply 传了两个 double:8654.41 和 7234.00,服务端算完原样回 XML-RPC 响应。 在 MT5 里用 WebRequest 发这种请求时,自己拼字符串最容易在 Content-Length 上翻车——建议先算 UTF-8 字节数再填,别照抄例子里的 188,否则换台机器就可能报 400。

MQL5 / C++
POST /xmlrpc HTTP class="num">1.1
User-Agent: mql5-rpc/class="num">1.0
Host: class="num">10.12.class="num">10.10
Content-Type: text/xml
Content-Length: class="num">188
<?xml version="class="num">1.0"?>
<methodCall>
  <methodName>multiply</methodName>
      <params>
        <param>
          <value><class="type">class="kw">double>class="num">8654.41</class="type">class="kw">double></value>
        </param>
        <param>
          <value><class="type">class="kw">double>class="num">7234.00</class="type">class="kw">double></value>
        </param>
      </params>
</methodCall>

常见问题

可以,用 MQL5 内置的 WebRequest 直接发 XML-RPC 请求即可,关键是拼对报头和有效负荷的 XML 结构。
它是用 HTTP 传 XML 格式请求和响应的老牌远程调用协议,比 REST 更强调方法调用和严格数据类型,不适合高频轻量场景。
小布盯盘的 AIGC 可内置这类诊断,打开对应品种页就能看到账户画像的异动汇总,不用自己写 XML 解析。
最易错的是类型标签不匹配,比如把 double 写成 string,以及 member 名拼写和服务器端不一致。
必须写成 text/xml,且需带正确的 Content-Length,否则服务端可能直接丢弃有效负荷。