Skip to content

面向对象OOP

一、面向对象 vs 面向过程

掌握这部分内容后,才能理解下一章“如何在一个EA中运行多个策略”。此前未讲解,是因为知识点较为抽象,但随着学员职业多样化,理解OOP的需求也在增加。科班出身的开发者可能更容易理解,非科班学员尽量掌握——OOP是强大的编程思想,能让代码更简洁、易复用、可扩展,但在EA这种小规模开发中场景较少,大家量力而行。

1. 面向过程

注重“过程”,将任务拆分为按顺序执行的方法,所有方法执行完毕即完成任务。
举例:开车

  • 步骤:进入车辆 → 启动车辆 → 操作方向盘 → 行驶 → 停止 → 熄火 → 离开车辆
  • 特点:按流程顺序调用独立方法。

2. 面向对象

注重“对象”,将任务涉及的事物抽象为对象,通过对象的方法协作完成任务。
举例:开车

  • 对象:“人”和“车”
  • 人拥有的方法:拧钥匙(启动车辆)、掌控方向盘
  • 车拥有的方法:启动、行驶、停止
  • 执行:创建对象 → 按顺序调用对象的方法
  • 特点:先抽象对象,再通过对象交互解决问题。小规模问题中可能显得复杂,但适合复杂场景。

二、类(Class)的核心概念

类是OOP的基础,用于组织代码和数据。以下通过Strategy类示例拆分知识点:

1. 类的结构

cpp
class Strategy : public CObject {

public:
  long MagicNum;        // EA编号
  int SlType;           // 止损方式
  double SlParam;       // 止损依据
  string CurrentSymbol; // 当前品种
  ENUM_TIMEFRAMES TimeFrame; // 时间周期
  int BbPeriod;              //  bb周期
  int slBBandsRange;
  int efficiencyRatio;

  Strategy(long InpMagicNum, int InpSlType, double InpSlParam,
           string InpCurrentSymbol, ENUM_TIMEFRAMES InpTimeFrame,
           int InpBbPeriod, int InpSlBBandsRange, int InpefficiencyRatio) {
    MagicNum = InpMagicNum;
    SlType = InpSlType;
    SlParam = InpSlParam;
    CurrentSymbol = InpCurrentSymbol;

    TimeFrame = InpTimeFrame;
    BbPeriod = InpBbPeriod;
    slBBandsRange = InpSlBBandsRange;
    efficiencyRatio = InpefficiencyRatio;
  }

private:
  int barsTotal;
  double point;
  double initBalance;
  int handle;
  double upperBuffer[];
  double baseBuffer[];
  double lowerBuffer[];

  MqlTick currentTick;
  int efficiencyRatioHandle;
  double efficencyRatioBuffer[];
void OnInitEvent();
void OnTickEvent();
void OnDeinitEvent();
};

(1)成员变量

  • 私有成员(private:仅类内部可访问
  • 公有成员(public:类内外均可访问

(2)构造函数

  • 特殊成员函数,创建对象(new Strategy(...))时自动调用,用于初始化成员变量。
  • 必须传递构造函数定义的参数,否则编译报错。

(3)成员函数

  • 类内定义的函数,如OnInitEventOnTicketEvent,实现具体逻辑。

2. 封装与访问权限

  • 封装:将数据(成员变量)和操作(成员函数)封装到类中,通过private/public控制访问。
    • private:隐藏内部细节,外部不可直接访问(需通过类内公共方法间接操作)。
    • public:对外暴露的接口,允许外部调用。
  • 示例
cpp
void test() {
   Strategy * sg = new Strategy(102,4,10000,"AUDUSD.C",PERIOD_H3,2,2,2);
}

三、OOP在EA中的应用:封装策略

1. 传统EA vs 面向对象EA

  • 传统EA:参数通过input修饰,全局变量直接暴露,逻辑分散在全局函数中。
  • 面向对象EA
    • 将策略逻辑封装到类中,input参数转为类的公有成员或构造函数参数。
    • 全局变量转为类的私有成员,通过类方法访问。
    • 系统回调函数(如OnInitOnTickOnDeinit)转为类的成员函数,由外部调用。

2. 封装优势

  • 代码复用:多个策略可继承同一个基类,复用公共逻辑。
  • 多策略管理:一个EA中创建多个策略对象(如Strategy1Strategy2),独立管理各自状态和逻辑,避免全局变量冲突。

四、总结与建议

  • 抽象概念:封装、继承、多态等需系统学习,短期理解困难很正常。
  • 应用场景:若需在一个EA中运行多个策略,按固定模式封装类;若无此需求,可跳过OOP,优先掌握基础开发。
  • 目标:通过类的封装,为后续多策略管理奠定基础,代码结构更清晰、可扩展。