MQL5 编程基础: 终端中的全局变量(基础篇)
📘

MQL5 编程基础: 终端中的全局变量(基础篇)

第 1/3 篇

◍ 终端全局变量到底存在哪

MT5 里有一类叫全局变量(Global Variable)的东西,它不属于某个 EA 或指标,而是挂在终端进程之下的键值对,存活周期跟随终端运行,重启终端即清空。 这类变量适合在多个 EA、脚本之间传递状态,比如一个脚本算出日内波动率阈值,另一个 EA 直接读走,不必走文件或图表对象。 需要留意:全局变量不是跨终端共享的,每台机器、每个 MT5 实例各自独立;外汇与贵金属杠杆高,用它做跨品种协同开关时,要先在小账户验证同步延迟。 下面这段演示写入与读取一个全局变量,键名 gv_Test,值设为当前卖价:

MQL5 / C++
class=class="str">"cmt">//--- 写入全局变量
class="type">bool res = GlobalVariableSet("gv_Test", SymbolInfoDouble(_Symbol, SYMBOL_BID));
class=class="str">"cmt">//--- 读取并打印
class="type">class="kw">double val = GlobalVariableGet("gv_Test");
Print("gv_Test = ", val);
GlobalVariableSet 返回 bool,写入失败(如名称非法或终端内存紧张)会返回 false;GlobalVariableGet 在键不存在时返回 0,因此用前最好用 GlobalVariableCheck 确认存在,避免把‘没设过’误当‘值为 0’。

MQL5 / C++
class=class="str">"cmt">//--- 写入全局变量
class="type">bool res = GlobalVariableSet("gv_Test", SymbolInfoDouble(_Symbol, SYMBOL_BID));
class=class="str">"cmt">//--- 读取并打印
class="type">class="kw">double val = GlobalVariableGet("gv_Test");
Print("gv_Test = ", val);

终端全局变量能干什么

MT5 终端里的全局变量(Global Variable)和 EA 内部变量不同,它存活在客户端内存中,跨图表、跨 EA 实例都能读写,重启终端前一直有效。对做多品种协同、跨周期信号传递的交易者来说,这是不用落盘文件就能交换状态的最轻量通道。 这类变量名最长 63 字节,值类型为 double,写入后默认带一个时间戳记录最近一次修改时刻。需要注意:终端全局变量不随账户切换隔离,同一台终端登录不同账户时它们仍然可见,这在跟单或回测隔离时要特别小心。 从实战角度,它适合放「当前持仓指纹」「跨 EA 心跳」「限价单序列号」这类短小状态;不适合塞历史 K 线或大体量矩阵。后续小节会逐一拆开创建、读取、按条件改写和批量清理的具体函数。

「终端全局变量到底特殊在哪」

MT5 里的终端全局变量是 MetaTrader 与 MQL 体系独有的机制,和常规编程语言中那些随程序生命周期存活的全局变量不是一回事。很多 MQL5 新手绕开它,原因很直白:函数名拗口(GlobalVariableSet / GlobalVariableGet / GlobalVariableCheck 等),且不清楚何时该用。 关键差异在于持久性:终端全局变量在 MT5 完全关闭后依然保留数值。这一特性让它在编写订单间需要复杂交互的 EA 时,成了保存关键状态的轻量方案——不必落盘写文件,也不依赖数据库。 初学者常误以为它等同代码里的全局变量(如 MovingAverage EA 中那些红色标出的变量),其实后者随 EA 停止而释放。掌握终端全局变量后,做跨会话状态保持的 EA 会明显更顺手,但外汇与贵金属交易本身高风险,任何机制都只是工具,不预示胜率。

◍ MT5 里手动翻全局变量窗口

