MQL5语言帮助文件人话版(三十三)第四章(5) 函数的使用

| 发表于 昨天 13:38 | 显示全部楼层 |复制链接
五、预定义事件处理函数
(一)预定义事件处理函数
所有计算机程序,从底层逻辑上,运行方式只分两大类:顺序批处理(一次性跑完就结束)、循环驱动(持续等待 / 反复检查)。所谓循环驱动,就是该程序会有一个主循环(不需要你写,它自带的,删掉就不跑了)不断的跑,主动去检查条件是否成立。

而MQL5 的预定义事件处理,就是一种事件驱动的循环驱动运行模式。MT5平台内置「事件驱动机制」:系统预先定义好了一系列固定名称、固定参数的事件函数,负责监听图表、行情、交易、定时器等各类事件;当对应事件发生时,系统会自动调用对应的事件函数,开发者只需要在函数里编写业务逻辑即可,不用自己写事件监听逻辑。

预定义事件处理函数是所有 MQL5 程序的运行入口 —— 你写的所有策略、计算、交易逻辑,最终都要挂载在这些预定义事件上,由事件触发执行。有以下几条硬性规定:

1. 绝对的固定格式:函数名、参数列表必须和官方定义完全一致(大小写敏感),写错了系统就识别不了,事件不会触发,且不会报错,这是新手最常踩的坑。

2. 自动调用:开发者永远不需要手动调用这些函数,全部由系统在对应时机自动触发。

3. 程序类型不同,支持的事件不同:EA、技术指标、脚本三类程序,各自有专属的事件集合。

这些函数大致分为四类:生命周期事件、核心业务事件、定时事件、进阶事件。它们都有个共同的特点,以On开头,也就是编程界事件处理函数的“通用命名前缀”,其含义是当什么什么事件发生时。

下面我们一一学习。

(二)生命周期事件函数
共3个。EA、技术指标二类程序用OnInit ()和OnDeinit (),OnStart()是脚本专用。对应程序开始和收尾的环节。

1. 初始化事件OnInit ()

(1)触发时机:程序被加载到图表上时,自动调用且仅调用一次,是程序的总入口。

(2)函数原型:int OnInit();      //该函数无参数。init意思就是初始化。

(3)初始化成功返回值: 返回 `0`:初始化成功,程序继续运行;

(4)初始化失败返回值: 非零值,代表初始化失败,系统自动返回的所谓”非零值”就是初始化失败原因代码 REASON_INITFAILED,共有十个:

  ① 常量REASON_PROGRAM,       数值:0,含义:程序主动自我终止,代码里调用了系统终止函数 `ExpertRemove()` ,EA 自己请求卸载自己。典型场景如:回撤熔断、收益目标达成、异常触发等等,EA 主动退出。

  ②常量REASON_REMOVE,            数值:1,含义:用户手动删除程序,在图表上右键→删除 EA / 指标,手动把程序从图表上移除。这是最常见的卸载原因。

  ③常量REASON_RECOMPILE,       数值:2,含义:用户重新编译代码,在编辑器里修改了代码、点击编译,旧版本程序卸载,新版本重新加载。在开发调试阶段最常触发。

  ④常量REASON_CHARTCHANGE, 数值:3,含义:用户更改交易品种或图表周期,切换后程序先卸载,再用新的图表环境重新初始化。

  ⑤常量REASON_CHARTCLOSE,     数值:4,含义:用户关闭图表,图表上的所有程序跟着一起卸载。

  ⑥常量REASON_PARAMETERS,     数值:5,含义:用户改变输入参数,改参后程序先卸载旧参数版本,再用新参数重新初始化。

  ⑦常量REASON_ACCOUNT,          数值:6,含义:用户切换交易账户,登录状态变更,交易环境变化,程序重启。

  ⑧常量REASON_TEMPLATE,          数值:7,含义:应用新模板,模板包含了程序配置变更,触发程序重新加载。

  ⑨常量REASON_INITFAILED,         数值:8,含义:初始化失败导致终止,`OnInit()` 函数返回了非零值,初始化校验没通过,程序直接终止。

  ⑩常量REASON_CLOSE,                数值:9,含义:整个 MT5 终端关闭,所有程序跟着终端一起退出。

     虽然初始化函数会在失败后生成后这10个结果,但如果你什么都不做,你也看不到这些结果。所以我们可以使用UninitializeReason函数来获得具体的初始化失败结果。

     当EA程序初始化失败后,会直接停止运行,在当前图表上删除,但指标程序初始化失败后,并不会自动停止,也不会自动删除,但它也无法正常使用。

