终端和程序运行模式

MetaTrader 5 环境为交易与编程交互时涉及的各种任务提供了解决方案,这种交互需要涉及终端本身和特定程序的若干种运行模式。

使用 MQL5 API,你可以区分正常在线活动与回测活动,区分源代码调试(以识别潜在错误)与性能分析(查找代码瓶颈),以及区分终端的本地副本和云副本 (MetaTrader VPS)。

这些模式以标志描述,每个标志包含一个布尔值:truefalse

标识符

说明

MQL_DEBUG

程序正在以调试模式运行

MQL_PROFILER

程序正在以概要分析模式运行

MQL_TESTER

程序在测试程序中运行

MQL_FORWARD

程序在前向测试过程中执行

MQL_OPTIMIZATION

程序正在优化过程中运行

MQL_VISUAL_MODE

程序正在可视化测试模式下运行

MQL_FRAME_MODE

EA 交易在图表上以收集优化结果帧的模式执行

TERMINAL_VPS

终端在虚拟服务器 MetaTrader Virtual Hosting (MetaTrader VPS) 上运行

MQL_FORWARD、MQL_OPTIMIZATION 以及 MQL_VISUAL_MODE 标志表明已经设置了 MQL_TESTER 标志。

某些成对标志组合相互排斥,即这些标志不能同时启用。

尤其是 MQL_FRAME_MODE 与 MQL_TESTER 相互排斥。MQL_OPTIMIZATION 排斥 MQL_VISUAL_MODE,而 MQL_PROFILER 排斥 MQL_DEBUG。

我们将学习与测试相关的所有标志(MQL_TESTER、MQL_VISUAL_MODE)(在专门探讨 EA 交易 以及部分涉及 指标的章节中)。与 EA 交易优化相关的所有内容(MQL_OPTIMIZATION、MQL_FORWARD、MQL_FRAME_MODE)将在 单独章节中讨论。

现在我们使用调试 (MQL_DEBUG) 和分析 (MQL_PROFILER) 模式来熟悉标志读取原理。同时,我们回顾如何从 MetaEditor 激活这些模式(有关详细信息,参见文档中的 调试概要分析章节)。

我们将使用 EnvMode.mq5 脚本。

void OnStart()
{
   PRTF(MQLInfoInteger(MQL_TESTER));
   PRTF(MQLInfoInteger(MQL_DEBUG));
   PRTF(MQLInfoInteger(MQL_PROFILER));
   PRTF(MQLInfoInteger(MQL_VISUAL_MODE));
   PRTF(MQLInfoInteger(MQL_OPTIMIZATION));
   PRTF(MQLInfoInteger(MQL_FORWARD));
   PRTF(MQLInfoInteger(MQL_FRAME_MODE));
}

在运行程序之前,你应检查调试/分析设置。为此,在 MetaEditor 中运行命令Tools -> Options并检查Debugging/Profiling选项卡中的字段值。如果启用了选项Use specified settings,则将影响程序启动所在金融工具图表和时间范围的,是相关字段的值。如果禁用了该选项,则将使用Market Watch中的第一个金融工具和 H1 时间范围。

在此阶段,选择哪个选项并不重要。

准备就绪后,使用命令Debug -> Start on Real Data (F5) 运行脚本。由于该脚本仅将请求的特性打印到日志(并且其中我们不需要断点),其执行将瞬时完成。如果需要分步调试,我们可以在源代码中的任何语句上放置一个断点 (F9),脚本执行将在该处冻结我们需要的任何时长,从而能够研究 MetaEditor 中所有变量的内容,并且可以在算法中逐行移动 (F10)。

在 MetaTrader 5 日志中(“Expert”选项卡),我们将看到以下内容:

MQLInfoInteger(MQL_TESTER)=0 / ok
MQLInfoInteger(MQL_DEBUG)=1 / ok
MQLInfoInteger(MQL_PROFILER)=0 / ok
MQLInfoInteger(MQL_VISUAL_MODE)=0 / ok
MQLInfoInteger(MQL_OPTIMIZATION)=0 / ok
MQLInfoInteger(MQL_FORWARD)=0 / ok
MQLInfoInteger(MQL_FRAME_MODE)=0 / ok

所有模式的标志均被重置,MQL_DEBUG 除外。

现在我们在 MetaTrader 5 中从Navigator运行相同脚本(只需用鼠标将其拖到任何图表)。我们将得到几乎相同的一系列标志,但这次 MQL_DEBUG 将等于 0(因为程序以正常方式执行,而不是以调试器模式执行)。

请注意,以调试模式启动的程序之前,会先进行特殊模式的重新编译,在此其间,会将允许进行调试的服务信息添加到可执行文件。该二进制文件比一般的要更大更慢。因此,调试完成后,在用于真实交易、传输给客户或上传到市场之前,应使用File -> Compile命令 (F7) 重新编译该程序。
 
编译方法不直接影响 MQL_DEBUG 特性。我们可以看到,该程序的调试版本可以在没有调试器的终端中启动,在此情况下,MQL_DEBUG 将被重置。两个内置宏可用于确定编译方法:_DEBUG 和 _RELEASE(参见 预定义常量章节)。它们是常量而不是函数,因为该属性是在编译时被“固定”在程序中的,因此无法更改(不同于运行时环境)。

现在我们在 MetaEditor 中执行命令Debug -> Start Profiling on Real Data。当然,分析这样一个简单脚本没有特定意义,但是我们现在的任务是确保正确标志在环境特性中打开。实际上,现在 MQL_PROFILER 的值为 1。

MQLInfoInteger(MQL_TESTER)=0 / ok
MQLInfoInteger(MQL_DEBUG)=0 / ok
MQLInfoInteger(MQL_PROFILER)=1 / ok
...

带分析的程序启动也是首先以另一种特殊模式重新编译,在此期间,向二进制文件中添加测量指令执行速度所需的其他服务信息。在分析了分析器报告并修复了瓶颈之后,你应以常规方式重新编译程序。

原则上,调试和分析既可在线执行,也能在测试程序 (MQL_TESTER) 中基于历史数据执行,但测试程序仅支持 EA 交易和指标。因此,无法在脚本示例中看到设置的 MQL_TESTER 或 MQL_VISUAL_MODE 标志。

我们知道,MetaTrader 5 支持以快速模式(没有图表)和可视化模式(在单独图表上)测试交易程序。在第二种情况下才会启用 MQL_VISUAL_MODE 特性。有必要进行检查,尤其是在没有可视化的情况下,可禁用对 图形对象 的操作。

要使用历史数据以可视化模式调试,必须首先在 MetaEditor 设置对话框中启用Use visual mode for debugging on history选项。分析程序(指标)始终在可视化模式下测试。

记住,在线调试对于交易性 EA 交易并不安全。