外汇EA编写教程:使用面向对象方法编写EA模式

简介

在本文中,我们将讨论MQL5EA可以运行的编程模式。本文的目的是解释“每种模式都是以自己的方式实现”的思想。作者认为,这种方法可以使企业在不同阶段的开发效率更高。

首先,我们需要考虑EA开发包含哪些阶段。然后,讨论了元交易者5中EA的运行模式及其辅助应用。最后,本文总结了上述思想在各个层面的实施情况。

1。开发步骤

开发自动交易系统是一项多方面的工作。关键部分是算法的实现和测试。需要注意的是,EA的事务逻辑和算法代码需要严格测试。

实施步骤如下(图1)。

图1. 开发步骤及EA的实现

图1。EA的开发步骤和实施

“算法交易”的第五阶段需要开发人员、程序员、分析师和其他专业人员的参与。只有当所有这些任务都由一个人完成时,才能实现。假设这是一个程序交易者。

此方案可以更新和扩展。在我看来,这是EA开发中最重要的地方。这种循环模式使EA能够在整个开发周期中得到改进和修改。

在每个发展阶段都需要特定的工具、知识和技能。

在我看来,开发人员将遇到以下简单的变量矩阵(图2)。

图2. 变量矩阵

图2。变量矩阵

很明显,只有高代码质量的盈利策略才能被称为“算法交易”的第五阶段。

2。MQL5中的EA模式

在MQL5环境下,EA可以以不同的模式运行。有七种型号。让我们逐个分析它们。

程序文件有两种类型:

  1. 需要源文件和可执行文件的模式。
  2. 并且只需要可执行文件模式。

调试和分析模式属于第一类。

区分模式的另一种方法是查看EA是基于真实数据还是历史数据运行。所有测试模式都使用历史数据。

编程定义了六种模式。结果可用于确定EA是否以标准(发布)模式运行。模拟EA程序可用于市场交易的ex5后缀文件)应在此模式下运行。同时,该程序还允许在策略测试仪中使用其他模式。

让我们为MQL程序的执行模式创建枚举值enum_mql_模式:

//+------------------------------------------------------------------+
//| MQL 模式                                                          |
//+------------------------------------------------------------------+
enum ENUM_MQL_MODE
  {
   MQL_MODE_RELEASE=0,       // 发布
   MQL_MODE_DEBUG=1,         // 调试
   MQL_MODE_PROFILER=2,      // 分析 
   MQL_MODE_TESTER=3,        // 测试
   MQL_MODE_OPTIMIZATION=4,  // 优化
   MQL_MODE_VISUAL=5,        // 可视化测试 
   MQL_MODE_FRAME=6,         // 时间框架集结
  };

这些值稍后将用于确定EA的当前操作模式。

2.1。确定和测试模式的功能

编写一个简单的函数来检测日志中的所有模式和打印信息。

//+------------------------------------------------------------------+
//| 检验所有MQL程序模式                                                |
//+------------------------------------------------------------------+
void CheckMqlModes(void)
  {
//--- 如果是调试模式
   if(MQLInfoInteger(MQL_DEBUG))
      Print("Debug mode: yes");
   else
      Print("Debug mode: no");
//--- 如果是分析模式
   if(MQLInfoInteger(MQL_PROFILER))
      Print("Profile mode: yes");
   else
      Print("Profile mode: no");
//--- 如果是测试模式
   if(MQLInfoInteger(MQL_TESTER))
      Print("Tester mode: yes");
   else
      Print("Tester mode: no");
//--- 如果是优化模式
   if(MQLInfoInteger(MQL_OPTIMIZATION))
      Print("Optimization mode: yes");
   else
      Print("Optimization mode: no");
//--- 如果是可视化测试模式
   if(MQLInfoInteger(MQL_VISUAL_MODE))
      Print("Visual mode: yes");
   else
      Print("Visual mode: no");
//--- 如果是时间框架聚集的优化结果模式
   if(MQLInfoInteger(MQL_FRAME_MODE))
      Print("Frame mode: yes");
   else
      Print("Frame mode: no");
  }


我们将检查函数中的每个模式。它可以在OnInit()事件句柄中调用。

为了测试,我们创建了一个EA模板test1_modes_ea.mq5。

