Tag标签
  • 传统
  • 图文
  • 卡片
全部文章

MT4编程低级手册

绒毛玩具

  一、MT4自定义指标存储在C:\Program Files\MetaTrader 4\experts\indicators这个目录中

  该目录中主要存储二种类型的文件,一种是后缀为mq4文件,这是MT4自定义指标的源码文件,是一种高级语言源文件,可以人工编写修改,机器不能直接执行,但能在MT4把它编译为ex4可执行文件;另一种就是ex4文件,这是MT4自定义指标的可执行文件,即系统调用需要的文件,由mq4文件编译得到。

  mq4文件必须编译为ex4文件才能被MT4执行,但ex4文件是机器码文件,人工不能被修改,只能通过修改mq4文件后重新编译来修改。

  另外要说的是,还有一个文件是mqlcache.dat,它用来保存目录中的文件信息,如果MT4无法自动编译,只要删除此文件即可解决问题,这是解决此类问题的一个小窍门,大家应当记住。

  2、用MQL编辑器打开mq4文件,点一下“编译”按钮,即可生成相应的ex4文件。

  在论坛上我们经常看到有mq4源文件或ex4文件可供下载,我们只要把它们保存到C:\Program Files\MetaTrader 4\experts\indicators这个目录中,也就是下面这个目录中,就可以了。如果下载的是ex4文件,那就可以直接调用,但你不知道作者是如何编写的;如果是mq4文件的线,让系统自动编译生成ex4可执行文件,这种情况可以看到源代码,就可以知道作者是如何编写的。如果下载的是rar、zip等类型的压缩文件,还必须下载后将压缩文件中的mq4或ex4的文件解压到此目录才能使用。

  在论坛上,我们也可以经常看到一些指标的源码贴在网页上,但没有mq4、ex4等的文件可以下载,这种情况下只需要复制源码,自己粘帖过去就可以了。此时需要我们自己动手将源码保存为源码文件之后再编译,那也没关系,非常地简单,多点几下鼠标就搞定,别忘记给这个指标起个名字。

  2、在MQL编辑器中新建一个文件,文件名一定要输,别的随便操作都没关系。

  4、之后我们就可以将网页上源码复制粘贴到这里面来,试着点一下“编写”,如果左下角出现“0错误,0警告”,那说明源码没有问题,编译通过了,成功生成了ex4可执行文件,但网上很多代码可能会存在一定的错误,无法形成ex4文件,这主要是由于编写环境的因素,所以在此一部可能需要反复调试和修改错误的语句。

  可以打开一个原已存在的mq4文件,然后将其以别的文件名另存,再删除文件中的所有内容成一个空文件,把网页上的源贴到文件中保存即可。

  也可以打开Windows自带的记事本,把网页上的源码贴进去,然后取个文件名保存到上面提到的目录,不过文件后缀必须设定为mq4,保存类型选择“所有文件”(这些方法大同小异,大家充分发挥自己的聪明才智吧)。

  分隔符,表示一个语句内部间隔,不结束语句,通常用于变量与变量之间,参数之间。

  表示把符号后的值加到符号前的变量中。例如“i+=2;”,实际进行的运算就是“i=i+2;”的简写,表示i的值加2。

  逻辑判断符,等于号。用于逻辑判断,双等号两边值相等,则返回布尔值“真-true”;双等号两边值不相等,则返回布尔值“假-false”。

  逻辑判断符,不等于号。用于逻辑判断,不等号两边值不相等,则返回布尔值“真-true”;不等号两边值相等,则返回布尔值“假-false”。

  一、自定义变量在使用前,必须先声明(定义),向系统声明变量的类型和名称。

  创建时可同时进行赋值(赋默认值),也可以不赋值。MQ语法中自定义变量的名称可以使用中文字符。

  4、布尔型(bool):其值分别为“true、false”,即“线线假)。

  类型定义词仅在创建和声明变量时时候使用,后面使用再变量时,如进行运算时,就不能再加这些类型定义词了。

  附加变量就是在程序完善后投入使用时,变量值允许用户自由更改的变量,一般用作程序参数。

  一般指标,例如MACD(12,26,9)参数输入就是通过附加变量实现的,(12,26,9)分别为三个附加变量值。

  创建一个整型附加变量,变量名为“时间框架”,默认值为9,允许用户在程序外部修改参数值,或进行参数优化。

  大家可以将自定义函数与数学函数在本质上看作是是一致的,在程序中需要用到的地方直接以函数名来调用。

  例如:数学函数fuc(x,y)=5x+6y (x,y为正整数) 写成程序语句就是:

  一、同自定义变量一样,自定义函数在付诸使用前,也必须先声明设立,应定义其返回值类型、名称、参数和函数体(运算处理语句)。

  函数返回值类型、名称、参数位于的函数头部(参数间以逗号分隔),大括号中的是运算语句或者处理语句,也就是函数体部分。

  return语句为函数结束语句,return后面的括号中的值为函数返回值,即函数运算处理结果。

  在上面例子中,double为函数类型,表示该函数的返回值(运算结果)是小数;

  x,y为参数,由于自定义变量使用之前都必须先声明,否则函数不知道参数的类型,所以要加上类型定义关键词double;

  fa为函数名,有了函数名,我们就可以在需要使用的地方用fa(2,1)的格式来调用此函数;

  此函数也可以简写为:double fa(double x,double y)

  包括整型(int)、双精度浮点型(double)、字符串型(string)、布尔型(bool)等,还有一种函数是以函数运行或进行一定的处理为目的,运行结束后不需要返回值也没有返回值的,则函数类型可以在声明中写成void(无值型)。

  三、函数中如果需要定义自定义变量,那么此变量作用域仅在本函数内部,函数运行结束时,这个自定义变量也就自动注销了。

  上例中,有x、y、temp三个自定义变量,在函数运行时被声明创建,在函数运行结束的时侯自动消失,仅在函数内部有效,与函数外部无关,外部不可使用这些变量,需要注意的是外部可以使用与内部同名的变量但不影响内部的变量,不过为了程序的清晰性,不建议大家这么做。

  函数调用非常便捷,只要函数名正确,参数个数一致,类型相同就能够正确的调用。

  如我们前面创建了一个fa(x,y)函数,在程序的别处我们可以用ft(4,5)等样式来调用fa(x,y)函数运算求值。

  调用时,传递参数值给fa(x,y)函数(按次序把4传给x,把5传给y),返回结果22后继续向下执行主程序。

  一、数组是一组同类型变量的集合,可以以一个名称同时存储多个数值,由索引来调用,在实现我们EA的算法时是一个非常重要的工具。

  这是一个数组名为arrai、包含了5个元素的整数型数组(即数组长度length为5),可以同时存储5个数据。

  数组中第一个元素的索引编号为0,第二个为1,以此类推。编号使用方括号跟在数组的后面;

  在这上例中arrai[0]的值为5、aa[1]的值为4、aa[2]的值为3、aa[3]的值为2、aa[4]的值为1。

  数组的赋值必须指定明确的将要赋值对象的索引,除新建数组时可以批量赋值以外,数组元素必须一个一个地赋值。

  这个是对数组cc的第2个元素cc[1]([0]是第1个,[1]表示第2个)重新赋值为5。

  数组的引用必须指定明确的引用对象索引值,一次只能引用一个。如果需要使用整列数组,则必须逐个使用。在程序中经常使用循环与数组相互配合来完成相应的功能。

  开盘价、最高价、最低价、收盘价、成交量等市场历史数据,每根K线实体都各自有一个,所以必须使用数组来调用,MT4有几个预定义数组,预定义的意思就是这些数据都是被准备好了的,EA的开发者可以直接使用:

  预定义数组:开盘价Open[]、最高价High[]、最低价Low[]、收盘价close[]、成交量Volume[]、K线所属时间Time[]

  这里有一个引用顺序或位置的问题,从右边起第一根K线实体(即最新的K线,第二根K线,第三根K线,以此类推,也就是说从右向左倒着数过去,最近的数值小,而越远的数值越大。

  Open[0]、High[0]、Low[0]、Close[0],表示最新的开盘价、最高价、最低价、收盘价;

  Open[1]、High[1]、Low[1]、close[1],表示第2根K线蜡烛的开盘价、最高价、最低价、收盘价(也就是昨天);

  Open[2]、High[2]、Low[2]、close[2],表示第3根K线蜡烛的开盘价、最高价、最低价、收盘价;

  Open[3]、High[3]、Low[3]、close[3],表示第4根K线蜡烛的开盘价、最高价、最低价、收盘价;

  Open、High、Low、close,表示第i+1根K线蜡烛的开盘价、最高价、最低价、收盘价

  买入价、卖出价是行情数据,MT4用预定义变量Ask和Bid表示,数值类型为double双精度浮点类型。

  Digits 表示当前货币对的小数位数,类型为int整数型,无日元币对为4(位),有日元币对为2(位),黄金石油等一般也为2(位);

  Point 表示当前货币对的点值(相当于最小变动价位),类型为双精度浮点double型,无日元币对为0.0001,有日元币对为0.01。与Digits正好相反。

  成交量:iVolume(symbol,timeframe,shift)

  K线分钟图(PERIOD_M1)、5分钟图(PERIOD_M5)、15分钟图(PERIOD_M15)、30分钟图(PERIOD_M30)、1小时图(PERIOD_H1)、4小时图(PERIOD_H4)、日线)、周线)、周线)、月线)。

  iMA(symbol, timeframe, period, ma_shift, ma_method, applied_price, shift)

  参数共7个,分别为:商品名称、K线时间框架、均线周期、均线偏移、平均模式、价格种类、位置;

  平均模式:简单移动平均(MODE_SMA)、指数移动平均(MODE_EMA)、平滑移动平均线(MODE_SMMA)、线性加权移动平均线(MODE_LWMA);

  价格种类:收盘价(PRICE_CLOSE)、开盘价(PRICE_OPEN)、最高价(PRICE_HIGH)、最低价(PRICE_LOW)、中值(PRICE_MEDIAN)、5(PRICE_TYPICAL)、6(PRICE_WEIGHTED)。

  例1:iMA(EURUSD,PERIOD_M1,20,0,MODE_SMA,PRICE_CLOSE,0)

  表示:欧元对美元1分钟图上,以收盘价计算的,20分钟简单移动平均线,最新K线所对应位置的值;

  例2:iMA(NULL,0,10,0,MODE_LWMA,PRICE_CLOSE,5)

  表示:在当前商品、当前K线周期图表上,以收盘价计算的,10(天)线根K线(Bar)所对应位置的值。

  其他如MACD指标、威廉指标、RSI、SAR、布林线等常用指标取值都与移动平均线指标相类似。

  iMAOnArray(数组名, 总数, 平均周期, 均线偏移, 平均模式, 位置)

  这也与iMA函数差不多,不过数据源变为数组,也就是原来写货币对的地方改为数组名。

  我们经常根据需要自己编一些自定义指标,可用iCustom函数来取得自定义函数的值。

  iCustom(商品名 ,K线周期 ,自定义指标名称 ,自定义指标参数1 ,参数2 ,参数3…… ,自定义指标线编号 ,位置)

  表示:求当前图表中,自定义指标mykdj(9,3,3)的第3条指标线在当前位置的值。

  规则:如果小括号中的条件成立则执行大括号中的语句;如果不成立则跳过大括号,执行后面的语句。

  if( Low[1]1.0000 && Low[0]=1.0000 && flag!=1){

  if( High[1]1.0000 && High[0]=1.0000 && flag!=2)

  当上穿报警后,flag的值就变为1;当下穿报警后,flag的值就改为2;

  当flag=1时,说明已经上穿报过警了,不能再上穿报警,但仍可下穿报警;

  当flag=2时,说明已经下穿报过警了,不能再下穿报警,但仍可上穿报警。

  规则:如果小括号中的条件成立则执行if下大括号中的第一部分语句;如果不成立则执行else下大括号中的第二部分语句。

  1、只有语句后面才用到语句结束符“;” 条件、大、小括号后面都不用语句结束符“;”。

  2、语句用大括号括起来(大括号的作用为界定语句块),但如果只有一行语句,则大括号可以省略:

  一幅K线图有几千上万条K线(Bar,根据设定的样本数),每根K线Bar又各有开收盘价、收盘价、最高低价等数值,而且还有很多移动平均线、MACD、RSI等技术指标数值。

  面对大量的数据,我们经常采用循环来实现数据的取值和赋值。下面我们简单来介绍一下MT4中主要用到的循环语句。

  规则:当小括号中的判断条件成立时,就执行大括号中的语句,执行完毕后再判断条件是否成立,如果条件成立就再继续执行大括号中的语句。

  只要条件成立,程序就不停地执行大括号中的语句(循环体),直到小括号中的条件不再成立时结束循环,while循环又叫做“当循环”,意思为当XX条件时执行循环。

  它与if语句的区别是:if语句是当条件为真时只运行一次;而while语句则是只要条件为真,循环体语句就不断地运行,直到条件为假时结束循环。所以为了避免造成死循环,循环体内应当对判断的条件进行修改,如进行数值的累加等。

  iMA(NULL,0,fast,0,MODE_EMA,PRICE_CLOSE,i)

  -iMA(NULL,0slow,0,MODE_EMA,PRICE_CLOSE,i);

  这里,循环执行条件是i1000,循环体中有两条语句,一句是把两条均线的差值赋给数组buffer,另一句“i++;”,我们知道“++”是自增运算符,那么每运行一次,i的值在原有基础上增加1。这样,随着循环的不断地运行,i的值逐渐增加,循环到1000次后,i的值也就从0变为了1000,此时“i1000”就不再成立,循环结束。这样,数组buffered[ ]中也就存储了1000个值。

  for循环与while循环在原理上可以认为是一致的,只是书写格式上有所区别,一般for循环多用在已知循环次数的循环上面,而while循环用在未知循环次数的循环上面(也即循环的次数可能根据运行的结果动态的改变)。

  iMA(NULL,0,fast,0,MODE_EMA,PRICE_CLOSE,i)

  -iMA(NULL,0,slow,0,MODE_EMA,PRICE_CLOSE,i);

  “int i=0;”语句从“while(i1000)”循环体上方移到循环条件里面、“i1000”的前面;

  “i++;”语句从循环体中移到了循环条件里面、“i1000”的后面。

  (此语句用来定义初始循环变量,在循环中仅执行一次,可以为没有任何表达式的空操作符“;”)

  第四步、执行小括号中的第1句:i++ (此语句即:每循环一次,i的值自增1)

  再补充一点:同if语句一样,如果循环体中(大括号中)只有一行语句,大括号可以省略,其他的操作符也是如此。

  2、#property indicator_separate_window

  显示3根指标线、#property indicator_color1 Red

  全局性的参数、变量、数组在此定义,局部变量可在start()函数中定义。

  初始化函数的功能是“设置”。如果自定义指标需要划线,则必然用到此函数。

  当数据有变动时,start()就被触发。数据变动一次,start()就运行一次。

  start()函数的作用主要是取值和给指标线赋值,报警也在此函数内发起。

  deinit()在自定义卸载时运行一次,可用以去除指标加载时init()所做的初始化操作。

  我们现在以一个简单的实例来给大家讲述如何进行EA的开发。要画指标线,只要在程序中写明以下几点就可以了:

  第三、要建立指标线与数组的对应关系(函数关系,运算关系),哪个数组中的数据对应哪条指标线。

  第三、四、五条写在init()初始化函数中(init函数仅在指标加载时运行一次);

  第六条写在start()函数中(start函数在数据发动变动时运行,变动一次刷新运行一次);

  下面我们以MACD为例来说明,我们知道,MACD指标由二条曲线(快线和慢线)和一组红绿柱线组成。(下图一)

  我们从简单入手,先去除紫线和红绿柱线,仅保留其中的那根白线,来看白线是怎样画出来的。

  #property indicator_separate_window

  ==============================================

  ==============================================

  #property indicator_separate_window

  初始化函数。该函数进在指标加载时只运行一次。init是系统默认的函数名,但使用时仍需要进行创设,所以要加定义符int;

  指标触发函数。与init函数相区别,该函数在有行情数据变化时被触发,如果数据被不断更新,则该函数则将被不断执行。start也是系统默认的函数名,但在使用我们时也仍然需要进行创设,所以也要加定义符int。

  IndicatorCounted()函数调用的是缓存中的柱数,就是已经计算过的有值的柱数。

  这样limit的值就是未经计算的柱数,这样就可以起到优化程序的作用了。

  报警功能是MT4的一个特色功能。它可以在预定的条件达到时,给用户发出警报。见图:

  与指标画线相比,报警语句则显得相对简单,只要在判断语句中加一个报警的指令语句即可。

  如果您的邮箱开通了手机短信通知,则邮件报警的内容则会即时转发到手机上面。

  文件类型为wav格式,并且需要保存在C:\Program Files\MetaTrader4\sounds目录中。

  iHigh(0,0,0) = iMA(0,0,警戒均线,MODE_SMA,PRICE_CLOSE,0)

  iMA(0,0,警戒均线,MODE_SMA,PRICE_CLOSE,1)

  iLow(0,0,0) = iMA(0,0,警戒均线,MODE_SMA,PRICE_CLOSE,0)

  iMA(0,0,警戒均线,MODE_SMA,PRICE_CLOSE,1)

  mark的初始值是0,当上穿报警时给mark赋值1,当下穿报警时给mark赋值2。这样当mark的值为1时,说明已经对上穿报过警了,就不能再次对上穿报警;当mark的值为2时,说明已经对下穿报过警了,就不能再次对下穿报警。这样就起到了避免重复报警的作用。

上一篇:

下一篇:

本站文章于2019-10-26 06:09,互联网采集,如有侵权请发邮件联系我们,我们在第一时间删除。 转载请注明:MT4编程低级手册 绒毛玩具