Summary: 本文带你从零开始编写第一个完整的EA程序,学习Hello World EA的代码结构,理解OnInit、OnTick、OnDeinit三大核心函数,并在模拟图表上成功运行。




一、什么是Hello World EA?

“Hello World”是学习任何编程语言时的第一个传统程序。对于外汇EA开发来说,Hello World EA不会进行真实交易,而是通过打印消息来确认EA正常运行,帮助你理解EA的基础代码结构。

二、完整的Hello World EA源代码

```mql4
//+------------------------------------------------------------------+
//| HelloWorld.mq4 |
//| Copyright 2024, ForexEA傻瓜教程 |
//| https://www.xxx.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, ForexEA傻瓜教程"
#property link "https://www.xxx.com"
#property version "1.00"
#property strict

//+------------------------------------------------------------------+
//| EA初始化函数 |
//+------------------------------------------------------------------+
int OnInit() {
Print("================== HELLO WORLD EA ==================");
Print("EA初始化成功!时间:", TimeToString(TimeCurrent()));
Print("当前图表品种:", Symbol());
Print("当前时间周期:", PeriodToString(Period()));
Print("====================================================");
return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| EA主执行函数(每个Tick触发) |
//+------------------------------------------------------------------+
void OnTick() {
static int tickCounter = 0;
tickCounter++;

// 每100个Tick打印一次信息,避免日志过多
if(tickCounter % 100 == 1) {
Print("第", tickCounter, "个Tick | 当前买价:", MarketInfo(Symbol(), MODE_BID),
" | 当前卖价:", MarketInfo(Symbol(), MODE_ASK));
}

// 在图表上实时显示信息
Comment("=== Hello World EA 运行中 ===\n",
"品种:", Symbol(), "\n",
"周期:", PeriodToString(Period()), "\n",
"Tick计数:", tickCounter, "\n",
"当前买价:", MarketInfo(Symbol(), MODE_BID), "\n",
"当前卖价:", MarketInfo(Symbol(), MODE_ASK), "\n",
"账户余额:", AccountBalance(), "\n",
"EA状态:运行正常");
}

//+------------------------------------------------------------------+
//| EA反初始化函数 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
Print("================== EA已停止 ==================");
Print("停止原因代码:", reason);
Print("停止原因说明:", GetDeinitReasonText(reason));
Print("总Tick处理数:", tickCounter);
Print("=============================================");

// 清除图表上的注释
Comment("");
}

//+------------------------------------------------------------------+
//| 辅助函数:将周期数值转换为可读字符串 |
//+------------------------------------------------------------------+
string PeriodToString(int period) {
switch(period) {
case PERIOD_M1: return("M1 (1分钟)");
case PERIOD_M5: return("M5 (5分钟)");
case PERIOD_M15: return("M15 (15分钟)");
case PERIOD_M30: return("M30 (30分钟)");
case PERIOD_H1: return("H1 (1小时)");
case PERIOD_H4: return("H4 (4小时)");
case PERIOD_D1: return("D1 (日线)");
case PERIOD_W1: return("W1 (周线)");
case PERIOD_MN1: return("MN1 (月线)");
default: return("未知周期");
}
}

//+------------------------------------------------------------------+
//| 辅助函数:获取反初始化原因说明 |
//+------------------------------------------------------------------+
string GetDeinitReasonText(int reason) {
switch(reason) {
case REASON_REMOVE: return("用户从图表上移除了EA");
case REASON_RECOMPILE: return("用户重新编译了EA");
case REASON_CHARTCLOSE: return("用户关闭了图表");
case REASON_PARAMETERS: return("用户修改了输入参数");
case REASON_ACCOUNT: return("账户切换或重新登录");
default: return("其他原因");
}
}
//+------------------------------------------------------------------+
```

三、逐行代码解读

1. 属性声明部分(第5-8行)

| 属性 | 作用说明 |
|------|----------|
| #property copyright | 设置版权信息,会在EA属性中显示 |
| #property link | 设置EA的网站链接 |
| #property version | 定义版本号,便于后续更新追踪 |
| #property strict | 启用严格语法检查,提前发现编码错误 |

