Summary: EA只开仓不平仓?别被表面现象迷惑。本文深入讲解MQL4中if条件判断的底层逻辑——任何非0值都被视为“真”,以及OrderSend后跟OrderModify的致命时间差,教你写出更稳健的EA代码。




步骤1:识别“EA不平仓”的症状

你的EA能正常开仓,但当价格达到止盈或止损条件时,仓位却纹丝不动。先打开工具箱(Ctrl+T)中的“EA交易”选项卡,检查是否有隐藏的红色报错。截图位置:工具箱窗口的EA交易选项卡,表面无红色错误但图表上仓位未平。

步骤2:理解if语句陷阱——非0即为真

在MQL4中,if条件判断有一个关键规则:任何非0的数字都被视为“真”(True),只有0才是“假”(False)。这意味着`if(1)`、`if(-5)`和`if(0.5)`全部会执行真分支[citation:3]。截图位置:MetaEditor中显示if(OrderSelect())代码示例。

步骤3:检查函数返回值的假设

很多EA开发者默认函数成功返回1、失败返回0。但MQL4中某些函数的返回值不同。例如`OrderSend()`成功时返回订单号(正数),用`if(OrderSend(...))`没问题。但如果你写了一个自定义函数,成功返回0、失败返回-1,那么`if(MyFunction())`会把成功的0判断为“假”,导致逻辑错误[citation:3]。截图位置:正确与错误返回值处理的代码对比。

步骤4:检查OrderSend后跟OrderModify的时间差漏洞

一个常见但隐蔽的错误:EA先发一个不带止损止盈的订单,然后立即用`OrderModify()`加上止损止盈。这两个操作之间存在微小的时间差。如果在这毫秒之间价格发生了跳动,你计算的止损/止盈价位可能变成无效值(例如买单止损价高于市价),导致`OrderModify()`静默失败,你的仓位变成一个没有任何保护的“裸单”[citation:3]。截图位置:展示错误的两步法代码示例。

步骤5:修复方法——在OrderSend()中直接设置止损止盈

不要分两步操作。在发送订单之前就计算好止损价和止盈价,然后将它们作为参数直接传入`OrderSend()`。这样操作是原子性的——一次服务器请求完成开仓和保护设置,没有时间差漏洞[citation:3]。截图位置:修复后的代码,显示OrderSend()中包含预计算的止损止盈参数。

步骤6:为每个交易函数添加错误检查

每次调用交易函数后,都要检查返回值,并用`GetLastError()`捕获具体错误码。把这些信息打印到EA交易选项卡中,方便调试。示例代码:`if(ticket<0){ Print(“订单失败,错误码:”,GetLastError()); }`[citation:3]。截图位置:包含Print语句的错误检查代码块。

步骤7:先在模拟账户上测试修复后的EA

务必在模拟账户上运行修复后的EA至少一周。持续监控EA交易选项卡,确认没有新的错误信息。逐一验证所有仓位都能在你设定的止损/止盈价位正常平仓。截图位置:模拟账户图表上EA正常运行(笑脸图标)并显示已平仓记录。

参考来源: MQL4官方文档;FM Studio EA逻辑指南2025[citation:3]