程序运行

每个脚本、服务和EA交易都运行在一个单独的线程中。在一个交易品种上计算的所有指标,即使它们附加在不同的图表上,也在同一线程中工作。因此,一个交易品种的所有指标共享一个线程的资源。

与交易品种相关的所有其他操作,例如处理订单号和历史记录同步,也会与指标一起始终在同样的线程中执行。这意味着如果一个指标执行一个无限操作,那么与其交易品种相关的所有其他事件将不会执行。

当运行EA交易时,请确保它有真实的交易环境 和能够访问 所需交易品种的历史记录和周期,并同步程序端和服务器之间的数据。对于所有这些程序,程序端提供了不高于5秒的启动延迟,在这之后,EA交易将和可用的数据一起启动。因此,如果没有连接服务器,这可能导致EA交易的启动延迟。

以下表格包含MQL5程序的简要概述:

程序

运行

注意

服务

一个单独的线程,服务的线程数量等于服务的数量

循环服务不能中断其他程序的运行

脚本

单独线程,脚本的线程数量等于脚本数

循环脚本不能破坏其他程序的运行

EA交易

单独线程,EA交易的线程数量等于EA交易的数量。

循环EA交易不能破坏其他程序的运行

指标

适用于一个交易品种上的所有指标的一个线程。线程的数量等于指标交易品种的数量

一个指标中的无限循环将停止该交易品种上的所有其他指标

程序附属于图表之后,上传客户端内存并进行全局变量初始化,如果分类中的某些全局变量有构造函数,在全局变量 初始化时调用构造函数。

在程序等待客户端事件之后,每个MQL5程序应该至少有一个事件处理器,否则就不会执行下载程序,事件处理程序有预定义名称,参量和返回类型。

类型

函数名称

参量

应用

注释

int

OnInit

EA交易和指标

初始化 事件处理器,允许使用缺省返回类型

void

OnDeinit

const int reason

EA交易和指标

无法初始化 事件处理器

void

OnStart

脚本和服务

Start(开始)处理程序

int

OnCalculate

const int rates_total,

const int prev_calculated,

const datetime &Time[],

const double &Open[],

const double &High[],

const double &Low[],

const double &Close[],

const long &TickVolume[],

const long &Volume[],

const int &Spread[]

指标

所有价格计算处理器

int

OnCalculate

const int rates_total,

const int prev_calculated,

const int begin,

const double &price[]

指标

计算 单个数据数组事件处理器

 

指标不能同时有两个事件处理器

 

只有一个事件处理器处理数据数组

void

OnTick

EA交易

新订单事件处理器,处理新接收的文件,该类型没有收到其他文件

 

void

OnTimer

EA交易和指标

定时器 事件处理器

void

OnTrade

EA交易

交易 事件处理器

double

OnTester

EA交易

测试 事件处理器

void

OnChartEvent

const int id,

const long &lparam,

const double &dparam,

const string &sparam

EA交易和指标

图表事件 事件处理器

void

OnBookEvent

const string &symbol_name

EA交易和指标

预定事件 事件处理器

客户端发送新事件给对应的打开图表。事件也可以通过图表(图表事件)或mql5-程序(自定义事件)生成。生成创建的事件或删除图表上的图形对象可以通过设置CHART_EVENT_OBJECT_CREATECHART_EVENT_OBJECT_DELETE图表属性来启用或禁用。每个MQL5程序和每个图表都有其自己的事件队列,在这里添加所有新入的事件。

程序仅接收来自它所运行的图表的事件。所有事件按照它们接收的顺序先后处理。如果队列已有NewTick事件,或者该事件当前正被处理,那么新NewTick事件不能置于MQL5程序队列。同样,如果ChartEvent 已经入列,或该事件正被处理,那么此类新事件也不会入列。timer事件以同样的方式处理 - 如果Timer 事件入列或被处理中,新的timer事件就不会入列。

事件队列拥有一个有上限但足够大的容量,这样就不会存在编写良好的程序超出队列大小。如果超出队列容量,新事件就会丢弃,不会入列。

强烈建议不要使用无限循环来处理事件。可能的例外就是处理单独的Start事件的脚本和服务。

程序库 不能处理任何事件。

 

指标和EA交易中禁止的函数

指标,脚本和EA交易是用MQL5编写的可执行程序。它们是专为不同类型的任务而设计的。因此,根据程序类型 ,在使用某个函数上会有一些限制。以下函数在指标中被禁止:

 

专为指标设计的所有函数在EA交易和脚本中也被禁止:

程序库不是一个独立的程序,在调用:脚本,指标或EA交易的MQL5程序的情况下被执行。相应地,上述的限制应用到了调用的程序库。

 

