将EA从MQL4迁移到MQL5不是简单的重新编译。两者的执行模型、交易函数和历史数据访问方式存在根本差异。本文聚焦于高级用户所需的语法变更和逻辑适配。
1. 交易执行:OrderSend() vs CTrade类
MQL4使用参数繁多的`OrderSend()`。MQL5使用`CTrade`类,将开仓简化为方法调用。直接移植会失败,因为MQL5没有`OrderSend()`。
MQL4示例:
```cpp
int ticket = OrderSend(Symbol(), OP_BUY, 0.1, Ask, 3, stopLoss, takeProfit, "EA", magic, 0, clrNONE);
```
MQL5中使用`CTrade`的等价写法:
```cpp
#include
CTrade trade;
double sl = Ask - 50 * Point();
double tp = Ask + 100 * Point();
trade.SetExpertMagicNumber(magic);
trade.PositionOpen(Symbol(), ORDER_TYPE_BUY, 0.1, Ask, sl, tp, "EA");
```
2. 分笔模型与历史数据
MQL4可直接使用`Close[1]`获取上一根K线收盘价。MQL5需要`CopyClose()`或`CopyRates()`。此外,MQL5区分分笔历史与K线历史。
MQL5获取最近10个收盘价:
```cpp
double closes[];
CopyClose(Symbol(), PERIOD_CURRENT, 0, 10, closes);
```
MQL4等价写法是直接访问`Close[0]`到`Close[9]`。MQL5的方法能避免意外使用未来函数——这对回测准确性至关重要。
3. 订单选择循环
在MQL4中,通过`OrdersTotal()` + `OrderSelect()`遍历持仓。MQL5使用`PositionSelect()`或`PositionsTotal()`配合`PositionGetTicket()`。
MQL5循环示例:
```cpp
for(int i = PositionsTotal() - 1; i >= 0; i--) {
ulong ticket = PositionGetTicket(i);
if(PositionSelectByTicket(ticket)) {
if(PositionGetInteger(POSITION_MAGIC) == magic) {
// 执行操作
}
}
}
```
MQL4的`OrderSelect()`通过ticket选择持仓的方式不能直接移植。避免在MQL5中使用`OrderSelect()`。
4. 参数优化与遗传算法
MQL5优化器原生支持遗传算法(GA),而MQL4需要外部工具。GA收敛公式:种群多样性衰减 `D(t+1) = D(t) * (1 - alpha)`,其中alpha为交叉率。MQL5内置的GA在性能上优于MT4的暴力穷举。
在MT5策略测试器中启用GA:设置“优化”→选择“遗传算法”。输入参数范围的定义方式与MQL4相同。
5. 跨平台兼容模式
若要维护一套代码同时支持两个平台,可使用预处理器指令:
```cpp
#ifdef __MQL4__
// MQL4 代码
#else
// MQL5 代码
#endif
```
但避免在内部编写复杂逻辑——最好将交易执行抽象到独立的include文件中。
6. 常见迁移错误
参考来源