客户终端全局变量
在前一章中,我们学习了处理文件的 MQL5 函数。它们为读写任意数据提供了广泛、灵活的选项。然而,有时一个 MQL 程序需要以更简便的方式在运行之间保存和还原属性状态。
例如,我们想要计算某些统计信息:程序启动了多少次,在不同图表上并行执行了程序的多少个实例等等。这些信息无法在程序本身内部累计。必须有某种外部长期存储。为此创建一个文件也是可行的,只不过代价很高。
很多程序设计用于彼此交互,即它们必须以某种方式交换信息。如果我们说的是与终端外部的程序集成,或者传输大量数据,那么不使用文件便很难实现。但是,若无需发送大量数据,并且所有程序均是以 MQL5 编写并在 MetaTrader 5 中运行,则使用文件似乎是多余的。对于这种情况,终端提供了更为简单的技术:全局变量。
全局变量是在终端的共享内存中的一个指定位置。全局变量可以由任何 MQL 程序创建、修改或删除,但并不会被任何程序独占,并且可以由所有其它 MQL 程序使用。全局变量的名称是在所有变量中唯一的字符串,长度不超过 63 个字符。该字符串不必满足 MQL5 中变量标识符的要求,因为终端的全局变量不是常规意义上的变量。编程人员无需在源代码中根据我们在 变量章节学习的语法定义这些全局变量,它们不是 MQL 程序的一个组成部分,对它们的任何操作都只能通过调用本章将介绍的特殊函数实现。
全局变量允许你仅存储 double 类型的值。如果必要,你可以将其它类型的值包装/转换为 double,或者使用变量名称的一部分(例如,遵循某个前缀)存储字符串。
当终端正在运行时,全局变量存储在 RAM 中,几乎即时可用:唯一开销与函数调用有关。相比使用文件,全局变量无疑更具有优势,因为在使用文件时,获取句柄是一个相对缓慢的过程,而句柄本身也会消耗某些额外资源。
在终端会话结束时,全局变量被卸载进入一个特殊文件 (gvariables.dat),并在下次运行终端时从这个文件中还原。
一个特定全局变量如果在 4 个星期内未被申领使用,则会被终端自动销毁。此行为依赖于保持跟踪并存储变量的上次使用时间,其中“使用”指的是设置新值或读取旧值(但不是检查是否存在,也不会获取上次使用时间)。
请注意,全局变量并不与账户、数据图或交易环境的任何其它特性绑定。因此,如果要将它们用于存储与环境相关的内容(例如特定账户的某些一般限制),则变量名称的构建应考虑影响算法和决定的所有因素。要区分同一 EA 交易的多个实例的全局变量,你可能需要通过 EA 设置向名称添加现有交易品种、时间范围或“魔法数字”。
除了 MQL 程序,全局变量也可由用户手动创建。现有全局变量的列表以及它们的交互式管理方式可在通过 Tools -> Global Variables 命令 (F3) 在终端中打开的对话框中找到。
使用对应按钮,你可以Add和Delete全局变量,还可以在 Variable 或 Meaning 列中双击以编辑特定变量的名称或值。可从键盘使用以下热键:F2 用于名称编辑,F3 用于值编辑,Ins 用于添加新变量,Del 用于删除选定变量。
稍后我们将了解两个主要类型的 MQL 程序:“EA 交易”和“指标”。它们的特殊功能是能够在测试程序中运行,用于全局变量的函数也同样有效。然而,全局变量由测试程序代理在测试程序中创建、存储和管理。换言之,终端全局变量列表在测试程序中不可用,由受测试程序创建的变量属于特定代理,它们的生命周期仅限于一次测试传递。也就是说,该代理的全局变量对其它代理不可见,并且在测试运行结束时将被移除。尤其是如果 EA 针对若干个代理进行了 优化 ,则它可操纵全局变量,从而与它在同一代理上下文中使用的指标通信,因为它们在该上下文中一起执行,对于并行代理,EA 的其它副本将形成它们自己的变量列表。
使用全局变量进行的 MQL 程序之间的数据交换不是唯一可用的方法,也并非始终是最适当的方法。尤其是 EA 和指标是交互型 MQL 程序的情况下,此时它们可以生成和接受 图表上事件。你可以在事件参数中传递各种类型的信息。此外,计算数据数组能以 指标缓冲区的形式准备并提供给其它 MQL 程序。图表上的 MQL 程序可使用 UI 图形对象 传输和存储信息。
从技术角度而言,全局变量的最大数量仅受限于操作系统的资源。但是,对于大量元素,建议使用更适当的方式: 文件 或 数据库。