MQL5 简介(第 4 部分):掌握结构、类和时间函数(基础篇)
◍ 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 两行,证明字段赋值生效。
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 新建脚本,粘入下方代码跑一遍,比看十遍比喻都直白。外汇与贵金属杠杆高,实盘前任何封装逻辑都先在策略测试器回测。
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();