保持敬畏之心
交易是一场持久战

MQL4(53):终端全局变量

在之前的讨论中,我们提及的“全局变量”通常指的是在EA程序代码内部具有全局作用域的变量。然而,MetaTrader平台自身提供了一套函数,用于设置一种特殊类型的变量——“终端级别全局变量”。这些变量一旦被设定,就可以被当前在该终端上运行的所有EA所访问和共享(前提是其他EA知道这些变量的准确名称)。

MQL的官方文档将这类变量也称为“全局变量”,但或许称之为“终端变量”能更清晰地区分它们与程序内部的全局变量。要操作这类终端级别的全局变量,我们需要使用MQL参考手册中“全局变量(Global variables)”章节下定义的系列函数。用户可以通过MetaTrader终端的“工具”菜单 -> “全局变量”选项,或者直接按 F3 快捷键,来查看当前终端上已存在的所有全局变量列表。

终端级别全局变量的一个实用场景是,将EA的某些关键状态信息(尤其是那些具有全局性或应持久化的信息)保存到终端。这样,即便是EA意外关闭或重启,之后也能读取这些保存的状态,从而尝试从中断的地方恢复运行。当然,并非所有EA都需要这样的机制。但对于一些逻辑复杂的EA而言,它们运行时可能会维持某种特定的内部状态,一旦这种状态因中断而丢失,EA的后续操作逻辑就可能发生错乱。

从设计层面看,避免创建这类需要复杂状态管理的EA自然是上策。但如果复杂性难以避免,那么在发生意外关停时,利用全局变量函数将EA的当前状态写入终端,不失为一种有益的补救措施。需要强调的是,这种方法并非绝对可靠(例如,在某些极端情况下,写入操作本身也可能失败),但它很可能是目前能达到的最佳的、简便的状态持久化方案了。

要声明并设置一个终端级别的全局变量,应使用 GlobalVariableSet() 函数。该函数的第一个参数是一个字符串,用作该全局变量的名称;第二个参数是一个 double 类型的值,即要赋给该变量的内容。

GlobalVariableSet(VariableName_as_String, Value_as_Double);

为了确保您的终端全局变量名称具有唯一性,避免与其他EA或脚本的变量冲突,推荐的做法是为您的EA所创建的全局变量名添加一个独特的前缀。您可以在EA中声明一个普通的字符串型全局变量(程序内部),然后在EA的 init() 初始化函数中,结合当前图表的交易品种、时间周期、EA自身的名称以及魔术号等信息,动态构建这个唯一的前缀。

// 程序内部的全局变量,用于存储前缀
string GlobalVariablePrefix;

int init()
{
    // 构建唯一前缀
    GlobalVariablePrefix = Symbol() + (string)Period() + "_" + "ProfitBusterEA" + "_" + (string)MagicNumber + "_";
    return(0); // init() 函数标准返回
}

在这个例子中,我们组合了当前交易品种(Symbol())、图表周期(Period())、一个EA的特定标识(如 “ProfitBusterEA”)以及外部输入的 MagicNumber,共同构成了一个前缀字符串。此后,当您使用 GlobalVariableSet() 函数设置终端全局变量时,就可以将这个前缀与实际的变量名拼接起来:

GlobalVariableSet(GlobalVariablePrefix + "MyCounter", CurrentCounterValue);

举例来说,如果您的EA名为 “ProfitBusterEA”,在一张 EURUSD 的 M15(15分钟)图表上运行,使用的魔术数字是11,并且您想保存一个名为 MyCounter 的变量,那么最终在终端中创建的全局变量的完整名称将会是 EURUSD15_ProfitBusterEA_11_MyCounter。您可以根据自己的喜好制定命名规范,但强烈建议至少包含上述这些能提供上下文辨识度的信息。

要从终端读取一个已存在的全局变量的值,可以使用 GlobalVariableGet() 函数,只需提供该全局变量的完整名称作为参数即可:

CurrentCounterValue = GlobalVariableGet(GlobalVariablePrefix + "MyCounter");

若要删除某个不再需要的终端全局变量,可以使用 GlobalVariableDel() 函数,同样以其完整名称作为参数。如果您希望一次性删除由您的EA(通过特定前缀标识)创建的所有终端全局变量,可以使用 GlobalVariableDeleteAll() 函数,并将之前定义的前缀作为参数传入。

GlobalVariableDel(GlobalVariablePrefix + "MyCounter"); GlobalVariableDeleteAll(GlobalVariablePrefix);

关于终端全局变量系列函数的更详尽信息和用法,请查阅MQL参考手册中的“全局变量(Global variables)”相关章节。

赞(0)
未经允许不得转载:图道交易 » MQL4(53):终端全局变量
分享到