2. OnInit()初始化函数(第12-20行)

这个函数在EA首次加载到图表时运行一次,用于完成以下工作:
  • 初始化变量

  • 检查交易条件

  • 加载所需资源

  • 打印启动确认信息


  • 3. OnTick()主执行函数(第24-37行)

    这个函数在每个价格Tick到来时都会触发执行,核心要点:
  • 每次行情变动都会触发该函数

  • 使用static静态变量在两次Tick之间保持数值

  • Comment()函数直接在图表上显示文字信息

  • 避免过多Print()语句,防止日志溢出


  • 4. OnDeinit()反初始化函数(第41-51行)

    这个函数在EA被移除时运行,用于完成以下清理工作:
  • 清除图表上创建的对象

  • 关闭文件句柄

  • 打印关闭汇总信息


  • 四、如何编译和运行Hello World EA

    第1步:创建新的EA文件
    1. 打开MetaEditor(按F4键)
    2. 点击 文件 > 新建 > 智能交易系统 > 下一步
    3. 命名为“HelloWorld”
    4. 点击完成

    第2步:替换模板代码
    1. 全选生成的代码(Ctrl+A)
    2. 删除所有内容
    3. 粘贴上面的完整Hello World EA代码(Ctrl+V)

    第3步:编译代码
    1. 点击编译按钮或按F7键
    2. 检查底部面板是否显示“编译成功”
    3. 如果出现错误,根据错误提示进行修复

    第4步:在模拟图表上运行
    1. 切换回MT4/MT5界面
    2. 打开导航器(按Ctrl+N)
    3. 展开“智能交易系统”文件夹
    4. 找到“HelloWorld”
    5. 将其拖拽到任意模拟图表上
    6. 在弹出的窗口中点击确定

    五、预期运行效果

    EA成功加载后,你将看到以下输出:
  • 终端窗口的“智能交易系统”选项卡:OnInit()打印的启动信息

  • 图表显示区域:Comment()显示的实时信息

  • 每100个Tick:在“智能交易系统”选项卡中打印新的信息


  • Comment()在图表上的显示效果
    ```
    === Hello World EA 运行中 ===
    品种:EURUSD
    周期:H1 (1小时)
    Tick计数:1523
    当前买价:1.09250
    当前卖价:1.09260
    账户余额:10000.00
    EA状态:运行正常
    ```

    六、常见问题及解决方案

    | 问题现象 | 原因分析 | 解决方法 |
    |----------|----------|----------|
    | EA未出现在导航器中 | 编译失败 | 检查MetaEditor中是否有红色错误信息 |
    | 图表上没有笑脸图标 | EA因错误停止运行 | 查看“智能交易系统”选项卡中的错误信息 |
    | Comment内容不显示 | 图表字体太小 | 增大图表字体大小或放大图表 |
    | Print信息看不到 | 日志级别设置问题 | 确保终端窗口的“智能交易系统”选项卡可见 |
    | EA一加载就停止 | 自动交易按钮未开启 | 点击MT4工具栏上的“自动交易”按钮 |

    七、测试验证清单

  • [ ] EA编译通过,显示0个错误、0个警告

  • [ ] EA出现在导航器的“智能交易系统”文件夹中

  • [ ] 加载后图表右上角出现笑脸图标

  • [ ] Comment文字正常显示在图表上

  • [ ] Print信息正常出现在“智能交易系统”选项卡中

  • [ ] 从图表上移除EA时正常清理,无残留信息


  • 参考来源:

  • MetaQuotes Ltd.《MQL4官方文档 - OnInit、OnTick、OnDeinit函数说明》(2024)

  • Franklin, James.《7天学会MQL4编程》(2021)

  • 陈晓东.《MQL4从入门到精通》(2023)


  • 9. 下一步

    第5篇将讲解EA在图表上的运行机制 – EA的完整生命周期、初始化阶段、Tick循环执行机制、定时器事件以及反初始化清理流程。