本文中我们将讨论MQL5EA能够运行的编程模式。本文的目标是阐释“每种模式都以其自有的方式实现”的想法。作者相信此方法能够让EA不同阶段的开发工作更具效率。
首先,我们要考虑一个EA的开发由哪些阶段组成。然后,探讨MetaTrader 5中EA的运行模式及其辅助应用。最后,以实现上述想法的各层次类的实现结束本文。
开发一个自动交易系统(EA)是一件涉及多方面的工作。关键部分是算法的实现和测试。需要注意的是,EA的交易逻辑和算法代码都需严格测试。
实现步骤如下(图1)。
图1. 开发步骤及EA的实现
第五阶段的“算法交易”阶段需要开发者,程序员,分析师和其他专业人员的介入。只有当所有这些工作都由一个人完成时才可能实现。让我们假设这是一个程序化交易者。
这个方案能够得到更新和扩展。在我看来,这是在EA开发中最为重要的地方。这种循环模式能够让EA在整个开发周期中得到改进和修正。
在开发的每个阶段都需要特定的工具,知识和技能。
在我看来,开发者会遇到如下简单的变量矩阵(图2)。
图2. 变量矩阵
很清楚,只有以高的代码质量实现的盈利策略才能称之为第五阶段的“算法交易”。
MQL5环境下,EA能够运行于不同的模式。共有7种模式。下面我们逐一分析。
以程序文件类型来分,有大两类:
调试和分析模式属于第一类。
另一种区分模式的方法是看EA运行于真实数据上还是历史数据上。所有的测试模式都使用历史数据。
有6种模式由编程定义。可以根据结果来确定EA是否运行于标准(发布)模式。一个成型的可用于市场交易的EA程序(*.ex5后缀文件)应该在此模式下运行。同时,程序也允许在策略测试器中使用其他模式。
让我们来创建一个MQL程序的执行模式枚举值ENUM_MQL_MODE:
//+------------------------------------------------------------------+ //| 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。因此,函数确定这既不是调试模式(Debug mode:no),也不是分析模式(Profile mode:no)等等。由此我们得出结论,当前是在发布模式下运行。
现在我们来看看是如何确定调试模式的。
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_TESTER标识符来设置。
现在我们来看看优化模式。日志将保存在测试器的文件夹内。在我的情况下,保存目录为: %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_OPTIMIZATION 标识符调用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_MODE 标识符来设置。
最后一个模式是时间框架控制模式。
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_MODE标识符,能够方便的定义EA在时间框架聚集模式下进行测试。
下面是能够自动确定EA在何种模式下运行的函数MqlMode()。
//+------------------------------------------------------------------+ //| 确定当前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
我们讨论一下MQL5 EA模式的细节,以便创建特定类的模型。我们将在本文的另一部分实现之。
我建议再来审视一遍EA的开发步骤。
在算法阶段,程序开发者经常要调试和分析代码。在历史数据回测阶段,他们会尝试所有的策略测试器模式。最终模式(发布模式)用于在线交易。
在我看来,EA必须是包含多种模式的,因为开发和测试阶段的需求必须反映在代码中。
这样主要的算法逻辑将被保持,EA在不同的模式下也将会有不同的表现。面向对象的编程工具非常合适实现这个想法。
图 3. 用于设计在不同模式下运行EA的类的层次结构
图3表示实现不同模式的类的层次结构。
基础类CModeBase封装了所有常用对象,它有2个子类:CModeRelease和CModeTester 类。第一个是调试类的父类,第二个是用于EA进行历史数据回测的类。
在分模式的背景下开发类方法时,让我们用过程和模块化组合来完成开发构想。作为例子,让我们考虑下面的交易逻辑:
当新的柱形到来时,交易信号由标准指标MACD发出。
买入信号出现在MACD的主线在负值区域从下往上穿越信号线(图4)。
图4. 买入信号
卖出信号出现在MACD的主线在正值区域从上往下穿越信号线(图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指标数据将不能被后续类使用,因为他们是私有变量。
必须注意到在这些方法中的 Main(), Open(), Close(), Trail()虚拟方法。他们的实现取决于EA当前的运行模式。在基类中这些方法的方法体将为空。
此外,基本类包括了对所有MQL模式相同的交易逻辑方法。包含所有的信号方法:
本文的目的不是为了提供所有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. 可视化测试模式下的图形对象
矩形的高度取决于其创建时图表子窗口的最大和最小值。如果图表子窗口的大小改变,那么需要添加改变矩形坐标的代码,以便将所有矩形设置为一样的尺寸。
因此在MACD指标子窗口我们有如下区域:未标颜色的(没有持仓),粉色的(空单),浅蓝色(多单)。
常规测试模式在TestMode_visual_tester.mq5 EA中实现。
在本文中我试图介绍MetaTrader 5和MQL5语言创建不同模式程序的能力。不得不提的是,虽然创建多模式程序编写交易算法会增加开销,但也是一次逐步了解每一个开发阶段的良机。在这种情况下面向对象的编程是开发者的好帮手。
优化和时间框架聚集模式将在后续关于交易系统的统计特性的文章中介绍。
本社区仅针对特定人员开放
查看需注册登录并通过风险意识测评
5秒后跳转登录页面...
移动端课程