输入参数中有一个选项,用于确定EA将在哪个模式下运行。确保模式名称正确是很重要的,否则信息将不正确。就是这样。

以下是释放模式。

CL      0       17:20:38.932    Test1_Modes_EA (EURUSD.e,H1)     Current mode: MQL_MODE_RELEASE
QD      0       17:20:38.932    Test1_Modes_EA (EURUSD.e,H1)     Debug mode: no
KM      0       17:20:38.932    Test1_Modes_EA (EURUSD.e,H1)     Profile mode: no
EK      0       17:20:38.932    Test1_Modes_EA (EURUSD.e,H1)     Tester mode: no
CS      0       17:20:38.932    Test1_Modes_EA (EURUSD.e,H1)     Optimization mode: no
RJ      0       17:20:38.932    Test1_Modes_EA (EURUSD.e,H1)     Visual mode: no
GL      0       17:20:38.932    Test1_Modes_EA (EURUSD.e,H1)     Frame mode: no


对于发布模式,所有其他模式都标识为0。因此,函数确定这既不是调试模式:否,也不是配置文件模式:否,依此类推。由此我们可以得出结论,当前的操作模式是释放模式。

现在我们来看看如何确定调试模式。

HG      0       17:27:47.709    Test1_Modes_EA (EURUSD.e,H1)     Current mode: MQL_MODE_DEBUG
LD      0       17:27:47.710    Test1_Modes_EA (EURUSD.e,H1)     Debug mode: yes
RS      0       17:27:47.710    Test1_Modes_EA (EURUSD.e,H1)     Profile mode: no
HE      0       17:27:47.710    Test1_Modes_EA (EURUSD.e,H1)     Tester mode: no
NJ      0       17:27:47.710    Test1_Modes_EA (EURUSD.e,H1)     Optimization mode: no
KD      0       17:27:47.710    Test1_Modes_EA (EURUSD.e,H1)     Visual mode: no
RR      0       17:27:47.710    Test1_Modes_EA (EURUSD.e,H1)     Frame mode: no


调试模式已正确标识。

在任何编程手册中,都提到在模式模式模式下很容易发现和定位错误。同时也强调了程序的特殊性。有关在MQL5环境中调试程序的详细信息,请参阅文章“调试MQL5程序”。

该模型最常用于交易策略的形成和算法的构建阶段。

在程序中,调试模式可以由is_debug_mode宏或mqlinfointeger()函数的mql_debug标识符设置。

接下来,让我们检查分析模型。

GS      0       17:30:53.879    Test1_Modes_EA (EURUSD.e,H1)     Current mode: MQL_MODE_PROFILER
OR      0       17:30:53.879    Test1_Modes_EA (EURUSD.e,H1)     Debug mode: no
GE      0       17:30:53.879    Test1_Modes_EA (EURUSD.e,H1)     Profile mode: yes
QM      0       17:30:53.879    Test1_Modes_EA (EURUSD.e,H1)     Tester mode: no
CE      0       17:30:53.879    Test1_Modes_EA (EURUSD.e,H1)     Optimization mode: no
FM      0       17:30:53.879    Test1_Modes_EA (EURUSD.e,H1)     Visual mode: no
GJ      0       17:30:53.879    Test1_Modes_EA (EURUSD.e,H1)     Frame mode: no


功能正确识别当前分析模式。

在此模式下,可以检测程序的运行速度。分析模式可以将时间开销信息传送到程序段。该函数可以检测算法的瓶颈。尽管可能无法消除瓶颈,但至少这些信息非常有用。

分析模式可以由is_profile_mode宏或mqlinfointeger()函数的mql_profiler标识符设置。

现在让我们看看测试模式。策略测试人员的信息将显示在“日志”选项卡下。

EG      0       17:35:25.397    Core 1  2014.11.03 00:00:00   Current mode: MQL_MODE_TESTER
OS      0       17:35:25.397    Core 1  2014.11.03 00:00:00   Debug mode: no
GJ      0       17:35:25.397    Core 1  2014.11.03 00:00:00   Profile mode: no
ER      0       17:35:25.397    Core 1  2014.11.03 00:00:00   Tester mode: yes
ED      0       17:35:25.397    Core 1  2014.11.03 00:00:00   Optimization mode: no
NL      0       17:35:25.397    Core 1  2014.11.03 00:00:00   Visual mode: no
EJ      0       17:35:25.397    Core 1  2014.11.03 00:00:00   Frame mode: no