开 MT5 后走 主菜单 — 工具 — 全局变量,会弹出全局变量窗口(原文图 3)。写 EA 能靠代码管这些变量,但这个窗口在测策略时很实用:你能直接看终端里所有全局变量的名称、数值,也能改。 想改某个变量,点它的名称或数值栏位就能编辑;右上角“增加”建新变量,“删除”前先点中目标变量按钮才激活。练一遍建、改、删,但窗口里若已有变量别动——那可能是你账户上挂着的 EA 在用。 每个全局变量带三个属性:名称、数值、时间。时间栏显示最后一次访问时刻,若超 4 周没访问,变量会被自动清除。重要数据靠它存的话,得周期性访问一下续命。

用一行函数往终端塞个全局变量

MT5 终端里的全局变量不需要预先声明,第一次赋值就自动建好;同名再写则会直接覆盖旧值。核心只有 GlobalVariableSet(),它吃两个参数:字符串形式的变量名、double 类型的数值。 打开 MetaEditor 建个脚本,在 OnStart() 里写一行就能验证。跑完脚本后,到终端的「全局变量」窗口看,会多出一个叫 test 的条目,数值停在 1.23。 这套动作在 sGVTestCreate 脚本里有完整示例。外汇和贵金属行情高波动,全局变量虽不下单,但常被用来跨 EA 传状态,误写同名变量可能让逻辑串味,建议命名加前缀隔离。

MQL5 / C++
GlobalVariableSet("test",class="num">1.23);

「读终端全局变量时的两种取法与报错细节」

MT5 终端的全局变量在脚本跑完之后仍驻留内存,想在外面读它的数值就用 GlobalVariableGet()。这个函数有两条调用路径:只传变量名,返回 double;或者传名称加引用变量,返回 bool 表示成败。 只传名的写法运行后弹窗显示 1.23,对应附件脚本 sGVTestGet1。双参数写法把 val 以引用方式传入,成功时弹窗打出 'true 1.23',失败则 result 为 false。 如果去读一个不存在的变量,双参数版会返回 false 并且 val 保持原值——例子里先给 val 赋 1.0 再读 'test2',弹窗是 'false 0.0',脚本见 sGVTestGet2-2。单参数版在变量缺失时同样回 0.0,但会同时写错误码。 单参数配合 ResetLastError 和 GetLastError 能拿到和双参数版等同的信息:读 'test2' 弹窗显示 '0.0 4501',4501 即『客户终端中的全局变量没有找到』。这不是致命错误,只是通知,算法允许时可直接引用不存在的变量。 典型用法是跟踪历史最大余额:MathMax 比较实时权益与 'max_equity' 旧值,变量不存在时旧值视为 0.0,首跑即落定真实权益。外汇与贵金属交易端全局变量跨 EA 共享,杠杆品类波动剧烈,误读残留变量可能引发逻辑偏差,开 MT5 用下面代码逐段验证即可。

MQL5 / C++
class="type">class="kw">double val=GlobalVariableGet("test");
Alert(val);
class="type">class="kw">double val;
class="type">bool result=GlobalVariableGet("test",val);
Alert(result," ",val);
class="type">class="kw">double val=class="num">1.0;
class="type">bool result=GlobalVariableGet("test2",val);
Alert(result," ",val);
ResetLastError();
class="type">class="kw">double val=GlobalVariableGet("test2");
class="type">int err=GetLastError();
Alert(val," ",err);
GlobalVariableSet("max_equity",MathMax(GlobalVariableGet("max_equity",AccountInfoDouble(ACCOUNT_EQUITY))));

常见问题

用终端全局变量存关键状态(如仓位方向、开仓价),EA重启时读取即可续上,不依赖图表或文件。
指标存在图表内存里,关图就丢;终端全局变量存在终端层级,关图表甚至关图表窗口都还在,除非手动删或终端退出。
可以,小布能定时读取终端全局变量并跨品种汇总提醒,你不用自己挨个开窗口抄数值。
返回 0 且 GetLastError() 为 ERR_GLOBAL_VARIABLE_NOT_FOUND;别只看返回值,必须查错误码区分“真为0”和“没这变量”。
在终端菜单找全局变量窗口(或对应面板),里面列了名称、数值、创建与最后访问时间,可手动删或改。