最后由 麻爪 于 2026-9-4 14:52 编辑
第二章 MQL5应用程序分类
完成的MQL5程序,可以执行四种交易自动化任务,也就是四种特定类型:
一、EA交易:是一种与图表相连接的自动交易系统,直白点说就是你整个交易策略转化成的一套自动化执行程序(注意EA交易和量化交易一般是看作不同的两个概念的)。
EA交易程序靠事件处理函数干活。事件处理函数就是OnTick()、OnInit()这类函数,专门用来响应一些预定义事件。 所谓预定义事件,就是MT5 平台运行时产生的各种事件,核心常用事件函数有下面几种: - OnTick():每来一根新报价(tick 价格变动)触发
- OnNewBar():K 线形成新柱子时触发
- OnTrade():账户发生交易事件(开仓、平仓、成交、撤单)触发
- OnTimer():按固定时间周期定时触发
- OnInit() / OnDeinit():EA 初始化、卸载事件
所谓的触发,就比如OnTick()函数就对应着价格跳动,只要有新的成交价形成,OnTick()函数就会运行一遍。而EA加载就对应着OnInit()函数,所谓加载就是打开EA,只有这时候,OnInit()函数才会运行一遍。 MT5平台运行时,大约有8种常用的实盘交易事件,4种策略测试事件,1种脚本加载事件,1种自定义指标更新事件,总共14种。后续学到再细写。但需要注意,这个语言更新换代很快,将来肯定会有更多的事件。相比较而言,MT4的交易事件少的可怜。 理论上,复杂的量化交易程序,都是由这14种或者只用其中的几种事件来驱动的。我们在编写MQL5程序时,一定要先想明白你的策略到底是受哪种,或者哪几种事件来驱动的。最容易掉坑的就是,你的信号是价格突破(OnTick)启动,还是完整K线突破(OnNewBar)才启动,这两种事件在实操中天差地别。 编写好的EA程序放置在MT5安装目录的“\MQL5\Experts”文件夹中,可以通过点击MT5界面左上角文件→打开数据文件夹→MQL5→Experts,就可以看到。Experts首先是系统自带的一些EA程序(没有测试的,慎用),然后你可以自行新建文件夹,命名为你的EA名字,再把你的EA放进去,就可以在MT5界面上的“导航→EA交易”中调用了。
二、自定义指标:是由用户开发的技术指标。
本质上,它与MT5平台自带的各类指标是一样的东西,只不过是你自己编的。 MT5平台提供了一大堆各类指标,但有一些并没有提供原始的MQL5代码,你只能在它允许的范围内进行修改,比如改改周期参数,颜色,线粗等等,它的底层逻辑是改不掉的。 有一些提供了MQL5代码,你双击它就可以进入METAEDITOR编辑器,可以修改里面的内容。但我给新手的建议是看看就好,我怕你改不回去了。 METAEDITOR编辑器的代码库中,提供了海量的各种其他人已经编好的代码,有免费的,也有付费的,你可以下载几个观摩或者修改。但因为网络的问题,许多地方打不开下载的网站。 所以,当你自己有一些不同于常人的奇怪想法时,不如试试自定义指标,自己写一个。我就曾经写过一个让成交量除以价格差,得到一个所谓的成交密度指标,用柱线表示,很方便。但看了许久,也没发现这个指标有什么实际意义,就没管它了。 个人感言,代码都是人写的,只有水平高低,没有神圣属性,初学者不用迷信任何代码。 编写好的自定义指标放置在MT5安装目录的“\MQL5\Indicators“文件夹中,同样可以通过点击MT5界面左上角文件→打开数据文件夹→MQL5→Indicators,就可以看到。该文件夹中同样先是系统自带的一些指标程序,然后你同样可以新建文件夹,放入自己的指标程序。 郑重提示,EA就放Experts中,指标就放Indicators中,放错文件夹,MT5就找不到它们了,也不能正常运行。 三、脚本:是一种单独执行操作的程序。
脚本是一种一次性程序。 先说EA交易,一旦打开,只要你不主动结束它,或者没有写让其自动结束的事件,也没有其他意外情况,比如断网断电之类(理论上断网断电之后EA都无法对已有的单子做任何操作,如果没有准备后手,自求多福吧),EA交易程序会一直运行,一直检测你设定的事件是否发生,发生了就立即执行相应操作。 但脚本只在你打开它,或者把它拖到图表上那一刻,运行一次,给你一个结果,除非你再调用它一次,否则它绝对不动。比如批量修改图表、批量导出历史数据、一键平仓全部订单等等,干完就完事。 脚本只处理三种事件:触发器(OnStart)、初始化(OnInit函数)和去初始化(OnDeinit),也就是最基础的加载、卸载逻辑,这三种事件在程序运行过程中,都只执行一次。 其代码中必须包括OnStart处理程序函数,也就是触发器函数,否则启动都启动不了。同时,即使脚本只写了一个OnStart函数,也可以正常运行并实现一定的功能。 写好的脚本被存储在\MQL5\Scripts文件夹中。
四、服务:一种后台默默运行的支持型程序
当你需要做类似下面的事情时: - · 后台轮询任务:持续读取外部接口、接收外部自定义数据源;
- · 全局日志记录,不依赖某一张图表;
- · 跨品种全局监控,不用为每个品种开一张图表挂 EA;
- · 作为桥梁,和外部程序通信(zeromq、网络接口)。
就写一个服务程序吧。 服务程序不会在图表上显示出来,当打开MT5平台时,它就会在后台默默运行,MT5关闭,它也跟着下班。如果你的EA程序出了毛病,出现了死循环,服务程序也会跟着一直原地转圈。 服务不会感知前文说的预定义事件,它能持续运作,依靠的是其内部的while循环语句。但这个循环语句会形成一种内部的死循环,不停的运转下去,系统会直接死机。所以需要补上Sleep()休眠语句,让它运转一轮后休眠一段时间,比如一秒钟。这一秒钟对于计算机程序来说是很漫长的,相当于人为设定让服务程序间歇性的干活,而不是像EA那样时时刻刻盯着数据变化。 你可以在其中写一个服务专属的IsStopped()停止函数,让用户可以在导航器点停止服务,这个函数返回 true,用来跳出循环,服务程序安全退出。 如果没有这个手动退出设定,它会反复的一遍遍运行,只要系统在干活,它永远不下班,这一点与脚本不同。 与脚本相同的是,服务程序也是必须写OnStart处理程序函数,而且也可以只靠这一个函数运作。 服务程序放在MQL5/Services文件夹中。MT5导航器中同样也有”服务“一项。
此外,MQL5程序中还有两个类型的东西,但严格来说,它们不是程序,而是组成程序的材料。 第一:MQL5 函数库(Library) 函数库是代码工具包,不能独立运行,它是给 EA、脚本、服务、指标调用使用的零件。 文件后缀:.mqh(头文件)、.mq5(库源码),存放目录:MQL5/Include 它们不会自己跑,只有被别的程序引入之后,里面的函数、结构体、类才可以被别人调用。 MQL5自带的函数库有许多种,比如数学工具库 Math.mqh、数组标准库 Array.mqh、字符串库 String.mqh等等,随着MQL5的不断更新,这些库也会相应的增减修改。 编程时,在你的 EA / 脚本 / 服务最上方写 include 引入 #include ”mytools.mqh“ 然后你就可以直接调用库里面写好的函数,不用自己再把这个函数的逻辑写一遍。 “mytools”是举例用的一个自定义库名字。通常情况下,我们自编策略所用的函数,都是自定义的,因为你 的策略逻辑就是自定义的,所以你可以自己写一个.mqh文件,把你的函数写清楚,放进MQL5/Include 文件夹新建文件,并给这个函数做个命名,比如”mytools“。然后通过#include <mytools.mqh>一样可以调用,而不是总在你的程序中复制粘贴这段函数代码。 如果需要调用自带的库,需要准确的写上自带库的名字。 #include <Math.mqh> //MetaQuotes自带的数学工具库
这里有小小的区别,如果调用自己编的库,文件名称要用双引号”“括起来,如果调用系统自带库,需要用尖括号<>括起来。这个形式上的问题,跟你的文件保存路径有关系,如果用错,MT5很可能同样找不到库文件。 比如要做下面这些事儿: - · 封装重复代码:风控计算、订单工具、字符串处理、数学计算,多处程序共用同一套代码,避免复制粘贴。
- · 封装结构体、枚举、类。MQL5 标准库(STL‑like 容器、数组工具、指标辅助类)全部是以库的形式提供。
- · 把复杂代码隔离出去,让 EA、脚本主代码变得简洁。
就可以调用或设计一个库。
第二:包含文件
前文提到,函数库(Library)中有两种文件,.mqh(头文件)和.mq5(库源码)。 这个”.mqh“就是包含文件,它并不是库本身,但可以作为简易程序的库来使用,也就是其他程序用来调用的东西。 而mq5(库源码)是编译型库程序的源代码文件,通过编译生成.ex5二进制库,可以被MT5程序调用,一般会配套一份.mqh头文件,用来函数声明(告诉 EA 有该库到底有哪些函数,也就是只有函数名称,没有函数内容)。 当你在EA程序中引用.mqh(头文件)时,相当于把该文件里的所有内容复制到EA程序中。 .ex5是编译之后的二进制成品,看不见源码,不能编辑,MT5 可以运行直接运行它。 这样别人只能看到你编的函数名字,看不到函数逻辑过程,也是一种保护手段。 如果你不在乎,也可以把你的函数写在.mqh文件中,所有拿到你代码的人,都可以研究你的函数到底是怎么个逻辑。 当然,你头铁完全不同函数库,所有的东西都写在你的EA程序文件中,它一样运转,一些简单的EA完全可以这样操作。 但是复杂的程序,还是建议使用函数库来编程,以保证主程序的简洁明了。 |