发表时间:2022-03-26来源:网络
本系列的文章主要针对的是完全不懂编程,但想要在最短的时间内花费最少的精力尽快了解 MQL4 语言的交易者。如果您看到“面向对象”或“三维数组”这类词语就觉得头痛,那么这篇文章正是您需要的良方。这些课程的设计旨在最快出成果。内容也通俗易懂。我们在理论方面不会有太深的研究,但从第一课起就已能获得实际的收益了。
如果您之前从未做过编程工作,第一次阅读某些案例时,您会发现很难懂其中的意思。慢慢再看一遍文本,仔细思考每个句子。您终会豁然开朗,因为这实际上真的不难。在理解之前的信息后,方可进行下一步。研究代码示例。根据您学到的内容编写自己的代码示例。
让我们先来看一下可以用这种语言做什么。它主要用于创建脚本、自定义指标、EA 和库:
本文中我们将学习编写通用脚本。为此我们使用了一个特殊的程序 - MetaEditor 4。要启动它,在打开的自定义终端上按 F4 键。要新建一个脚本,单击 MetaEditor 4 菜单中的“文件”->“新建”按钮,用用“Ctrl+N”按钮:

在显示的窗口中,选择要创建的项目。选择“脚本”,然后单击“下一步”:

在下一个窗口中,在名称字段中名称字段中键入脚本名称。在作者字段中添加您的姓名并在链接字段中键入脚本名称。然后单击确定:

之后会看到一个新窗口,这是您将使用的最重要的工具。它显示原始文本:

请注意,即便是一个空白的、不可运行的脚本也包含着一个代码。现在万事俱备,开始编程。但很遗憾,接下来该怎么做,您一点头绪都没有。让我们试着改变这种状况。
您应该了解一件重要的事情。在 MetaEditor 中编写的是源代码。即,它是一个命令序列,而终端将一个个往下执行这些命令。但终端无法执行源代码。源代码对您来说是可以理解的,但 MetaTrader 理解不了。要终端可以理解源代码,应将源代码“翻译”成合适的“语言”。要进行“翻译”,在 MetaEditor 中按下F5键。之后,源代码将被编译成一个运行文件。编译是一种将您编写并可理解的源代码“翻译”成 MetaTrader 可理解并可执行的特殊文件的过程。自己试一试。新建一个名为“Test1”的脚本,但不要编译。使用“浏览器”打开终端,进入“脚本”文件夹。您会看到并没有名为“Test1”的脚本:

现在编译此脚本(F5 键):

再次进行终端。“Test1”脚本出现了。

在终端浏览器中双击该脚本名称,该脚本将打开。但什么都不会发生,因为脚本是空的。
现在您应该已经了解编写脚本的流程是什么样的了:编写源代码,编译脚本,在终端中打开脚本,查看结果,更改特定代码,编译,查看...就这么循环,直到得到想要的结果。
您应该已经看到,空脚本包含一个特定代码。但应该将源代码写到哪里?什么源代码有用?应该将源代码写在int start(){行与 return(0);}行之间,如图中所示:

