让 MT5 给 MT4 发信号:用 TCP 套接字做跨平台跟单
很多人已经用 MQL5 写出好策略,却只能在真实账户跑 MT4;也有人想实时跟随锦标赛领先者。文章给出一套方案:让 MetaTrader 5 当“信号源”,通过 TCP 套接字把每笔交易广播给任意数量的 MT4“跟随端”,且转发在后台线程进行,不拖慢 MT5 本身。
一、为什么要让 MT5 给 MT4 发信号
三个典型动机:其一,MT5 已发布很久,但常用经纪商还没在真实账户放开,有人用 MQL5 写好策略想实盘跑;其二,锦标赛里大家都想跟随领先者,但官网数据每 5 分钟才更新,容易错失买卖点;其三,有人有好策略想共享给朋友,需要支持多连接且实时不降效。这套方案正对这三个痛点。
二、跟随什么:仓位 / 订单 / 交易
要转发信息,得先决定跟什么粒度。单纯跟“仓位”不够全面,除非每单号或每秒都比对状态;挂单信息在“订单”里有但“交易”里缺进场类型(DEAL_ENTRY)。最佳折中是“交易+订单”结合:既有挂单信息,又能跟随账户的交易行为。文章在速度(挂单)和效果(交易)间选了效果,跟“交易”也能执行挂单,只是有微小网络延迟。
// 交易字符串格式示例(用尖括号分隔多笔) // <EURUSD;BUY;IN;0.01;1.37294> // <EURUSD;SELL;OUT;0.01;1.37310> // <EURUSD;SELL;IN;0.01;1.37320> // <EURUSD;BUY;INOUT;0.02;1.37294> // 字段:品种;买卖;进场类型;手数;价格
三、传输通道:TCP 套接字
作者比较了几种通信方式:MQL5 没直接 API 做这事,WinInet 类文章不能满足需求。因为客户端很可能在别的机器上,最终选 TCP 连接。服务端用 C# 写(SocketServer.dll),最多支持 500 并发客户端,后台独立线程运行,不阻塞 MT5。MT4 端则借用 MQL4 代码库的 WinSock.mqh 做客户端。
// MT5 端 #import C# 写的 SocketServer.dll #import "SocketServer.dll" string About(); // 关于信息 int SendToAll(string msg); // 广播给所有客户端 bool Stop(); // 停止服务器 bool StartListen(int port); // 启动监听(最多500客户端) string ReadLogLine(); // 读服务器日志 #import
四、MT5 端:信号服务器 EA
MT5 端是个 EA(挂哪个货币图都行)。OnInit 里启动监听线程;它不关心连了谁,每次有交易就用 OnTrade() 从最近 24 小时历史里找新交易,构建交易字符串并 SendToAll 广播。即使没人连也照发。OnTimer 每秒打印服务器日志,方便排错。
// OnTrade:发现新交易就广播
void OnTrade() {
datetime dtStart=TimeCurrent()-60*60*24, dtEnd=TimeCurrent()+60*60*24;
if(HistorySelect(dtStart,dtEnd)){
for(int i=0;i<HistoryDealsTotal();i++){
ulong ticket=HistoryDealGetTicket(i);
if(HistoryDealGetInteger(ticket,DEAL_ENTRY)!=DEAL_ENTRY_STATE){
if(HistoryDealGetInteger(ticket,DEAL_TIME)>g_dtLastDealTime){
int cnt=SendToAll(sBuildDealString(ticket));
if(cnt>=0) g_dtLastDealTime=(datetime)HistoryDealGetInteger(ticket,DEAL_TIME);
}
}
}
}
}
五、MT4 端:信号接收脚本
MT4 端用脚本而非 EA,因为它要持续维护与 MT5 的套接字连接、不断接收。作者直接复用 MQL4 代码库的 WinSock.mqh(轻量、测试稳定),连上 MT5 的 SocketServer,解析收到的交易字符串并在本地下单。这样 MT4 端就像“镜像”了 MT5 的信号源账户。
六、数据处理与自定义交易类型
为应对 TCP 可能一次收到多笔、以及部分平仓等边界,作者定义了自定义交易类型 DEAL_ENTRY_OUTALL:当 MT5 端某品种仓位已平完,广播 OUTALL 而非普通 OUT,确保 MT4 端不会留下“幽灵订单”。同时按品种启用/禁用机制,避免把禁用品种的信号误执行。手数映射上,INOUT 只取 IN 部分手数,减少跨端微小手数差异。
七、小结
让 MT5 给 MT4 发信号,本质是用 TCP 把“交易事件”从信号源实时广播给跟随端:MT5 端 C# SocketServer 后台监听、OnTrade 广播;MT4 端 WinSock 接收并执行。它解决了“好策略在 MT5、实盘在 MT4”和“跟随锦标赛”两类刚需。上线前务必处理好手数映射、断线重连和自定义 OUTALL 类型——跨平台跟单的细节全在边界情况里。