测试模式已正确识别。

打开策略测试仪时,这是EA的默认模式。

没有与此模式对应的宏。在mql5中,我们只能通过mqlinfointeger()函数的mql_测试仪标识符来设置它。

现在我们来看看优化模型。日志将保存在检测仪的文件夹中。在我的示例中,将目录另存为:%program files/metatrader5/tester/agent-127.0.0.1-3000/logs

OH      0       17:48:14.010    Test1_Modes_EA (EURUSD.e,H1)     2014.11.03 00:00:00   Current mode: MQL_MODE_OPTIMIZATION
KJ      0       17:48:14.010    Test1_Modes_EA (EURUSD.e,H1)     2014.11.03 00:00:00   Debug mode: no
NO      0       17:48:14.010    Test1_Modes_EA (EURUSD.e,H1)     2014.11.03 00:00:00   Profile mode: no
FI      0       17:48:14.010    Test1_Modes_EA (EURUSD.e,H1)     2014.11.03 00:00:00   Tester mode: yes
KE      0       17:48:14.010    Test1_Modes_EA (EURUSD.e,H1)     2014.11.03 00:00:00   Optimization mode: yes
LS      0       17:48:14.010    Test1_Modes_EA (EURUSD.e,H1)     2014.11.03 00:00:00   Visual mode: no
QE      0       17:48:14.010    Test1_Modes_EA (EURUSD.e,H1)     2014.11.03 00:00:00   Frame mode: no


如果激活优化模式,则默认情况下将打开测试模式。

如果“设置”选项卡中未禁止“优化”字段,则在策略测试仪中启用“优化”模式。

要确认是否在优化模式下测试MQL5中的EA,将使用MQL U优化标识符调用mqlinfointeger()函数。

我们再来看看可视化模式。

JQ      0       17:53:51.485    Test1_Modes_EA (EURUSD.e,H1)     2014.11.03 00:00:00   Current mode: MQL_MODE_VISUAL
JK      0       17:53:51.485    Test1_Modes_EA (EURUSD.e,H1)     2014.11.03 00:00:00   Debug mode: no
KF      0       17:53:51.485    Test1_Modes_EA (EURUSD.e,H1)     2014.11.03 00:00:00   Profile mode: no
CP      0       17:53:51.485    Test1_Modes_EA (EURUSD.e,H1)     2014.11.03 00:00:00   Tester mode: yes
HJ      0       17:53:51.485    Test1_Modes_EA (EURUSD.e,H1)     2014.11.03 00:00:00   Optimization mode: no
LK      0       17:53:51.485    Test1_Modes_EA (EURUSD.e,H1)     2014.11.03 00:00:00   Visual mode: yes
KS      0       17:53:51.485    Test1_Modes_EA (EURUSD.e,H1)     2014.11.03 00:00:00   Frame mode: no


在这里我们可以看到可视模式和标准测试模式是打开的。

如果选择了“策略测试仪设置”页下的可视化字段,则EA将在此模式下运行。

要在可视测试模式下运行mql5程序,可以通过mqlinfointeger()函数的mql_visual_模式标识符进行设置。

最后一种模式是时间帧控制模式。

HI      0       17:59:10.177    Test1_Modes_EA (EURUSD.e,H1)     2014.11.03 00:00:00   Current mode: MQL_MODE_FRAME
GR      0       17:59:10.177    Test1_Modes_EA (EURUSD.e,H1)     2014.11.03 00:00:00   Debug mode: no
JR      0       17:59:10.177    Test1_Modes_EA (EURUSD.e,H1)     2014.11.03 00:00:00   Profile mode: no
JG      0       17:59:10.177    Test1_Modes_EA (EURUSD.e,H1)     2014.11.03 00:00:00   Tester mode: yes
GM      0       17:59:10.177    Test1_Modes_EA (EURUSD.e,H1)     2014.11.03 00:00:00   Optimization mode: yes
HR      0       17:59:10.177    Test1_Modes_EA (EURUSD.e,H1)     2014.11.03 00:00:00   Visual mode: no
MI      0       17:59:10.177    Test1_Modes_EA (EURUSD.e,H1)     2014.11.03 00:00:00   Frame mode: no