在这里编写我会提供给您的所有东西,这些都会起到作用。稍后我们将详细说明这些行的意义。
什么是变量?试着自己找到答案,我会提供一些帮助。您现在几岁?五年后您几岁?看,您的年龄就是个变量。您的年龄随着时间在变化,就像任何其他变量那样。也就是说,变量的第一个特性是它会随着时间而发生变化。另一个示例:您五岁时多高?很可能比现在矮得多。身高又是一个变量示例。但有一个很重要的区别点。注意,年龄是用整数来算的。身高一般要算到小数位(“浮点数”)。年龄:20 岁,30 岁。身高:1.8米,1.9米。这是个非常重要的特点:每个变量都属于特定的类型。我们来看看还有哪些其他类型的变量。您可以用数字来描述很多参数,但怎么描述文本呢?特殊字符串类型就用于这个用途。此类变量类型仅包含行。现在我们来看看如何用 MQL4 语言创建和描述变量。示例:
int age = 25;这里我们看到一个整型变量 (int - integer)。Int 是 MQL4 语言里的一个关键字,即我们使用一个整数类型。然后我们写入“年龄”- 这是变量的名称,即此变量中存储的用于表达意义的词。之后我们使用符号“=”将值 25 分配给此变量。每条指令之后都应有一个“;”。注意,任何变量的声明和初始化都遵循以下形式:
[ 变量类型] [ 变量名称] = [ 变量值];
此外,不必将值分配给变量(初始化),你可以这么写:
int age;再举一个例子:
double height = 1.95;这里我们声明一个名为“身高”的变量,此变量存储 double 类型值(浮点数、小数),并用“=”运算符分配值 1.95。
现在我们来看看字符串变量:
string name = "Janet";字符串是一种变量类型,名称是一个变量名称,“Janet”是一个变量值。注意,字符串类型变量的值要放在双引号(“”)中间。
还有一种非常有用的变量类型 - 布尔型。这种变量仅可接受两个值:true 或 false。示例:
bool trend = false;现在您应该记住一些简单的东西。MQL4 语言是一种区分大小写的语言,即用编写代码时用大写还是小写字母有很大的区别。例如,如果您声明几个变量时使用相同的名称但不同的大小写,那将得到完全不同的变量:
double HIGHTPRICE; double hightprice; double HightPrice; double hightPrice;上述代码将创建四个完全不同的变量。还请注意,MQL4 语言的所有关键字都是小写的。
下一个示例:
DOUBLE hightPrice1; Double hightPrice2;上述代码无法正常工作,因为“double”将不会被接受为 MQL4 语言的一个关键字。还有个更重要的注意事项,变量名称不能用数字或特殊符号(*、&、%、$)开头。例如:
double 1price; double %price;注释也是一个语言元素。如果在一行开头写入“//”,那么整行都是注释。这意味着编译期间,这行将被忽略。例如:
// this is a comment现在您可以看到,一个空脚本代码包括对一个资料性字符的很多注释。注释您的代码。有时它会帮助您节省大量时间。
现在我们来看看在声明这些变量后该对它们做什么。来一个简单的例子:
double a = 50.0;// declare a value with a floating point and // assign the value 50 to it double b = 2.0; double c; c = a + b; // assign to the variable c sum of variables // a and b. Now the value is equal to 52. Like after // any other instruction put a semicolon (“;”) c = a - b; // diminution, c = 48 c = a*b; // multiplication, c = 100 c = a / b; // division, c = 25 c = (a + b)*a; // place the operations that should be performed // first inside the brackets. In our case // first we get the sum of a and b // after that this sum will be multiplied by a and assigned to c c = (a + b) / (a - b); // if there are several operations in brackets, // they will be performed c = a + b*3.0; // according to mathematic rules first you will get // multiplication b and 3, and then the sum如果需要用某个变量执行一项运算,并分配一个结果给它,例如加 5,可以采用以下方式之一:
int a = 5; a = a + 5; // add 5 a += 5; // analogous a = a*5; a *= 5; // multiply a by 5 and assign to it a /= 5; // divide and assign如要加 1 或减 1,用以下方法:
int a = 5; a++; // add1, it is called increment а--; // subtract 1, it is decrement这都可以,但用这种脚本的话,您无法确定这一切是否能正常运行,因为屏幕上没有任何反应。
这就是显示结果会很方便的原因。为此,我们需要使用一个集成函数 MessageBox()。
一个函数就是一套指令,它接受参数,并根据参数显示结果。在我们的示例中,MessageBox() 函数接受两个参数:第一个是消息文本,第二个是标题文本。示例如下:
MessageBox("Hello, World! There is some text.","caption");要执行一个函数,首先写入其名称。别忘了区分大小写!然后在括号中写入参数,用逗号隔开。我们示例中的参数是字符串类型的参数。正如我们记得的那样,所有行都用引号(“”)括起来的。在任何指令的末尾加一个分号。为了正确理解,我们来看图。它显示了代码和结果之间的关联。

当然,一切正常。但我们如何展示其他类型的变量呢?很简单 - 牢记在心里:
int a = 50; int b = 100; MessageBox("It is very simple. a+b=" + (a + b), "a+b=?")得到的结果是:

如您所料,MQL4 就是这么设计的,当我们尝试向某行中添加其他数字类型时,它会自动将数字传递到行中并合并它们。这真是一个美妙的特性!您也可以对字符串变量进行这种运算:
int a = 50; int b = 100; string str1 = "a + b ="; str1 += a + b; // now str1 = "a + b = 150" // now use the variable str1 as // a first parameter MessageBox(str1, "a + b = ?");现在您知道如何使用 MessageBox() 函数提取不同的数据了。但是,能够显示简单的数学运算结果又算什么?我们对 MQL4 的要求可不仅仅是算个加法和乘法,不是吗?
别怕。这很简单。看一看。假设您要记住五个价格。我们该怎么做?好吧,我们这么做:
double price1 = 1.2341; double price2 = 1.2321; double price3 = 1.2361; double price4 = 1.2411; double price5 = 1.2301;我们得到五个变量,它们只有一个数据类型,且描述同一个参数 - 价格。我们可以换种方法,用一个数组。一个数组就是一组变量,指数不同,但名称相同。从五个元素声明一个数组,方式如下:
double price[5];
常用形式:
(数组类型)(数组名称) [元素数量];
在我们的示例中:数组类型 - double(双类型),名称 - price(价格),元素数量 - 5。我们来看如何引用这些数组元素:
double price[5]; // declare an array of 5 elements price[0] = 1.2341; // refer to the first element of the array and // assign a price to it. Note // that the index of the first element starts with 0 // It is an important feature, // you should get used to it. price[1] = 1.2321; // refer to the second element price[2] = 1.2361; // and so on price[3] = 1.2411; price[4] = 1.2301;就像常用变量一样,我们可以对数组元素执行任何运算。实际上,数组的元素就是常用变量。
double price[2]; price[0] = 1.2234; price[1] = 1.2421; MessageBox("Middle price is " + (price[0] + price[1]) / 2.0,"middle price");声明一个数组时,可以向所有元素分配初始值。
double price[2] = {1.2234, 1.2421};我们简单地列举元素的初始值(在大括号中用逗号隔开)。在这种情况下,您可让编译器自动放上元素的数量,而不是您手动写入。
double price[] = {1.2234, 1.2421};毫无疑问这些都是可以的,不过,遗憾的是,这根本没什么用处。我们总得弄到一点实际的数据吧!例如,当前价格、时间、可用金额等。
没有实际的数据,我们当然什么都做不了。要获得实际数据,我们只需参考对应的内置数组。以下是几个内置数组:
High[0]; // refer to the last maximal price, // that the bar has achieved in the current timeframe // and current currency pair. Currency pair and // the timeframe depend on the chart, on which you // have started a script. It is very important to remember! Low[0]; // minimal price of the last bar // in the current chart. Volume[0]; // value of the last bar in the current chart.要正确理解内置数组和指数,看看这个:

