MT5 到 MT4 交易复制器:净持仓模型的桥接方案
为什么需要 MT5→MT4 复制器
很多交易者看好 MT5 的功能,但实盘账户还在 MT4 上。复制器的思路是:用 MT4 作为 MT5 交易的“执行载体”,把 MT5 上的持仓同步复制到 MT4。文章先厘清一个关键结论:利润只来自“报价 × 交易量”,报价由经纪商决定改不了,交易者能控制的只有交易量——所以复制的核心是“同步持仓的交易量”,而非逐笔复制每笔订单。
净持仓模型 vs 对冲模型
MT5 用净持仓(一个品种一个仓位),MT4 用对冲(同品种可多笔独立订单)。差异在于“平哪个订单不重要,重要的是该位置的平仓量一致”——文章用例子证明:同量订单以不同顺序平仓,单笔利润不同,但整段总利润相同。因此复制器只需保证 MT4 上的净持仓量等于 MT5 的净持仓量,不必还原 MT5 的订单结构。
架构:源端监听 + 共享文件传信号
MT5 端 EA 用 OnTimer 每秒扫描所有品种持仓,比较现值与前值,有变化就把“品种、持仓方向、交易量、SL/TP”写成共享文件(放在 MT5 的 MQL5\Files\ 下,且把 MT4 装到该目录里,使两边都读得到)。MT4 端脚本循环读文件、解析、对比虚拟头寸,再决定开/平/改。
差额下单:虚拟头寸比较
复制的核心是“差额下单”——比较文件里的目标持仓与实际虚拟持仓,只对差额部分操作。把方向转成 -1/+1,比较 TF·VF 与 TR·VR:不一致就平仓或开仓补齐差额:
int TF = SymPosType[i]*2-1; // 文件中的方向
int TR = realSymPosType[i]*2-1; // 实际方向
double VF = SymPosVol[i], VR = realSymPosVol[i];
if(NormalizeDouble(VF*TF,8) != NormalizeDouble(VR*TR,8))
{
if((VR!=0 && TF!=TR) || (TF==TR && VF<VR)) // 方向变 或 实际更多
{ double lot = (TF==TR)? (VR-VF) : VR; close_market_order(Symbols[i], lot); }
else // 实际更少 -> 开仓补齐
{ double lot = (TF==TR)? (VF-VR) : VF; open_market_order(Symbols[i], SymPosType[i], lot); }
}
坑与注意
完整复制流程(一句话串起来)
MT5 端 OnTimer 每秒扫持仓→compare_positions 比对→有变化写共享文件 cnt_command++;MT4 端循环读文件→parser 解析成数组→虚拟头寸比较→processing_signals 算差额→开/平/改→processing_sl_tp_levels 同步止损止盈。两个 processing_* 函数都是“带 IsStopped 退出的无限循环”,且只在交易流空闲(Busy_and_Connected)时才发指令,避免服务器拒单。