有趣的是,函数只识别测试和优化模式,时间框架聚合模式标识为0。如果通过ontesterinit()句柄调用函数,则智能事务日志将包含以下内容:

IO      0       18:04:27.663    Test1_Modes_EA (EURUSD.e,H1)     Current mode: MQL_MODE_FRAME
GE      0       18:04:27.663    Test1_Modes_EA (EURUSD.e,H1)     Debug mode: no
ML      0       18:04:27.663    Test1_Modes_EA (EURUSD.e,H1)     Profile mode: no
CJ      0       18:04:27.663    Test1_Modes_EA (EURUSD.e,H1)     Tester mode: no
QR      0       18:04:27.663    Test1_Modes_EA (EURUSD.e,H1)     Optimization mode: no
PL      0       18:04:27.663    Test1_Modes_EA (EURUSD.e,H1)     Visual mode: no
GS      0       18:04:27.663    Test1_Modes_EA (EURUSD.e,H1)     Frame mode: yes


仅检测到时间框架凝聚模式。

如果未禁用“设置”页中的“优化”字段,策略测试仪将启动此模式。经验表明,此模式是在ontesterInit()、ontesterPass()和ontesterDeInit()函数中定义的。

mqlinfointeger()函数具有mql_frame_模式标识符,可以轻松定义EA以在时间帧聚合模式下进行测试。

下面是mqlmode()函数,它可以自动确定EA运行的模式。

//+------------------------------------------------------------------+
//| 确定当前MQL模式                                                    |
//+------------------------------------------------------------------+
ENUM_MQL_MODE MqlMode(void)
  {
   ENUM_MQL_MODE curr_mode=WRONG_VALUE;

//--- 如果是调试模式
   if(MQLInfoInteger(MQL_DEBUG))
      curr_mode=MQL_MODE_DEBUG;
//--- 如果是分析模式
   else if(MQLInfoInteger(MQL_PROFILER))
      curr_mode=MQL_MODE_PROFILER;
//--- 如果是可视化测试模式
   else if(MQLInfoInteger(MQL_VISUAL_MODE))
      curr_mode=MQL_MODE_VISUAL;
//--- 如果是优化模式
   else if(MQLInfoInteger(MQL_OPTIMIZATION))
      curr_mode=MQL_MODE_OPTIMIZATION;
//--- 如果是测试模式
   else if(MQLInfoInteger(MQL_TESTER))
      curr_mode=MQL_MODE_TESTER;
//--- 如果是时间框架聚集的优化结果模式
   else if(MQLInfoInteger(MQL_FRAME_MODE))
      curr_mode=MQL_MODE_FRAME;
//--- 如果是发布模式
   else
      curr_mode=MQL_MODE_RELEASE;
//---
   return curr_mode;
  }

由于对标准测试模式进行了优化和可视化,在定义了优化和可视化的测试模式之后,将检测到标准测试模式。

如果我们看看第二个模板eatest2_modes_ea.mq5中的函数是如何工作的,我们可以看到加载模板时会出现一行新的日志。例如,在分析模式中,有以下日志:

HG      0       11:23:52.992    Test2_Modes_EA (EURUSD.e,H1)    Current mode: MQL_MODE_PROFILER

让我们讨论MQL5EA模式的细节,以便创建一个特定于类的模型。我们将在本文的另一部分中实现它。

三。为不同的模式设计EA模板

我建议再次回顾EA开发步骤。

在算法阶段,程序员经常调试和分析代码。在历史数据重新测试阶段,他们将尝试所有策略测试人员模式。最终模式(发布模式)用于在线交易。

在我看来,EA必须包含多个模式,因为开发和测试阶段的需求必须反映在代码中。

这样,将维护主算法逻辑,并且EA在不同模式下的行为也会有所不同。面向对象编程工具非常适合实现这一思想。

图2.用于设计在不同模式下运行EA的类的层次结构

图3。在不同模式下运行EA的类的层次结构

图3显示了实现不同模式的类的层次结构。

基类cmodebase封装了所有公共对象,并具有两个子类:cmodelease和cmodetester。第一个是调试类的父类,第二个是EA用于历史数据返回测试的类。

