语法基础已经了解的差不多了,从这节开始,我们进入EA开发环节。
一个标准的EA结构包含7大模块,在EA执行的过程中遵循清晰的生命周期:初始化 → 实时处理 → 退出(清理资源)
① 预处理指令区
位置在代码最顶部,#property
:声明EA的基本信息(版权、网站、版本等);#include
:引入库文件、头文件;#define
:定义常量(可重复使用)。
② 外部输入参数区
关键字:extern
。作用:定义用户可修改 的策略参数(在EA参数面板中显示),无需改代码即可灵活调参,实现策略模块化。
③ 全局变量区
位置:extern
后、主函数前。作用:用于函数之间共享的数据,生命周期 = EA整段运行周期,所有函数均可读取或修改
④ 初始化函数 OnInit()
声明方式:
触发时机:EA加载到图表时,只执行一次。主要用于初始化变量、加载资源、校验账户类型、图表品种、创建图形对象、输出日志。
返回值:返回 INIT_SUCCEEDED (0)
表示成功;也可以返回 INIT_FAILED
等错误码。
⑤ 主逻辑函数 OnTick()
声明方式:
触发:每一个Tick(报价变动)都会调用一次。EA的核心功能,生成交易信号、执行下单、平仓、管理已有订单、控制风险(如止损、止盈)、更新图表或信息面板。OnTick()
是EA的 主引擎,也是判断行情、发单的核心入口。
⑥ 清理函数 OnDeinit(const int reason)
声明方式:
触发:卸载EA、关闭图表或MT4、参数变更、重新编译等。用途:清除图形对象、释放资源(如句柄)、输出退出日志。
reason
参数代表退出原因(如 REASON_REMOVE、REASON_RECOMPILE 等)
⑦ 自定义函数区
作用:将复杂逻辑拆分为可复用的小函数,提升可读性与维护性
建议:给每类功能编写函数,如下单函数、信号函数、风险控制函数,函数内部保持简洁,逻辑清晰。
🔄 EA运行流程(生命周期)
在此过程中:extern
参数由用户在界面设置、全局变量在多个函数中共享、自定义函数在 OnInit()
、OnTick()
中被调用
总结
模块名 | 关键词/函数名 | 执行时机 | 主要用途 |
---|---|---|---|
预处理指令 | #property , #include 等 |
编译时 | 设置EA信息、导入库 |
外部参数区 | extern |
编译后 → 用户设定参数 | 调整策略参数 |
全局变量区 | 无关键字 | 整个生命周期 | 各函数共享数据 |
初始化函数 | int OnInit() |
EA加载时 | 初始化数据、检查环境 |
主逻辑函数 | void OnTick() |
每个Tick到达时 | 判断行情、管理交易 |
清理函数 | void OnDeinit(int reason) |
EA卸载或图表关闭时 | 清除资源、释放对象 |
自定义函数区 | void MyFunction() 等 |
被其他函数调用 | 模块化处理逻辑、提高复用性 |
结构清晰,执行流畅,功能稳定 —— 这是所有优秀EA的共同特点。
下面是一个EA布局示例
小结一下整体流程,下面是整个EA结构的流程图思维:
EA文件就是一个有明确模块分区的自动交易程序,从编译到运行到结束,每一步都非常规范,有标准的入口(OnInit
)、执行(OnTick
)、出口(Deinit
)。
下面给大家在写一个更规范一点的EA结构模板,同时加上详细注释,大家可以多琢磨琢磨,有助于你理解每一部分用途: