MQL5 简介(第 4 部分):掌握结构、类和时间函数(基础篇)
📘

MQL5 简介(第 4 部分):掌握结构、类和时间函数(基础篇)

第 1/2 篇

◍ MQL5 里时间函数怎么驱动 EA 节奏

MQL5 的EA不是靠人盯盘触发,而是靠事件与时间函数推进。TimeCurrent() 返回的是服务器当前时间(秒级 UNIX 时间戳),和本地电脑时钟不一定一致,跨时区跑策略时以它为准才能对齐经纪商K线。 很多新手把 Sleep() 当延时神器,但在 OnTick 里滥用会卡掉后续报价处理。正确做法是把时间判断交给定时逻辑:用 TimeLocal() 拿终端本地时间做界面显示,用 TimeCurrent() 做交易决策,二者职责分开。 一个可验证现象:在 MT5 终端按 F4 打开 MetaEditor,新建 EA 模板后,默认 OnTick 每秒可能触发多次,但 MqlDateTime 结构配合 TimeToStruct(TimeCurrent(), structVar) 能把时间戳拆成年/月/日/时/分/秒,方便写“仅在某小时段开仓”的过滤。外汇与贵金属杠杆高,时间窗误判会放大滑点风险。

「先摸清这一节要拆的三块骨头」

这一节不绕弯,直接把后面要啃的技术点摆清楚:结构体(struct)、类(class)、以及 MQL5 里处理时间的相关函数。对做过几周 EA 的人来说,这三者是写可维护策略代码的地基,跳过任何一个都会在回测模块里反复踩坑。 外汇和贵金属市场高杠杆、跳空频繁,用结构体和类把订单状态、品种参数封装好,比满屏全局变量更安全,也方便小布这类 AIGC 工具做静态扫描。 原文提到会附带一段回顾前一篇的总结视频,用来唤醒对第三部分的记忆;这对你而言是个可验证动作——打开 MT5 文档或对应系列前文,对照视频里的函数签名,确认自己环境里的 MQL5 版本号(例如 build 4410+)是否支持文中写法,再动手不迟。

用 struct 把散数据收进一个容器

MQL5 里的 struct 是一种用户自定义复合类型,能把 string、int、double 等不同类型字段捆成一个实体。对交易者而言,它最适合描述「一笔订单」或「一个品种的属性」——比如把品种名、点值、当前价差塞进同一个结构,后面调用时不用满屏找变量。 声明时先写 struct 加结构名,花括号内逐行列字段。下面这段就是最朴素的 Person 结构:三个字段分别占 1 个 string、1 个 int、1 个 string,编译后该结构尺寸为 2 个 32 位整数加 2 个字符串指针(具体内存随平台略异)。 新手常把数组和结构搞混:数组是同类型元素按索引排的列表,结构才是跨类型打包。做 EA 时若要把「账户净值为 10235.5、杠杆 1:500、风险百分比 2%」绑在一起跟踪,用结构比用三个独立数组更不容易写错下标。 声明完就能在 OnStart 里建实例。下例建了 person1、person2 两个实例并填值,Print 输出验证;你在 MT5 里新建脚本粘入,跑完终端会打印出 Israel 25 123 Main St 与 Bob 30 456 Oak St 两行,证明字段赋值生效。

MQL5 / C++
class="kw">struct Person
 {
    class="type">class="kw">string name;
    class="type">int age;
    class="type">class="kw">string address;
};
class="type">void OnStart()
  {
   class="kw">struct Person
     {
       class="type">class="kw">string        name;
       class="type">int           age;
       class="type">class="kw">string        address;
     };
class=class="str">"cmt">// Creating variables of type Person
   Person person1, person2;
class=class="str">"cmt">// Filling in details for person1
   person1.name = "Israel";
   person1.age = class="num">25;
   person1.address = "class="num">123 Main St";
class=class="str">"cmt">// Filling in details for person2
   person2.name = "Bob";
   person2.age = class="num">30;
   person2.address = "class="num">456 Oak St";
class=class="str">"cmt">// Now you can use person1 and person2 with their specific details
   Print("Details of Person class="num">1: ", person1.name, ", ", person1.age, ", ", person1.address);
   Print("Details of Person class="num">2: ", person2.name, ", ", person2.age, ", ", person2.address);
  }

◍ 从蓝图到实例:MT5 里类怎么落地

在 MQL5 写 EA 或脚本时,类就是一张造对象的蓝图。它不只装数据,还把操作数据的行为(方法)绑在一起。和 struct 比,struct 基本只是数据容器,类则能自带函数,适合把行情判断、下单逻辑封成一个可复用的模块。 下面这段直接在 OnStart 里声明了 Person 类,并实例化打印信息。注意 class 关键字后跟类名,public: 以下成员允许类外访问;displayInfo() 里用 Print 输出 name 与 age。 代码逐行看:Person person1; 是在栈上创建对象,person1.name="John" 与 person1.age=25 给属性赋值,person1.displayInfo() 调用方法向终端打印两行。跑完会在 MT5 Experts 日志看到 Name: John 和 Age: 25。 刚开始把类和结构搞混很正常。开 MT5 新建脚本,粘入下方代码跑一遍,比看十遍比喻都直白。外汇与贵金属杠杆高,实盘前任何封装逻辑都先在策略测试器回测。

MQL5 / C++
class="type">void OnStart()
  {
   class Person
    {
   class="kw">public:
     class=class="str">"cmt">// Attributes(data members)
     class="type">class="kw">string        name;
     class="type">int           age;
     class=class="str">"cmt">// Methods(member functions)
     class="type">void          displayInfo()
      {
       Print("Name: ", name);
       Print("Age: ", age);
      }
    };
class=class="str">"cmt">// Creating an object of the Person class
   Person person1;
class=class="str">"cmt">// Initializing attributes of the object
   person1.name = "John";
   person1.age = class="num">25;
class=class="str">"cmt">// Calling the displayInfo method to print information
   person1.displayInfo();
  }
class Person {
class="kw">public:
class="type">class="kw">string name;
class="type">int age;
class="type">void displayInfo() 
{
    Print("Name: ", name);
    Print("Age: ", age);
}
};
class="type">void OnStart() {
Person person1;
person1.name = "John";
person1.age = class="num">25;
person1.displayInfo();

常见问题

用TimeCurrent()取当前服务器时间,配合TimeHour()取出小时数做判断,只在目标区间返回交易信号即可。
用struct自定义结构,把同属一笔订单的字段声明在一个容器里,调用时直接点出字段名,不容易写错。
小布可以读取你的策略逻辑,标出时间判断漏洞和类实例化错误,并给出改写建议,省去手动排查。
struct只装数据无方法,class能带函数做封装;纯数据聚合用struct,要复用行为逻辑再用class。
在OnTick开头取一次TimeCurrent()存进变量,后续判断都读该变量,别在每个子函数里反复调用。