读写全局变量

MQL5 API 提供了 2 个函数用于读写全局变量:GlobalVariableSetGlobalVariableGet(两个版本)。

datetime GlobalVariableSet(const string name, double value)

该函数将新的 value 设置到 'name' 全局变量。如果在调用该函数之前该变量不存在,则将创建该变量。如果该变量已存在,则先前值将被替换为 value

如果成功,则函数返回变量修改时间(计算机的当前本地时间)。如果出错,则返回 0。

double GlobalVariableGet(const string name)

bool GlobalVariableGet(const string name, double &value)

该函数返回 'name' 全局变量的值。调用该函数第一个版本的结果仅包含变量的值(如果成功)或 0(如果出错)。由于变量可能包含 0 值(与错误指示相同),如果接收到零,该选项要求解析内部错误代码 _LastError ,以区分标准版本和非标准版本。尤其是如果试图读取一个并不存在的变量,则产生内部错误 4501 (GLOBALVARIABLE_NOT_FOUND)。

该函数版本适用于以下算法场景:获取零能等效模拟先前不存在的变量的默认初始化(参见下面的示例)。如果变量缺失需要以特殊方式(尤其是计算某些其它起始值)处理,则你应首先使用 GlobalVariableCheck 函数检查该变量的存在性,然后根据其检查结果执行不同的代码分支。或者,你可以使用第二个版本。

该函数的第二个版本根据执行的成功与否返回 truefalse。如果成功,则终端的全局变量的值被放入接收 value 变量中,通过引用作为第二参数传递。如果没有变量,则返回 false

在测试脚本 GlobalsRunCount.mq5 中,我们使用一个全局变量统计其运行次数。变量的名称是源文件的名称。

const string gv = __FILE__;

别忘了,内置宏 __FILE__(参见 预定义常量)由编译器扩展到被编译文件的名称中,即在本例中是 "GlobalsRunCount.mq5"。

OnStart 函数中,我们将尝试读取给定的全局变量,并将结果保存在本地 count 变量中。如果还没有全局变量,则返回 0,这对我们来说正常(我们从零开始计数)。

在将该值保存到 count 中之前,需要将其类型强制转换为 (int),因为 GlobalVariableGet 函数返回 double,如果没有强制转换,则编译器生成关于潜在数据丢失的警告(它不知道我们打算仅存储整数)。

void OnStart()
{
   int count = (int)PRTF(GlobalVariableGet(gv));
   count++;
   PRTF(GlobalVariableSet(gvcount));
   Print("This script run count: "count);
}

然后我们将计数器增加 1,并使用 GlobalVariableSet 将其写回到全局变量中。如果我们运行脚本若干次,我们将得到类似下面的日志条目(你的时间戳将不同):

GlobalVariableGet(gv)=0.0 / GLOBALVARIABLE_NOT_FOUND(4501)
GlobalVariableSet(gv,count)=2021.08.29 16:04:40 / ok
This script run count: 1
GlobalVariableGet(gv)=1.0 / ok
GlobalVariableSet(gv,count)=2021.08.29 16:05:00 / ok
This script run count: 2
GlobalVariableGet(gv)=2.0 / ok
GlobalVariableSet(gv,count)=2021.08.29 16:05:21 / ok
This script run count: 3

务必要注意,在第一次运行时,我们收到 0 值,并产生内部错误标志 4501。所有后续调用均正常执行,因为变量存在(可以在终端的“全局变量”窗口中看到)。感兴趣者可以关闭终端,重新启动它并再次执行该脚本:计数器将继续从先前的值增加。