四(一)程序运行

每个脚本或EA都是在各自独立的线程中运行。所有指标在图形接口线程中工作。在图形接口线程中也进行了滴答数的处理和历史同步。自定义指标在主接口线程中工作。如果使用iCustom()函数调用了自定义指标,则该指标在调用它的程序的线程中工作。库(导入)函数也在调用程序线程中工作。
在运行EAr时,请确保它所在实际的交易环境能够访问所需符号和周期的历史,并在终端和服务器之间同步数据。对于所有这些过程,终端提供不超过5秒的启动延迟,之后EA将使用可用数据启动。因此,如果与服务器没有连接,这可能会导致EA启动延迟。

下表包含MQL4程序的简要总结:
(程序 运行 注意事项)
脚本
一个单独的线程,脚本的线程数量等于脚本的数量
循环脚本不能中断其他程序的运行
EA
一个单独的线程,EA的线程数量等于EA的数量
循环的EA不能中断其他程序的运行
指标
所有指标共享终端图形接口线程的资源
一个指标的无限循环将会停止终端的工作

在将程序附加到图表后,程序被上传到客户端内存中,全局变量也被初始化。如果类类型的某个全局变量有构造函数,那么在初始化全局变量时将调用该构造函数。
之后,程序将等待来自客户机终端的事件。每个mql4程序应该至少有一个事件处理程序,否则将不会执行加载的程序。事件处理程序具有预定义的名称、参数和返回类型。

(类型 /函数名 /参数 /应用程序 /说明)
int OnInit() 用于EA,指标和脚本的初始化事件处理程序。
无参数
/它允许使用void返回类型。

void OnDeinit()函数 用于EA,指标和脚本
const int的原因 /
Deinit 事件处理器

void OnStart()函数
无参数
用于脚本/ 开始事件处理器

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[]
/ 指标处理和价格

void/ OnTick() 用于EA
无参数
新的Tick事件处理程序。当正在处理新标记接收的事件时,没有收到其他此类事件。

void OnTimer() 用于EA和指标
无参数
计时器事件处理程序

double OnTester() 用于EA
无参数
测试发生器

void OnChartEvent() 用于EA和指标
参数有:
const int id,
const long &lparam,
const double &dparam,
const string &sparam
图表事件发生器

客户端向相应的开放图表发送新事件。事件也可以由图表(图表事件)或mql4程序(自定义事件)生成。通过设置CHART_EVENT_OBJECT_CREATE 和CHART_EVENT_OBJECT_DELETE图表属性,可以启用或禁用在图表上创建或删除图形对象的事件的生成。每个MQL4程序和每个图表都有自己的事件队列,其中添加了所有新传入的事件。
程序只从运行它的图表中接收事件。所有事件都按照接收到的顺序依次处理。如果队列已经有一个NewTick事件,或者这个事件正在被处理,那么新的NewTick事件不会被放在MQL4程序的队列中。类似地,如果ChartEvent已经加入队列,或者正在处理此事件,则不会加入此类新事件。计时器事件的处理方式是相同的——如果计时器事件在队列中或正在处理中,那么新计时器事件不会加入队列。
事件队列有一个有限但足够大的大小,因此对于编写良好的程序来说,队列溢出是不可能的。在队列溢出的情况下,在不排队的情况下丢弃新事件。
不建议使用无限循环来处理事件。此规则的例外可能只有仅处理单个启动事件的脚本。
库不处理任何事件。

指标、脚本和EA是用MQL4编写的可执行程序。它们是为不同类型的任务而设计的。因此,对于某些函数的使用有一些限制,这取决于程序的类型。

在指标中禁止具备以下功能:
OrderSend();
SendFTP();
Sleep();
ExpertRemove();
MessageBox().

EA和脚本中禁止为指标设计的所有功能:
SetIndexBuffer();
IndicatorSetDouble();
IndicatorSetInteger();
IndicatorSetString().

库不是一个独立的程序,它是在MQL4程序上下文中执行的,MQL4程序称为:脚本、指示器或专家顾问。因此,上述限制适用于被调用的库。

指标装卸
在以下情况下加载指标:
指标附在图表上;
终端启动(如果指标在终端关闭前附在图表上);
加载模板(如果模板中指定了附图的指标;
更改概要文件(如该指标附于其中一个概要文件图表);
更改图表的符号及/或时间表,该指标及/或时间表已附于图表上;
在成功地重新编译指标后(如果指标附加到图表上);
指标输入参数的变化。

在下列情况下卸载指标:
从图表中分离指标时;
终端关机(如果指标附有图表);
加载模板(如果指标附加到图表上);
附有指标的图表的结束;
更改概要文件(如指标附于已更改概要文件的图表之一);
更改图表的指标及/或时间表,该指标及/或时间表已附于图表上;
指标输入参数的变化。

在以下情况下加载EA:
将EA附加到图表时;
终端启动(如果EA在终端关闭前附在图表上);
加载模板(如果模板中指定了附在图表上的EA);
更改配置文件(如果将EA附加到配置文件图表之一);
连接到帐户,即使帐户编号相同(如果EA在服务器上的终端授权之前附加到图表中)。

EA在以下情况下被卸载:
将EA从图表中删除时;
如果一个新的EA被附加到一个图表上,如果另一个EA已经被附加,这个EA将被卸载。
终端关闭(如果EA附在图表上);
加载模板(如果将EA附加到图表中);
图表的结尾,EA附在图表上。
个人资料的更改(如EA附于已更改个人资料的图表之一);
更改连接终端的帐户(如果在服务器上的终端授权之前将EA附加到图表上);
调用ExpertRemove()函数。

如果一个图表的指标或时框附加了EA,则不会加载或卸载EA。在这种情况下,客户机终端随后在旧的指标/时框上调用OnDeinit()处理程序,在新符号/时框上调用OnInit()(如果是这样的话),全局变量和静态变量的值不会被重置。所有在初始化完成之前接收到的事件(OnInit()函数)都被跳过。
为了更好地了解EA操作,我们建议编译以下EA的代码,并执行加载/卸载、模板更改、符号更改、时框更改等操作:

加载和卸载脚本
脚本附加到图表后立即加载,完成操作后立即卸载。
当程序被卸载(从图表中删除)时,客户端终端执行全局变量的反初始化并删除事件队列。在这种情况下,反初始化意味着所有字符串类型变量的重置、动态数组对象的重新分配以及调用它们的析构函数(如果它们是可用的)

输入参数和源代码编译
如果在图表上启动的程序的源代码被成功地重新编译,它的前一个版本将从图表中删除,新的编译副本将被执行。
如果重新编译后输入参数集没有更改,则应用先前指定的参数值。否则,使用默认值。
在以下情况下,在编辑源代码时考虑要更改mql4程序输入参数集:
改变了参数的数量;
改变了参数的顺序;
参数名称已更改;
一个或多个参数的类型已经更改。

更改任何参数的默认值不被认为是输入参数集的更改。
输入参数集清楚地标识了终端执行系统中的程序。如果此集合不变,则认为可执行文件的新版本保留了程序的整个逻辑和功能。
如果输入参数集发生了更改,终端将认为新的可执行文件与之前在图表上启动的程序不兼容。因此,启动新的重新编译程序时,输入参数集具有默认值。
在其他情况下(包括更改任何参数的默认值时),在重新编译之后应用先前指定的参数。
在任何编译之后都会调用OnInit()预定义函数。它的目的是正确初始化程序的所有全局变量和静态变量。在OnInit()事件处理程序中应该正确使用程序的输入参数值。

你可能感兴趣的:(四(一)程序运行)