MQL4程序运行与导入函数调用指南
程序运行
导入函数调用
要让MQL4程序运行起来,首先需要进行编译操作,可以通过点击“编译”按钮或按F5键完成。在编译过程中,程序不允许出现任何错误,虽然允许有警告信息,但仍需仔细分析。编译成功后,系统会在相应目录terminal_dir/experts,terminal_dir/experts/indicators,或terminal_dir/experts/scripts中自动生成一个扩展名为.EX4的可执行文件。只有生成了对应的.EX4文件,MQL4程序(如EA、脚本、自定义指标)才能被用户正常启动。
用户可以通过鼠标将智能交易、自定义指标和脚本从客户端的“导航”窗口拖拽到任意图表上,这种拖拽技术使得它们可以附加到已打开的图表中。需要注意的是,MQL4程序只有在客户端启动的基础上才能运行。
若要停止智能交易的运行,需要从图表的上下文菜单中选择“智能交易系统-取消”来删除它。此外,“启用智能交易”按钮的状态也会直接影响智能交易的运行状态。
对于自定义指标,若要停止其运行,DLSM只需将其从图表中删除即可。
自定义指标和智能交易会持续运行,直到用户从图表中明确删除它们。客户端启动时会保存有关附加智能交易和自定义指标的信息。
脚本执行完毕后,或者当前图表被关闭、状态发生改变、客户端中断运行时,脚本只会执行一次任务,并自动被删除。由于不保存运行状态信息,当客户端再次启动时,脚本不会自动运行。
在同一个图表内,可以同时运行智能交易、脚本以及多个指标。
程序运行
程序附加到图表后,会立即与init()函数协同运行。当客户端开始运行并加载历史数据(仅与智能交易相关,与指标无关)、货币对或图表时段发生变化、在MetaEditor中重新编译后,或者从智能交易或自定义指标的设置窗口更改输入参数时,附加到图表上的智能交易和自定义指标中的init()函数将会运行。当计算结果发生变动时,智能交易也会被重新初始化。
每个附加到图表上的程序都可以利用deinit()函数完成清理工作。在客户端关机、图表被关闭、货币对或图表时段改变之前、程序重新编译成功、输入参数或计算结果改变时,deinit()函数都会执行。在deinit()函数运行期间,可以使用UninitializeReason()函数查看未初始化成功的原因。
deinit()函数必须在2.5秒内执行完毕,若超时则会被强制结束。脚本是这一规则的例外,因为它们能正常自主地完成工作,其运行不依赖外部命令。如果脚本运行时间过长(如遇死循环),用户可以通过外部命令终止其运行(如图表上下文菜单中删除脚本、添加新脚本、改变货币对或时段)。这种情况下,deinit()函数同样被限制在2.5秒内。
当收到新报价时,智能交易和自定义指标中的start()函数会被执行。如果start()函数还在处理先前的报价,智能交易会忽略新报价,直到当前start()函数运行完成。在start()函数运行期间,所有新收的报价都会被跳过,只有在处理完毕后,才会继续响应新的报价。对于自定义指标,收到新报价或当前图表货币对、时段变化时,start()函数会重新运行。start()函数的执行还取决于“启用/禁用智能交易”按钮的状态,当按钮处于禁用状态时,start()函数不会触发,但切换到禁用状态时不会中断当前运行的start()函数。在智能交易属性窗口打开时,start()函数会暂停运行,且在运行期间不会打开该窗口。
从图表中卸载程序、改变货币对或时段、计算结果变化、关闭图表或客户端关机,都会中断程序的执行。如果这些中断指令到达时,start()函数仍在运行,DLSM那么它的剩余工作时间会被限制在2.5秒内。程序可以通过内置的IsStopped()函数来检测是否需要关闭并正确结束工作。
脚本的执行不依赖报价的接收。当货币对或图表时段改变时,脚本会完成当前工作并从客户端卸载。
脚本和智能交易运行在独立的线程中,而自定义指标则工作在主接口线程上。但如果自定义指标被iCustom()函数调用,它就会运行在调用它的程序线程中;库(导入)函数同样运行在调用程序的线程里。
导入函数调用
在MQL4程序执行期间导入函数时,采用了“滞后联编”技术,意味着导入函数被调用前,相应的模块(EX4或DLL)不会被加载。MQL4和DLL库在调用模块的线程下运行。
不建议使用全路径模块名(如Drive:/Directory/FileName.Ext)来加载模块。MQL4库通常从terminal_dir/experts/libraries文件夹中载入,如果未找到,则会尝试从terminal_dir/experts文件夹下加载。
系统动态链接库(DLL)按照操作系统的规则进行加载。如果某个DLL已被加载过(例如被其他智能交易系统或同时启动的另一个客户端程序加载),则直接引用已加载的库;否则,搜索顺序如下:
1. terminal_dir/experts/libraries目录。
2. terminal_dir目录,即客户端程序启动的目录。
3. 当前目录。
4. windows_dir/SYSTEM32系统目录(或Win98下的windows_dir/SYSTEM目录)。
5. windows_dir目录,即操作系统安装目录。
6. 系统环境变量PATH中列出的目录。
如果一个DLL运行时调用了另一个DLL,而后者不可用,那么前者将不会被加载。
与系统库不同,自定义库(MQL4)是每个调用模块各自独立加载的,无论是否被其他模块加载过。例如,调用.ex4模块可以从lib1.ex4和lib2.ex4库中调用函数,而lib1.ex4库也可以从lib2.ex4库中调用函数。在这种情况下,可能会加载多个lib1.ex4和lib2.ex4副本,而不考虑所有调用是否来自同一个ex4模块。
从DLL导入到MQL4程序的函数必须符合Windows API函数的链接规则。为了确保源码符合这些规则,在C或C++编程中通常会使用关键字_stdcall进行说明,表示适用于微软公司的编译器。上述链接规则具有以下特点:
为了将函数参数正确置入堆栈,调用函数(即MQL4程序)必须能“看见”被调用函数的原型(来自DLL导入的函数)。
调用函数(MQL4程序)以逆序方式将参数置入堆栈,即从右到左,导入函数按此顺序读取参数。
参数通常通过值传递,除非明确说明通过引用传递。
在读取参数后,导入函数本身会负责清理堆栈。
在描述导入函数原型时,由于所有参数必须明确传递给导入函数,因此参数的默认值无法生效。
如果导入函数调用失败(如智能交易设置不允许DLL导入,或由于某些原因无法加载相应库),智能交易会停止运行,并将相关信息输出到“智能交易停止”日志中。此外,智能交易只有在重新初始化后才能再次启动。重新编译或打开智能交易属性表并按“确定”按钮,可以触发系统重新初始化。