在子模式的上下文中开发类方法时,让我们使用过程和模块组合来完成开发概念。作为一个例子,让我们考虑以下事务逻辑:

  1. 如果没有位置,根据信号打开位置。
  2. 如果有打开指令,根据信号关闭位置。
  3. 如果有未完成的订单,请打开滑动挡块。

当新列到达时,交易信号由标准指示器MACD发送。

购买信号出现在MACD的主线上,并在负区域从下到上遍历信号线(图4)。

图4 买入信号

图4。买入信号

卖出信号出现在MACD的主线上,在正区域从上到下横穿信号线(图5)。

图5 卖出信号

图5。销售信号

当出现反向信号或停止丢失时,关闭位置。

cmodeBase类定义如下:

//+------------------------------------------------------------------+
//| CModeBase 类                                                     |
//| 目的: MQL-模式基类                                                |            
//+------------------------------------------------------------------+
class CModeBase
  {
//--- === 数据成员 === --- 
private:
   //--- macd对象
   CiMACD            m_macd_obj;
   double            m_macd_main_vals[2];
   double            m_macd_sig_vals[2];

protected:
   long              m_pos_id;
   bool              m_is_new_bar;
   uint              m_trailing_stop;
   uint              m_trail_step;
   //--- 交易对象
   CSymbolInfo       m_symbol_info;
   CTrade            m_trade;
   CPositionInfo     m_pos_info;
   CDealInfo         m_deal_info;
   //--- mql 模式
   ENUM_MQL_MODE     m_mql_mode;

   //--- 新柱形对象
   CisNewBar         m_new_bar;
   //--- 当前tick标识
   bool              m_is_curr_tick_signal;
   //--- 平仓订单类型
   ENUM_ORDER_TYPE   m_close_ord_type;
   
//--- === 方法 === --- 
public:
   //--- 构造函数/析构函数
   void              CModeBase();
   void             ~CModeBase(void){};
   //--- 初始化
   virtual bool      Init(int _fast_ema,int slow_ema,int _sig,ENUM_APPLIED_PRICE _app_price);
   virtual void      Deinit(void){};

   //--- 模块
   virtual void      Main(void){};

   //--- 程序
   virtual void      Open(void){};
   virtual void      Close(void){};
   virtual void      Trail(void){};

   //--- 服务
   static ENUM_MQL_MODE CheckMqlMode(void);
   ENUM_MQL_MODE     GetMqlMode(void);
   void              SetMqlMode(const ENUM_MQL_MODE _mode);
   void              SetTrailing(const uint _trailing,const uint _trail_step);

protected:
   //--- 函数
   ENUM_ORDER_TYPE   CheckOpenSignal(const ENUM_ORDER_TYPE _open_sig);
   ENUM_ORDER_TYPE   CheckCloseSignal(const ENUM_ORDER_TYPE _close_sig);
   ENUM_ORDER_TYPE   CheckTrailSignal(const ENUM_ORDER_TYPE _trail_sig,double &_sl_pr);
   //---
   double            GetMacdVal(const int _idx,const bool _is_main=true);

private:
   //--- 宏
   bool              RefreshIndicatorData(void);
   //--- 标准化
   double            NormalPrice(double d);
   double            NormalDbl(double d,int n=-1);
   double            NormalSL(const ENUM_ORDER_TYPE _ord_type,double op,double pr,
                              uint SL,double stop);
   double            NormalTP(const ENUM_ORDER_TYPE _ord_type,double op,double pr,
                              uint _TP,double stop);
   double            NormalLot(const double _lot);
  };


您想在继承类中使用的任何东西都可以在基类中引入。

MACD度量数据不会被后续类使用,因为它们是私有变量。

需要注意的是,在这些方法中,缅因州的虚拟方法()、open()、close()和trail()。它们的实现取决于EA的当前操作模式。在基类中,这些方法的方法体将为空。

此外,对于所有MQL模式,基本类都包含相同的事务逻辑方法。包含所有信号方法:

  • cmodebase::checkopensignal(),
  • cmodebase::checkclosesignal(),
  • cmodebase::checktrailsignal()。

本文的目的不是为所有MQL模式类型提供代码。示例包括标准和可视测试模式。

3.1。测试模式

当算法代码完成并编译后,我通常使用策略测试仪来测试历史数据的性能。

