简介本系列的文章主要针对的是完全不懂编程,但想要在最短的时间内花费最少的精力尽快了解 MQL4 语言的交易者。如果您看到“面向对象”或“三维数组”这类词语就觉得头痛,那么这篇文章正是您需要的良方。这些课程的设计旨在最快出成果。内容也通俗易懂。我们在理论方面不会有太深的研究,但从第一课起就已能获得实际的收益了。 建议如果您之前从未做过编程工作,第一次阅读某些案例时,您会发现很难懂其中的意思。慢慢再看一遍文本,仔细思考每个句子。您终会豁然开朗,因为这实际上真的不难。在理解之前的信息后,方可进行下一步。研究代码示例。根据您学到的内容编写自己的代码示例。 首先要了解 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 itdouble 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 cc = (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() 函数接受两个参数:第一个是消息文本,第二个是标题文本。示例如下: 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 parameterMessageBox(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 elementsprice[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,以此类推。 循环假设您决定要计算图表中所有条柱的最大价格的平均值。为此,您将各个元素轮流添加到一个变量,如下所示: double AveragePrice = 0.0; AveragePrice += High[0]; AveragePrice += High[1]; AveragePrice += High[2]; AveragePrice += High[3]; AveragePrice += High[4]; // ... and so onAveragePrice /= 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=2AveragePrice+=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>10a!=10 // the cycle works while a is not equal to 10a==20 // while a is not equal to 20a>=2 // while a is more or equal to 2a<=30 // while a is less or equal to 30 计数器可用不同的方式进行更改。例如,您不必每次都加 1。您可以这么做: a-- // the counter will each time decrease by 1 a += 2 // the counter will each time increase by 2 此外,您可将计数器更改放到循环主体内。如下例中所示: for(int a=0; a<Bars;) { AveragePrice+=High[a]; a++; // the counter changes inside the cycle body } > 也不必在循环中声明变量计数器。您可以换一种方式: int a = 0; for(;a < Bars;) { AveragePrice += High[a]; a++; // the counter changes inside the cycle body } 如果循环主体仅包含一个操作符,如下所示: for(int a = 0; a < Bars; a++) { AveragePrice += High[a]; } 然后也不必使用发括号: for(int a = 0; a < Bars; a++) AveragePrice += High[a]; 这就是目前为止有关循环的所有内容了。还有其他的循环类型,我们会在下一课中讨论。现在您应该知道何时使用循环并记住语法。尝试编写几个循环,以通过 MessageBox() 函数显示计数器值。尝试编写一个非连续循环,看看启动后会发生什么。 条件还有一个您始终会用到的重要项目 - 条件。我们的生活充满着大量的条件以及根据这些条件进行的活动。我们往往采用的是条件式的思考方式。例如:“如果我有充足的时间,我会读这本书。如果没有,还是读本杂志吧”。您可以生成数以百计的此类条件和行动。但我们如何用 MQL4 来编写它们呢?示例如下: // of course the conditionsn should be written in MQL4if( I have enough time ) { // here we place any actions, directions in MQL4 will read this book; }// if the first condition is not fulfilled, // the second is fulfilledelse { read a magazine; // code } 现在您应可理解这种条件式语法了。我们看看用 MQL4 语言完整编写的条件: int a = 10;int b = 0; if(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 Integer=10;double Double=1.0;string String="JustWord";bool Bool=true; if(Integer<10) // the condition is correct{ MessageBox("It works!","Really!"); } if(Double!=1.0) // the condition is correct{ MessageBox("works!","Simple!"); } if(String==10) // this is nonsense!! // we found the variable //String with string type, but 10 is int{ MessageBox("Wrong type","u can't c this"); } if(String!="Word") // ok{{ // ...} if(Bool==true) // correct{ // ...} 注意,我们使用条件运算符(==, !=, >, <, >=, <=).对于字符串类型和布尔类型,仅使用 == 和 != 进行比较。 现在我们来了解一下其中内容的含义。是的,您可以在循环中使用条件,也可以在条件中使用循环;您可以在条件中使用其他条件,等等。例如: int a=0;double b=0.0;bool e; if(a==0) { for(int c=0;c<Bars;c++) { b+=High[c]; } if(b>500.0) { e=true; } else { e=false; } } 下例显示的是条件的另一种使用方式: int a=0;int result; if(a==0) { result=1; }else if(a==1) { result=2; }else if(a==2) { result=3; }else{ result=4; } 如果某个条件默认有另一个条件,在关键字“else”后编写该条件,具体参考上述编码。这也是可行的。其他条件的数量不受限制。如果用于满足条件的行动符合一项运算,您可忽略循环中的大括号。 if(a==1) { b=2; } // or this way:if(a==1) b=2; 复杂条件通常一个条件是不够的。您需要比较很多参数;这时就需要使用复杂条件。例如,如果我有足够的时间和耐心,我会好好学习 MQL4 语言。我们可以将它编写成代码: if((enough time) && (enough oatience))
{
I will learn MQL4 language;
} 这意味着您首先应将复杂条件细分为简单条件,将它们放到括号中,并在它们之间加上 &&(逻辑 AND)或 ||(逻辑 OR)。如果两个条件都为真,添加 && (AND)。如果只有一个条件为真,添加 || (OR)。示例如下: nt a=10;int b=20; if((a>5) && (b<50)) MessageBox("Its works!","Yes"); 除此以外,您可根据需要任意添加和组合条件: int a=10;int b=20; if ( ((a>5) || (a<15)) && ( b==20)) MessageBox("It works, too!","Yes"); 混合使用要在循环中同时使用复杂条件和简单条件,您可能要编写一段非常复杂的代码。几乎所有机制都可以用 MQL4 语言的这些浅显结构来表示。如果理解了这些简单代码的编写和操作原理,您也就弄懂了一半的 MQL4 或任何其他编程语言!这其实是非常简单的!您所需要的只是多练习。试着尽可能多地编写脚本,以记住语法和获取实践经验。此外,查看附件 examples.mq4 中的示例,尝试理解它们。 其他内置变量和数组您已了解了 High[]、Low[]、Volume[] 等数组以及 Bars 这个变量。以下是一些其他的有用变量: double Open[] // the array of prices of the current // chart opening barsdouble Close[] // the array of prices of the current // chart closing bars double Bid // the last known buying price in // the current currency pairdouble Ask // the last known selling price in // the current currency pair 总结您已经学了不少东西。也许现在您脑子里乱糟糟一团。重读本文,加深记忆,进行练习,尝试理解含义。我敢保证,不用多久一切都将会豁然开朗。本文介绍了整个 MQL4 语言的基础知识。对文中内容理解地越深,后续的学习就越轻松。再多说一句 - 后续的学习为何为简单得多?因为本文的内容就已经是最难的部分了。下一篇文章中,我们将学习 MQL4 语言的各个不同特点,并了解其他一些集成函数,这些函数将为编程带来更多的可能性。 |
|
来自: 昵称62517906 > 《MT4》