MQL5 中的高级变量和数据类型(基础篇)
◍ MQL5 里那些比 double 更狠的变量类型
写 EA 时如果只盯 int、double、string,等于把 MT5 一半武器库锁在仓库里。MQL5 在基础类型之外给了结构体、类、动态数组和枚举,这几样直接决定你处理报价和订单时的内存效率与代码可读性。 以动态数组为例,它能在运行时按需扩容,不像静态数组必须在编译期定死长度。处理多品种 tick 缓冲时,用 double 动态数组比开一大块固定数组更省内存,也避免越界崩 EA。 枚举(enum)则把魔法数字变成可读标签。下面这段定义了一个方向枚举,回测或日志里打印 BUY / SELL 比直接看 0、1 直观得多,排错时间能砍掉一块。 打开 MT5 按 F4 进 MetaEditor,新建脚本把下面代码贴进去编译,就能看到枚举和动态数组怎么配合跑。外汇与贵金属杠杆高,验证代码务必先用策略测试器历史数据,别直接上真实账户。
enum ENUM_DIR { BUY=class="num">0, SELL=class="num">1 }; class="type">class="kw">double ticks[]; class="type">void OnStart() { ArrayResize(ticks, class="num">100); ENUM_DIR dir = BUY; Print("direction=", dir); }
「MQL5 变量与数据类型要啃的硬骨头」
MT5 是目前零售外汇与贵金属交易者装机量最高的平台之一,其内嵌的 MQL5 语言覆盖了从均线警报到多币种对冲 EA 的全部开发需求。要在上面写得出能跑、能调、能实盘挂的系统,变量与数据类型是绕不开的底层结构。 前文已经铺垫过整数、双精度、字符串、布尔这些基础类型,也讲过 input 变量怎么让用户在 EA 参数面板里改偏好。本文进入更实战的部分:常量、数组、枚举、结构、类型转换,以及局部 / 全局 / 静态 / 预定义变量的生命周期差异。 外汇与贵金属杠杆交易风险极高,代码逻辑一处越界就可能触发异常平仓。建议每学一个概念就进 MT5 的 MetaEditor 敲一段最小可运行样例,比如先声明一个含 5 个 double 的数组,再写循环打印,比纯看文档印象深得多。 下面列出的 9 个主题会逐一拆开讲,并配可复制的代码段。编程是门手上出真知的活,光读不写等于没学。
MT5 里两种写死常量值的路数
MQL5 里常量就是第一次赋值后不能再改的只读标识,硬去改会在编译期或运行前直接报错。这点和外汇、贵金属 EA 开发关系很大——把点差上限、魔术码、品种名写死成常量,能避免逻辑里被误改引发滑点风险。 第一种是全局常量,用 #define 预处理器在文件头部定义,例如 #define PLATFORM_NAME "MetaTrader 5",后面在 OnStart() 里 Print 出来,专家日志会显示「The trading platform name is: MetaTrader 5」。这种常量没有类型约束,纯文本替换。 第二种是 const 指示符,写在类型前面:const int val = 1;。它带数据类型,作用域和普通变量一致。下面这段代码把两种写法放一起,常量 val 锁死为 1,普通变量 val2 初始为 2,打印后前者不变、后者可改。 若尝试 val2 = 4; 再打印,val2 输出 4 而 val 仍是 1。若对 val 重新赋值,编译器直接报错终止,不会生成 ex5。实盘前建议把这类代码丢进 MT5 策略测试器编译一遍验证。
class="macro">#define Identifier_Name constant_value class="macro">#define PLATFORM_NAME "MetaTrader class="num">5" class="type">void OnStart() { Print("The trading platform name is: ", PLATFORM_NAME); } const class="type">int varName = assignedVal const class="type">int val = class="num">1; Print("constant val is: ", val); const class="type">int val = class="num">1; class="type">int val2 = class="num">2; Print("constant val is: ", val); Print("val class="num">2 is: ", val2); val2 = class="num">4;
◍ MT5里数组的静态、动态与多维写法
数组本质是一个带索引的列表,索引从 0 起算。一个长度为 5 的数组,可用索引是 0、1、2、3、4,最大索引等于数组大小减 1,这是 MQL5 里取数组边界时最容易写越界的地方。
静态数组在声明时就锁死大小,比如 int newArray[5] 之后不能再扩。下面这段是标准写法,逐个赋值再打印,跑完会在专家日志里看到 Index 0~4 对应 1~5。
动态数组用空方括号声明,靠 ArrayResize 在运行时改长度。接价格或指标缓冲时几乎都用它,因为 K 线数随时在变。下方代码把 myDynArray 扩到 3 位并填 1.5 / 2.5 / 3.5,日志会出三条 Dynamic Array 记录。
多维数组可理解为数组里嵌数组。最常碰的是二维,例如 double newMultiArray[2][2] 存了两组各两个浮点值:组0为 1.5、2.5,组1为 3.5、4.5。注意多维声明只允许第一维留空,如 double newMultiArray[][2],再用变量传大小给 ArrayResize 即可,编译结果与前一种一致。
外汇与贵金属杠杆高、滑点突变频繁,用动态数组接实时报价时,要防 Resize 滞后导致缓冲错位,可能引发行情判断偏差。
<span class="keyword">class="type">int</span> newArray[<span class="number">class="num">5</span>]; newArray[<span class="number">class="num">0</span>] = <span class="number">class="num">1</span>; newArray[<span class="number">class="num">1</span>] = <span class="number">class="num">2</span>; newArray[<span class="number">class="num">2</span>] = <span class="number">class="num">3</span>; newArray[<span class="number">class="num">3</span>] = <span class="number">class="num">4</span>; newArray[<span class="number">class="num">4</span>] = <span class="number">class="num">5</span>; <span class="functions">Print</span>(<span class="class="type">class="kw">string">"newArray - Index class="num">0 - Value: "</span>, newArray[<span class="number">class="num">0</span>]); <span class="functions">Print</span>(<span class="class="type">class="kw">string">"newArray - Index class="num">1 - Value: "</span>, newArray[<span class="number">class="num">1</span>]); <span class="functions">Print</span>(<span class="class="type">class="kw">string">"newArray - Index class="num">2 - Value: "</span>, newArray[<span class="number">class="num">2</span>]); <span class="functions">Print</span>(<span class="class="type">class="kw">string">"newArray - Index class="num">3 - Value: "</span>, newArray[<span class="number">class="num">3</span>]); <span class="functions">Print</span>(<span class="class="type">class="kw">string">"newArray - Index class="num">4 - Value: "</span>, newArray[<span class="number">class="num">4</span>]); <span class="keyword">class="type">int</span> newArray[<span class="number">class="num">5</span>] = {<span class="number">class="num">1</span>, <span class="number">class="num">2</span>, <span class="number">class="num">3</span>, <span class="number">class="num">4</span>, <span class="number">class="num">5</span>}; <span class="functions">Print</span>(<span class="class="type">class="kw">string">"newArray - Index class="num">0 - Value: "</span>, newArray[<span class="number">class="num">0</span>]); <span class="functions">Print</span>(<span class="class="type">class="kw">string">"newArray - Index class="num">1 - Value: "</span>, newArray[<span class="number">class="num">1</span>]); <span class="functions">Print</span>(<span class="class="type">class="kw">string">"newArray - Index class="num">2 - Value: "</span>, newArray[<span class="number">class="num">2</span>]); <span class="functions">Print</span>(<span class="class="type">class="kw">string">"newArray - Index class="num">3 - Value: "</span>, newArray[<span class="number">class="num">3</span>]); <span class="functions">Print</span>(<span class="class="type">class="kw">string">"newArray - Index class="num">4 - Value: "</span>, newArray[<span class="number">class="num">4</span>]); <span class="keyword">class="type">class="kw">double</span> myDynArray[]; <span class="functions">ArrayResize</span>(myDynArray,<span class="number">class="num">3</span>); myDynArray[<span class="number">class="num">0</span>] = <span class="number">class="num">1.5</span>; myDynArray[<span class="number">class="num">1</span>] = <span class="number">class="num">2.5</span>; myDynArray[<span class="number">class="num">2</span>] = <span class="number">class="num">3.5;</span> <span class="functions">Print</span>(<span class="class="type">class="kw">string">"Dynamic Array class="num">0: "</span>,myDynArray[<span class="number">class="num">0</span>]); <span class="functions">Print</span>(<span class="class="type">class="kw">string">"Dynamic Array class="num">1: "</span>,myDynArray[<span class="number">class="num">1</span>]); <span class="functions">Print</span>(<span class="class="type">class="kw">string">"Dynamic Array class="num">2: "</span>,myDynArray[<span class="number">class="num">2</span>]); <span class="keyword">class="type">class="kw">double</span> newMultiArray[<span class="number">class="num">2</span>][<span class="number">class="num">2</span>]; newMultiArray[<span class="number">class="num">0</span>][<span class="number">class="num">0</span>] = <span class="number">class="num">1.5</span>; newMultiArray[<span class="number">class="num">0</span>][<span class="number">class="num">1</span>] = <span class="number">class="num">2.5</span>; newMultiArray[<span class="number">class="num">1</span>][<span class="number">class="num">0</span>] = <span class="number">class="num">3.5</span>; newMultiArray[<span class="number">class="num">1</span>][<span class="number">class="num">1</span>] = <span class="number">class="num">4.5</span>; <span class="functions">Print</span>(<span class="class="type">class="kw">string">"Array1 - Index class="num">0 - Value: "</span>, newMultiArray[<span class="number">class="num">0</span>][<span class="number">class="num">0</span>]); <span class="functions">Print</span>(<span class="class="type">class="kw">string">"Array1 - Index class="num">1 - Value: "</span>, newMultiArray[<span class="number">class="num">0</span>][<span class="number">class="num">1</span>]); <span class="functions">Print</span>(<span class="class="type">class="kw">string">"Array2 - Index class="num">0 - Value: "</span>, newMultiArray[<span class="number">class="num">1</span>][<span class="number">class="num">0</span>]); <span class="functions">Print</span>(<span class="class="type">class="kw">string">"Array2 - Index class="num">1 - Value: "</span>, newMultiArray[<span class="number">class="num">1</span>][<span class="number">class="num">1</span>]); <span class="keyword">class="type">class="kw">double</span> newMultiArray[][<span class="number">class="num">2</span>]; <span class="keyword">class="type">int</span> array1 = <span class="number">class="num">2</span>; <span class="functions">ArrayResize</span>(newMultiArray, array1);