通常需要检查系统对交易信号的执行是否准确。无论如何,EA在这个阶段的基本目标是能够正确地运行和交易。

一般测试的cmodeTester类实现如下:

//+------------------------------------------------------------------+
//| CModeTester 类                                                   |
//| 目的:用于测试模式的类                                              |            
//| 继承于CModeBase类                                                 |
//+------------------------------------------------------------------+
class CModeTester : public CModeBase
  {
//--- === 方法 === --- 
public:
   //--- 构造函数/析构函数
   void              CModeTester(void){};
   void             ~CModeTester(void){};

   //--- 模块
   virtual void      Main(void);

   //--- 程序
   virtual void      Open(void);
   virtual void      Close(void);
   virtual void      Trail(void);
  };


主要模块实现如下:

//+------------------------------------------------------------------+
//| 主模块                                                            |
//+------------------------------------------------------------------+
void CModeTester::Main(void)
  {
//--- 1) 平仓
   this.Close();
//--- 2) 开仓
   this.Open();
//--- 3) 滑动止损
   this.Trail();
  }


对于常规测试模式,事务信号生成的信息打印在日志中。

以字符串的形式打印出作为事务信号源的索引值。

以下是从日志中提取的打开信号和随后的关闭信号。

HE      0       13:34:04.118    Core 1  2014.11.14 22:15:00   ---=== Signal to open: SELL===---
FI      0       13:34:04.118    Core 1  2014.11.14 22:15:00   A bar before the last one, main: 0.002117; signal: 0.002109
DL      0       13:34:04.118    Core 1  2014.11.14 22:15:00   The last bar, main: 0.002001; signal: 0.002118
LO      0       13:34:04.118    Core 1  2014.11.14 22:15:00   market sell 0.03 EURUSD.e (1.25242 / 1.25251 / 1.25242)
KH      0       13:34:04.118    Core 1  2014.11.14 22:15:00   deal #660 sell 0.03 EURUSD.e at 1.25242 done (based on order #660)
GE      0       13:34:04.118    Core 1  2014.11.14 22:15:00   deal performed [#660 sell 0.03 EURUSD.e at 1.25242]
OD      0       13:34:04.118    Core 1  2014.11.14 22:15:00   order performed sell 0.03 at 1.25242 [#660 sell 0.03 EURUSD.e at 1.25242]
IK      0       13:34:04.118    Core 1  2014.11.14 22:15:00   CTrade::OrderSend: market sell 0.03 EURUSD.e [done at 1.25242]
IL      0       13:34:04.118    Core 1  2014.11.17 13:30:20   
CJ      0       13:34:04.118    Core 1  2014.11.17 13:30:20   ---=== Signal to close: SELL===---
GN      0       13:34:04.118    Core 1  2014.11.17 13:30:20   A bar before the last one, main: -0.001218; signal: -0.001148
QL      0       13:34:04.118    Core 1  2014.11.17 13:30:20   The last bar, main: -0.001123; signal: -0.001189
EP      0       13:34:04.118    Core 1  2014.11.17 13:30:20   market buy 0.03 EURUSD.e (1.25039 / 1.25047 / 1.25039)
FG      0       13:34:04.118    Core 1  2014.11.17 13:30:20   deal #661 buy 0.03 EURUSD.e at 1.25047 done (based on order #661)
OJ      0       13:34:04.118    Core 1  2014.11.17 13:30:20   deal performed [#661 buy 0.03 EURUSD.e at 1.25047]
PD      0       13:34:04.118    Core 1  2014.11.17 13:30:20   order performed buy 0.03 at 1.25047 [#661 buy 0.03 EURUSD.e at 1.25047]
HE      0       13:34:04.118    Core 1  2014.11.17 13:30:20   CTrade::OrderSend: market buy 0.03 EURUSD.e [done at 1.25047]

请注意,策略测试人员的日志不在智能交易选项卡中。所有信息都可以在日志选项卡上找到,其中包含测试和优化阶段策略测试人员的所有运行记录。

这就是为什么要搜索以查找要查看的字符串信息。如果您想将相关信息分开,可以将其记录在一个文件中。

标准测试策略在testmode_tester.mq5 ea中实现。

3.2。可视化测试模式

有时,如果你处理当前的市场,你希望通过实时图表观察EA。

可视化测试不仅可以观察交易系统对报价的反应,而且可以在测试结束时比较类似的价格模型。

用于可视测试的cmodeVisual类定义如下:

//+------------------------------------------------------------------+
//| CModeVisual类                                                    |
//| 目的:用于测试模式的类                                              |            
//| 继承于CModeBase                                                   |
//+------------------------------------------------------------------+
class CModeVisual : public CModeTester
  {
//--- === 数据成员 === --- 
private:
   CArrayObj         m_objects_arr;
   double            m_subwindow_max;
   double            m_subwindow_min;
   
//--- === 方法 === --- 
public:
   //--- 构造函数/析构函数
   void              CModeVisual(void);
   void             ~CModeVisual(void);

   //--- 程序
   virtual void      Open(void);
   virtual void      Close(void);

private:
   bool              CreateSignalLine(const bool _is_open_sig,const bool _is_new_bar=true);
   bool              CreateRectangle(const ENUM_ORDER_TYPE _signal);
   void              RefreshRectangles(void);
  };


此类包含私有成员。m_objects_arr类的成员具有carrayobj类型的动态数组。图形对象(如直线和矩形)属于此处。其他两个类(m_SubWindow_Max、m_SubWindow_Min)的成员控制索引窗口的最大化和最小化。

图形对象由私有方法控制。

此类不包含main()和trail()方法。它们的父函数cmodeTester::main()和cmodeTester::trail()将分别调用。

图形对象可以在可视测试模式下创建。它不能在策略测试人员的其他模式中实现。

当进入信号出现时,在图表上画红色垂直线;当退出信号出现时,画蓝色垂直线。在索引窗口中,入口点和出口点之间的区域用相应颜色的矩形填充。

如果不止一个,则矩形为浅蓝色。如果为空,则矩形为粉红色(图6)。

图6. 可视化测试模式下的图形对象

图6。视觉测试模式下的图形对象

矩形的高度取决于创建时图形子窗口的最大值和最小值。如果图形子窗口的大小发生更改,则需要添加代码来更改矩形坐标,以便所有矩形都可以设置为相同的大小。

因此,在MACD指示器子窗口中,我们有以下区域:未着色(无位置)、粉色(空列表)、浅蓝色(多个列表)。

传统测试模式在test mode_visual_tester.mq5 ea中实现。

总结

在本文中,我尝试介绍MetaTrader 5和MQL5创建不同模式程序的能力。必须指出的是,虽然创建多模式程序来编写事务算法会增加成本,但这也是逐步了解每个开发阶段的一个好机会。在这种情况下,面向对象编程对于开发人员来说是一个很好的助手。

优化和时间框架聚合模式将在随后的文章中介绍交易系统的统计特性。

本文由MetaQuotes Software Corp.翻译自俄语原文
,网址为https://www.mql5.com/ru/articles/1246。

附加文件下载zip cisnewbar.mqh(6.99 kb)modes.mqh(31.24 kb)test1_modes_ea.mq5(4.75 kb)t est2_modes_ea.mq5(5.04 kb)、testmode_tester.mq5(3.06 kb)、testmode_visual_tester.mq5(3.16 kb)

 

 


MyFxtop迈投(www.myfxtop.com)-靠谱的外汇跟单社区,免费跟随高手做交易!

 

免责声明:本文系转载自网络,如有侵犯,请联系我们立即删除,另:本文仅代表作者个人观点,与迈投财经(www.myfxtop.cn)无关。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。

著作权归作者所有。
商业转载请联系作者获得授权,非商业转载请注明出处。

風險提示

MyFxtops邁投所列信息僅供參考,不構成投資建議,也不代表任何形式的推薦或者誘導行為。MyFxtops邁投非外匯經紀商,不接觸妳的任何資金。 MYFXTOPS不保證客戶盈利,不承擔任何責任。從事外彙和差價合約等金融產品的槓桿交易具有高風險,損失有可能超過本金,請量力而行,入市前需充分了解潛在的風險。過去的交易成績並不代表以後的交易成績。依據各地區法律法規,MyFxtops邁投不向中國大陸、美國、加拿大、朝鮮居民提供服務。

邁投公眾號

聯繫我們

客服QQ:981617007
Email: service@myfxtop.com

MyFxtops 邁投