(5)ENUM_INIT_RETCODE 枚举返回值:

  - 普通的int型初始化函数只能返回0(代表初始化成功)或者1(代表初始化失败),即使返回其他非0整数,系统也都默认当失败处理,也就是说只有两种结果。但在回测工作中,往往需要了解比较详细的初始化失败原因,这个原因更倾向于“测试环境”,而非系统自身,需要使用ENUM_INIT_RETCODE 枚举做初始化函数的返回值类型。

  - ENUM_INIT_RETCODE是MQL5系统自带的一个枚举类型,是专门给测试优化场景设计的细分状态枚举,包含多种初始化结果,具体如下:

  ①枚举值INIT_SUCCEEDED,对应数值0,代表初始化成功,程序可以继续进行,相当于int类型中返回了0,void类型中返回了NULL值一样,都代表初始化成功

  ②枚举值INIT_FAILED,对应数值1,代表由于非常严重的错误导致初始化失败

  ③枚举值INIT_PARAMETERS_INCORRECT,对应数值2,代表输入参数组合不正确,不执行完整回测,直接丢弃当前这组参数,调度器立刻分配下一组参数给代理继续测试;在优化结果总表中,这组参数的结果会被标红高亮。

  ④枚举值INIT_AGENT_NOT_SUITABLE,对应数值3,代表当前测试代理(相当于独立的计算进程)不适合运行本 EA,即不是程序初始化本身导致的失败。

(6)简化无校验版void OnInit();  :没有返回值,也不需要在函数体内写`return` 语句。无论初始化过程有没有问题,程序都会默认初始化成功,继续进入运行阶段。不建议使用。

(7)典型用途:

  - 校验输入参数合法性;

  - 获取指标句柄、打开文件、初始化全局变量;

  - 设置定时器、注册事件监听;

  - 交易环境检查(比如账户类型、品种是否正确)。

  - 这是程序唯一可以提前终止的入口,它的函数体内一般放初始化校验代码,如果有一项初始化失败,整个函数就直接返回失败,避免程序带病运行。

2.卸载清理事件OnDeinit ()

(1)触发时机:程序被移除、图表关闭、终端退出、重新编译时,自动调用且仅调用一次,是程序的收尾入口。原手册上叫”失败初始化函数“,很容易让人误解,这个函数是专门和OnInit();匹配使用的,实际上一切程序卸载场景,都需要OnDeinit ()来收尾。

(2)函数原型:void OnDeinit(const int reason); //本函数为空型,无返回值;它的参数本质上是一个int类型的整数常量,const是常量标识符,int是整数型,reason是一个自定义变量,单词意思是原因。

(3)参数 `reason`:卸载原因码,也就是初始化事件OnInit ()函数失败后返回的那十个原因,可以根据不同原因做不同的清理逻辑。可以在函数内部这样写:int reason = UninitializeReason();  ,就可以把失败返回值赋值给变量reason,如果你想让系统输出具体的失败原因,可以用if 条件语句,把每个reason都对应打印依据文字说明,比如if(reason == REASON_INITFAILED)     { Print("[清理] 因初始化失败,执行异常清理");  }  。

(4)典型用途:

  - 释放指标句柄、关闭打开的文件;

  - 保存数据、打印收尾日志;

  - 可选:平仓、撤销所有挂单(根据策略需求);

  - 主要用在EA和指标程序中,脚本用不到。

3.启动事件函数OnStart()

(1)概念:`OnStart()` 是MQL5 脚本程序(Script)的主执行入口函数,相当于脚本的「主程序」。它对应脚本「一次性执行、跑完即退出」的特性:整个脚本只执行一次 `OnStart()`,执行完毕程序就直接结束,不会像 EA 那样常驻图表、持续响应事件。

(2)函数原型:int OnStart();  也可以是 `void OnStart()` 无返回值版本,但推荐int版本,可以深化具体错误信息设计。

(3)用途:所有不需要常驻图表、一次性完成的工具类任务,都适合写成脚本,逻辑全部写在 `OnStart()` 里,比如:

①. 批量交易操作:批量平仓所有持仓、批量修改所有挂单的止损止盈、批量删除挂单;

②. 数据导出:导出指定周期的历史 K 线数据、导出账户交易历史报表;

③. 批量设置:批量给图表添加指标、批量修改图表参数;

④. 计算统计:一次性计算历史策略回测指标、统计账户盈亏数据;

⑥. 工具类操作:检测账户状态、清理历史日志、同步配置文件。

(4)生命周期说明:

OnStart()函数是脚本的主体,脚本一切有业务功能的代码都写在这里,让然这不是说OnStart()就是脚本的全部,写脚本时,也可以把函数定义写在脚本外面,函数调用写在脚本里面,跟EA和指标程序没有区别,同时也可以写初始化事件OnInit () 函数和启动事件函数OnStart()。需要明确的是,其他内容可有可无,但没有OnStart()函数,脚本就没有意义。



最近访问 头像模式
举报

评论 使用道具

发新帖
EA交易
您需要登录后才可以评论 登录 | 立即注册

麻爪

麻爪 D

如果你想让一个人下地狱,介绍他做交易。
如果你想让一个人在地狱里永不超生,介绍他做EA交易。

Fast跟单EA