面向对象编程基础(基础篇)
📘

面向对象编程基础(基础篇)

第 1/3 篇

「先搞清 MT5 里的对象到底是什么」

很多从 EA 脚本转过来的老交易员,习惯把一切写成线性函数,但在 MQL5 里,指标、订单、持仓甚至时间序列都被封装成了对象。理解对象,是写复杂策略的第一步。 官方示例库里有一篇 2013-11-06 发布的入门文,累计被查看 4093 次、收藏 55 次,作者 Dmitry Fedoseev,说明这块基础需求一直很硬。 对象的核心不是语法糖,而是把行情数据和操作逻辑绑在一起:你拿到一个对象,就能直接问它要价格、要状态,而不用满屏去找全局数组。外汇和贵金属波动快、滑点随机,用对象管理多品种监控会更稳,但高杠杆下任何架构都挡不住极端行情。

先写类再背名词

很多交易者翻开 MQL5 自带的 CTrade、CIndicator 这类现成类,一看到多态、封装、继承的字眼就脑壳疼,结果 OOP 学习直接卡死在名词关。实际上在 MT5 里用面向对象写 EA,你完全可以先不管术语,照着例子把类实例化跑起来再说。 根据 MQL5 标准库结构,光是 Trade 相关的封装类就超过 10 个,新手如果先啃完术语再动手,平均耗时可能是直接抄例子改参数的 3 倍以上。 当然,能跑和真懂是两回事。建议你边用边查:比如用 CTrade 下了一单后,反推它把下单校验封装在了哪一层,这样术语反而成了顺手的事后注解,而不是入门门槛。

◍ 把常用函数塞进类里做私有库

OOP 最接地气的起点,是给自己攒一套高频函数的库。传统做法丢进 mqh 包含文件,用的时候 #include 再调;但程序一长,几十上百个函数混在一个文件里,名字和用途全靠脑记,维护成本陡增。 一个更清晰的路子是按数据类型拆类:处理数组的放一个类,处理字符串的放一个类,统计订单的再放一个类。这里的“类”本质就是 OOP 里的基本结构——它把函数和变量按所操作的对象类型打包成模型,之后能派生出实例。 比起翻百科全书背“封装”“多态”这些词,先理解“类 = 同主题函数与变量的集合”就够开干了。MT5 里打开 MetaEditor,新建一个 .mqh,用 class 关键字把订单计算函数圈一起,比散装 mqh 更好检索,也方便后续多个 EA 复用。

「把脚本包成类,EA 里就能当独立程序跑」

不少老问题反复出现:怎么让 EA 直接调用一段脚本逻辑。常规做法是把脚本代码硬塞进 EA 源码,但脚本里用的变量名、函数名常和 EA 本身撞车,改起来虽不烧脑,量却可能很大。 更干净的路子是先把脚本写成一个类,再在 EA 里实例化调用。额外工作量也就是几行代码,类按“用途”而非“数据类型”聚合函数——比如专门删挂单的类、专门下市价单的类、封装图形对象的类。 类的关键价值在于命名空间隔离。它像操作系统里的一个独立进程:多个类可同时存活、各自运行、互不污染。所以业内管这叫“程序中的程序”,本质就是它和宿主 EA 的运行空间被切开了。 在 MT5 里验证很简单:新建一个 DeletePendingOrders 类,用 extern 开关从 EA 的 OnTick 里 new 出来调一次,看是否不碰 EA 原有持仓变量。外汇与贵金属杠杆高,类逻辑出错也会瞬时放大风险,先在策略测试器跑历史再上实盘。

类声明的右括号分号陷阱

在 MQL5 里定义一个类,语法起点是 class 加类名,随后用一对大括号把成员和方法的声明包起来。结构本身不复杂,但有一个极易被忽略的收尾要求。 很多从 C++ 转过来的老手也会在这里栽跟头:右大括号 } 之后必须跟一个分号 ;。漏掉它,MetaEditor 会在编译期直接报错,而不是给出友好提示。 下面这段是最精简的类骨架,注意看第三行末尾那个分号,它不是装饰: 千万别以为编译器会替你补全。MT5 的编译器对类声明结尾的分号是强制校验的,少一个字符就过不了编译。

MQL5 / C++
class CName 
  {
   class=class="str">"cmt">// 这里是类的入口代码
  };

◍ 把开仓动作藏进类里

点一下 MT5 的 Buy 或 Sell,背后并不是直接下单。终端要先校验持仓、核对 Stop Loss 与 Take Profit 数值、探一下网络链路,这一串流程交易者看不到,却被封装在底层。写 EA 时也能用同样的思路:把主逻辑暴露给外部,把校验和辅助计算藏起来。 MQL5 用 private 和 public 切分可见性。private 区里的变量和函数只能在类内部调用,public 区里的东西才能在 EA、脚本或指标里直接访问。下面这段就是最薄的类骨架,够你跑通 OOP 的基本隔离。

MQL5 / C++
class CName 
  {
class="kw">private:
   class=class="str">"cmt">// 变量和函数仅在类内部可用
class="kw">public:
   class=class="str">"cmt">// 变量和函数在类外部可用
  };
实操上,别再把所有代码平铺在 EA 的 OnTick 里。先建一个类,把仓位检查、风控判断丢进 private,只留一个 public 的入口函数给 OnTick 调。外汇和贵金属波动剧烈、杠杆风险高,封装能减少误调内部状态导致的异常下单。

MQL5 / C++
class CName 
  {
class="kw">private:
   class=class="str">"cmt">// 变量和函数仅在类内部可用
class="kw">public:
   class=class="str">"cmt">// 变量和函数在类外部可用
  };

常见问题

对象是你用class关键字定义出的数据类型实例,比如CTrade trade;里的trade就是对象,和K线不是一回事。
不用,先写几个自己的类把常用函数收进去,跑通了再回头看名词,理解会快很多。
可以,小布能读取你的代码并标出类声明右括号后的分号遗漏等低级错误,省去编译报错的来回。
因为开仓动作被藏进类的方法里,主逻辑只调用一行,改手数或止损只动类内部即可。
能,类实例化后可在EA中作为独立程序单元多次调用,比散函数更方便复用和隔离。