最后一根条柱的指数(编号)为 0,旁边一根为 1,以此类推。
还有内置常用变量。例如,Bars 显示当前图表中的条柱数量。它是个常用变量,但它早就已经声明了,并非在您的脚本中进行的声明。此变量像其他内置数组和变量一样始终存在。
假设您决定要计算图表中所有条柱的最大价格的平均值。为此,您将各个元素轮流添加到一个变量,如下所示:
double AveragePrice = 0.0; AveragePrice += High[0]; AveragePrice += High[1]; AveragePrice += High[2]; AveragePrice += High[3]; AveragePrice += High[4]; // ... and so on AveragePrice /= Bars;我只能告诉您一点:这种方法可行,但有些可笑。循环专门适用此类用途。注意,所有运算都是完全类似的,只有指数从 0 更改为变量 Bars-1 值。确定计数器并用其引用数组元素某种程度上来说就已经非常方便了。我们可以用循环来解决这个任务:
double AveragePrice = 0.0; for(int a = 0; a < Bars; a++) { AveragePrice += High[a]; }我们看看各行:
double AveragePrice = 0.0; // everything is clear // this is a cycle. or(int a = 0; a < Bars; a++)循环用关键字 for 开头。(还有其他类型的循环,例如while,但我们现在不讨论它们)。然后在引号中指明用分号隔开的计数器、循环计算条件、计数器增加运算。通常它以以下方式呈现:
for(declaration of a counter; the cycle operation conditions; counter changes) { // the source code, that will be repeated is in braces, }让我们更近距离地了解循环声明的各个阶段。
计数声明int 类型用于此计数器。变量计数器的名称无关紧要。您应初始化主值,例如初始化为 0。
计数器计算条件:这很简单。在此处确定一个条件,如果它为 true,循环继续进行。否则,循环终止。例如在我们的示例中:
a < Bars很明显,当变量计数器小于变量 Bars 时,循环将继续进行。假设变量 Bars=10,则在循环上每移动一次,变量增加 1,直至达到 10。之后,循环将停止。
计数器更改:如果我们不更改计数器(在我们的示例中是增加它),将发生什么情况?循环将永不停止,因为条件永不会满足。为了更好地理解循环的意义,我编写了一段可执行循环的代码,并提供了注释:
// the cycle: // double AveragePrice=0.0; // // for(int a=0;a> // { // AveragePrice+=High[a]; // } // // will be performed in this way: // double AveragePrice=0.0; int a=0; AveragePrice+=High[a]; a++; // now a=1, suppose Bars=3. // then the cycle goes on, because Bars > a AveragePrice+=High[a]; a++; // a=2 AveragePrice+=High[a]; а++; // a=3 // the conditions is not fulfilled any more, so the cycle // stops, because a=3 and Bars=3现在您应该了解循环的工作方式了。但还应该再了解一些细节。
循环计算条件各有不同。如下例中所示:
a>10 // the cycle works while a>10 a!=10 // the cycle works while a is not equal to 10 a==20 // while a is not equal to 20 a>=2 // while a is more or equal to 2 a 10 ) { b = 1; } else { b = 2; } MessageBox("b=" + b,".");这一切都很简单。完成后,b 的值是多少?当然 b=2,因为条件 a > 10 并未满足。这很简单。另外也不必使用其他关键字:
int a = 10; int b = 0; if(a > 10) { b = 1; }在这种情况下,如果某个条件未满足,遵循大括号中该条件的代码块将被忽略。在我们的示例中是在满足 b = 0 之后。同时还要注意条件的构建方式。我们知道,不同类型的变量会获得不同的值,例如:
int - 整数(1、60、772);double - 浮点数(1.0021、0.221);string - 仅行(“字”、“一些文本”);bool - 仅 true 或 false(true、false)。因此,得出的结论是:在条件中比较仅带可接受值的变量,例如:
int Integer=10; double Double=1.0; string String="JustWord"; bool Bool=true; if(Integer
2022-03-26
2022-03-26
2022-03-26
2022-03-26
2022-03-26
2022-03-26
2022-03-26
2022-03-26
2022-02-15
2022-02-14