服务中禁止的函数

因为服务不绑定图表,进而不接受任何事件。服务中禁止以下函数:

ExpertRemove();

EventSetMillisecondTimer();

EventSetTimer();

EventKillTimer();

SetIndexBuffer();

IndicatorSetDouble();

IndicatorSetInteger();

IndicatorSetString();

PlotIndexSetDouble();

PlotIndexSetInteger();

PlotIndexSetString();

PlotIndexGetInteger();

 

函数库 不处理任何事件。

加载卸载指标

如下步骤装载指标:

  • 指标附属于图表 ;
  • 客户端开始(如果指标粘贴在图表之前,那是用来阻止客户端的);
  • 装载样本(在样本中,指标添加到图表指定位置);
  • 剖面转变(指标粘贴在其中一个剖面图里);
  • 图表中的交易品种或者时间表的转变,需要附加指标;
  • 改变程序端连接的账号;
  • 一个指标重新编译后,指标粘贴在一个图表上;
  • 改变指标的 输入参量

 

如下步骤卸载指标:

  • 从图表中分类指标;
  • 终端关机(指标附属在图表上);
  • 如果指标附加在图表上,下载一个模板;
  • 关闭一个图表,指标是附加的;
  • 改变一个剖面,改变指标附加的图表中的一个剖面;
  • 图表中交易品种或者时间表改变,指标附加;
  • 改变程序端连接的账号;

 

EA交易加载卸载

如下步骤下载EA交易:

  • 图表上添加EA交易;
  • 程序启动(EA交易添加到图表之前,关闭客户端);
  • 下载一个样本(在样本中添加到图表的EA交易是指定的);
  • 改变剖面(EA交易添加到图表中一项剖面图中);
  • 连接账户,即使账号相同(如果在服务器上授权程序端之前,EA交易被附加到图表)。
     

如下步骤卸载EA交易:

  • 从图表中分离EA交易;
  • 如果新的EA交易添加到图表中,另一个EA交易已经附加,EA交易就被卸载;
  • 关掉客户端(EA交易添加到图表中);
  • 装载模板,EA交易添加到图表中;
  • 关闭添加EA交易的图表;
  • 剖面转变,EA交易添加到图表中一个剖面图中;
  • 改变程序端连接的账号(如果在服务器上授权程序端之前,EA交易被附加到图表);

添加EA交易的图表中的交易品种和时间表改变了,EA加以就不能加载或者卸载。一旦客户端随后以新的交易品种/时间表调用在旧的交易品种/时间表的 OnDeinit()OnInit() 处理器,全局变量的值和 静态变量 不能重新设置。EA交易中接收的所有事件,在初始化之前就完整(OnInit() function)跳过。

 

脚本加载卸载

在添加到图表过后脚本就被迅速装载,在完成操作之后会迅速被卸载,OnInit() 和 OnDeinit() 用来调用脚本文件。

当程序卸载后(从图表中删除),全局变量的客户端程序不能初始化并删除队列中的事件,这样所有的字符类型常量都会重设,动态数组对象 的存储单元会分配析构函数 也会调用。

 

加载和卸载服务

如果服务在程序端关闭时启动,那么在启动程序端后立即加载这些服务。服务在完成工作后被立即卸载。

服务有一个OnStart()处理程序,在此程序中,您可以实现无休止的数据接收和处理循环,例如使用网络函数创建和更新自定义交易品种。

与EA交易、指标和脚本不同,服务并不绑定特定的图表,因此为其启动提供一个单独的机制。使用“添加服务”命令,在导航中创建一个新服务实例。可以使用对应的实例菜单启动、停止和移除服务实例。要管理所有实例,请使用服务菜单。

 

为了更好地理解EA交易的操作,我们推荐如下的EA交易编译代码,并执行装载/卸载,模板转变,样本转变,事件表转变等等:

示例:

//+------------------------------------------------------------------+
//|                                                   TestExpert.mq5 |
//|                        Copyright 2009, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "2009, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
 
class CTestClass
  {
public:  
   CTestClass() { Print("CTestClass constructor"); }
   ~CTestClass() { Print("CTestClass destructor"); }
  };
CTestClass global;
//+------------------------------------------------------------------+
//| 专家初始化函数                                                     |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   Print("Initialisation");
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| 专家无法初始化函数                                                  |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   Print("Deinitialisation with reason",reason);
  }
//+------------------------------------------------------------------+
//| 专家订单号函数                                                     |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
 
  }
//+------------------------------------------------------------------+

另见

客户端事件事件处理程序