外汇返佣网

您当前的位置:第一外汇返佣网 > 外汇学习 > 外汇百科 >

外汇百科

MT4编程入门

时间: 2023-06-12 13:49 文章来源: 外汇返佣网 点击次数:

  MT4编程入门1:MT4自定义指标的保存目录、指标编缉

  一、文件菜单中选择“打开数据文件夹”,然后进入MQL4\Indicators 子目录,MT4自定义指标即保存在此目录中。

  该目录中主要有二种类型的文件,

  一种是mq4文件,这是MT4自定义指标的源码文件,是一种高级语言文件,可以人工编写修改,机器不能直接执行,但能在MT4启动时自动编译为ex4可执行文件。

  另一种就是ex4文件,这是MT4自定义指标的可执行文件,由mq4文件编译得到。

  mq4文件必须编译为ex4文件才能被MT4执行。

  但ex4文件是机器码文件,人工不可修改

  另外还有一个文件是mqlcache.dat,它用来保存目录中的文件信息,如果MT4无法自动编译,只要删除此文件即可解决问题

  mq4文件编译为ex4可执行文件有两种方法:

  1、MT4启动时,会自动把此目录中的mq4文件编译为ex4文件。

  2、用MQ语言编辑器打开mq4文件,点一下“编写”按钮,即可生成ex4文件

  二、下载保存mq4文件、ex4文件

  在论坛上我们经常看到有mq4文件、ex4文件可供下载,我们只要把它们保存到环境变量\MQL4\Indicators 这个目录,也就是下面这个目录中,就可以了。如果下载的是ex4文件,那可以直接调用;如果是mq4文件,则需要重启动MT4,让系统自动编译生成ex4可执行文件。如果下载的是rar、zip等类型的压缩文件,还必须下载后解压到此目录才能使用。

  

  

  三、将源码保存为源码文件

  在论坛上,我们也经常能看到指标源码贴在网页上,但没有mq4、ex4等文件可以下载,只能复制源码。此时需要我们自己动手将源码保存为源码文件,那也没关系,非常地简单,多点几下鼠标就搞定。

  1、打开MQ语言编辑器

  

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

  

  3、删除新文件里面的所有内容,成为一个空文件,

  

  4、接着我们就可以将网页上源码复制粘贴进来

  试着点一下“编写”,如果左下角出现“0错误,0警告”,那说明源码没问题,编译通过了,成功生成了ex4可执行文件

  

  

  5、还有很重要的一点,就是要把源码文件保存到正确的目录中。

  保存后,再点一下编写。

  到此,源码保存完成。

  当然,我们也还有另的办法:

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

  也可以在记事本中新建一个文件,把网页上的源码贴进记事本,然后取个文件名保存到上面提到的目录,不过文件后缀必须输入mq4,保存类型选择“所以文件”
 

  四、MT4程序调用自定义指标

  这非常简单

  MT4编程入门2:自定义变量

  一、自定义变量在使用前,必须先创建(定义),设定变量的类型和名称。

  创建时可同时赋值,也可以不赋值。名称可以使用中文字符。

  例:

  int mark; 创建一个整型变量,变量名为“mark”。

  bool 是否报警=true; 创建一个逻辑型变量,变量名为“是否报警”,同时,赋初值“true”

  二、类型和类型定义词

  自定义变量的基本类型有:

  1、整形(int):就是整数,包括负整数

  2、双精度小数(double):可以简单地理解为带小数位的数

  3、字符串型(string)。

  4、逻辑型(bool):其值分别为“true、false”,即“真、假”,也可以写成“1、0”(1真,0假)。

  类型定义词仅在创建变量时使用,后面使用变量时,就不能再加类型定义词了

  三、附加变量

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

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

  定义附加变量只需在变量定义语句前加“extern”

  例:

  extern int 周期=9; 创建一个整型附加变量,变量名为“周期”,默认值为9,允许用户在程序外部修改参数值

  MT4编程入门3:自定义函数

  自定义函数与数学函数在本质上是一致的

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

  int ft(int x,int y)

   {

   int temp;

   temp=3*x+2*y;

   return(temp);

   }

  一、和自定义变量一样,自定义函数在使用前,也必须先设立,以定义其类型、名称、参数和运算语句。

  函数类型、名称、参数位于函数头部(参数间以逗号分隔),

  大括号中的是运算语句,也就是函数体部分。

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

  上例中,int为函数类型,表示该函数的返回值(运算结果)是整数;

  (x,y)为参数,由于自定义变量使用之前都必须先创建,所以要加上类型定义词int

  ft为函数名,有了函数名,我们就可以在别处用ft(2,1)的形式来调用此函数;

  函数体部分有三句:

  第一句,定义一个整形变量temp

  第二句,计算temp的值

  第三句,函数结束,返回调用点,以temp的值作为本函数返回值。

  此函数也可以简写为:int ft(int x,int y) {return(3*x+2*y);}

  二、函数类型与类型符

  函数类型就是函数返回值(运算结果)的类型,与自定义变量类型差不多

  有整型(int)、双精度型(double)、字符串型(string)、逻辑型(bool)等,

  还有一种函数是以函数运行为目的,运行结束后不需要返回值也没有返回值的,则函数类型可以写成void(无值型)

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

  上例中,有x、y、temp三个自定义变量,在函数运行时创建,在函数运行结束时自动消失,仅在函数内部有效,与函数外部无关。

  四、函数的调用

  函数调用非常简单,只要函数名正确、参数个数一致、类型相同就能正确调用

  如我们前面创建了ft(x,y)函数,则别处我们可以用ft(4,5)等样式来调用ft(x,y)函数求值。

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

  MT4编程入门4:自定义数组

  一、数组是一系列同类型变量的集合,可以同时存储多个数值。

  例:int aa[4]={4,3,2,1};

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

  二、自定义数组也必须“先建立,后使用”

  创建(定义)时,必须设定类型和名称。

  创建(定义)时,数组的元素个数也可以设定,也可以不设定

  数组中第一个元素的编号为0,第二个为1,以此类推。编号使用方括号括起来

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

  创建(定义)数组的同时,可以赋初值,也可以不赋初值。

  例:

  int bb[]; 创建数组bb,不设定数组元素个数

  int cc[8]; 创建数组cc,设定数组元素为8个,不赋初值

  int dd[3]={9,8,7}; 创建数组dd,设定数组元素为4个,并赋初值

  赋值后,dd[0]的值为9、dd[1]的值为8、dd[2]的值为7

  int ee[9]={0,1,2,3}; 创建数组ee,设定数组元素为9个,但只给前4个元素赋初值

  三、数组使用时的赋值

  数组的赋值必须指定明确的赋值对象,除了新建数组时可以批量赋值外,数组元素必须一个一个赋值

  例如:dd[2]=1;

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

  在这里,没有整数型变量定义符int,

  这样,数组dd原有三个值{9,8,7}就变为{9,8,1}

  四、数组的引用

  数组只是一系列变量的集合,所以每次只能使用数组中的一个元素。

  数组的引用必须指定明确的引用对象,一次只能引用一个。如果需要使用整列数组,则必须逐个使用。

  例如:数组aa[4]的值为{4,3,2,1}

  我们用aa[i]来引用数组aa中的值

  当i=0时,aa[i]的值为4

  当i=1时,aa[i]的值为3

  当i=2时,aa[i]的值为2

  当i=3时,aa[i]的值为1

  这样,我们在处理数列的时候,使用数组就能带来极大的方便

  MT4编程入门5:市场数据取值

  一、预定义数组(MT4已经定义好的,可以直接使用)

  开盘价、最高价、最低价、收盘价、成交量等历史数据,每根K线蜡烛都各有一个,所以必须用数组来解决问题,MT4有几个预定义数组:

  开盘价Open[]、最高价High[]、最低价Low[]、收盘价close[]、成交量Volume[]、所属时间Time[]

  类型为双精度double型(即精确小数)

  这里有一个位置的问题,右边第一根K线蜡烛(即最新的蜡烛)的编号为0,第二根蜡烛编号1,第三根蜡烛编号2,也就是说从右向左倒着数过去。

  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[i]、High[i]、Low[i]、close[i],表示第i+1根K线蜡烛的开盘价、最高价、最低价、收盘价

  以此类推。。。。。。

  注意:这些是数组,用的是方括号。

  二、预定义变量

  买入价、卖出价是实时价格,MT4用预定义变量Ask和Bid表示,数值类型为double双精度

  还有一些预定义变量,如:

  Bars 表示图表中的蜡烛数,类型为int整数型

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

  Point 表示当前货币对的点值,类型为双精度double型,无日元币对为0.0001,有日元币对为0.01。与Digits正好相反。

  三、指标函数

  1、价格、成交量、时间

  它们都有三个参数:货币对名、K线周期、位置序号

  开盘价:iOpen(symbol,timeframe,shift) 双精度double型

  收盘价:iClose(symbol,timeframe,shift) 双精度double型

  最高价:iHigh(symbol,timeframe,shift) 双精度double型

  最低价:iLow(symbol,timeframe,shift) 双精度double型

  成交量:iVolume(symbol,timeframe,shift) 双精度double型

  所属时间:iTime(symbol,timeframe,shift) 日期时间datetime型

  K线周期为:1分钟图(PERIOD_M1)、5分钟图(PERIOD_M5)、15分钟图(PERIOD_M15)、30分钟图(PERIOD_M30)、

  1小时图(PERIOD_H1)、4小时图(PERIOD_H4)、日线图(PERIOD_D1)、周线图(PERIOD_W1)、周线图(PERIOD_W1)、月线图(PERIOD_W1)

  例:

  iOpen(USDJPY,PERIOD_H1,0) 表示美元兑日元1小时图最新K线蜡烛的开盘价

  iClose(EURUSD,PERIOD_H4,2) 表示欧元兑美元4小时图第3根K线蜡烛的收盘价

  iClose(GBPUSD,PERIOD_H1,i) 表示英磅兑美元1小时图第i+1根K线蜡烛的收盘价

  iHigh(NULL,0,0) 既不指定商品,也不指定K线周期,用在谁就是谁,用在哪就是哪

  2、移动平均值。双精度double型

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

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

  均线周期:10天平均线的均线周期为10,20天均线的均线周期为20

  均线偏移:均线位置整体左右移动的位置偏移量

  平均模式:简单移动平均(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_H1,20,0,MODE_SMA,PRICE_CLOSE,0)

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

  例2:iMA(NULL,0,20,0,MODE_EMA,PRICE_CLOSE,2)

  表示:在当前商品、当前K线周期图表上,以收盘价计算的,20(天)指数移动平均线第3根K线所对应位置的值

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

  3、在数组中求元素的移动平均值。双精度double型

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

  这也与iMA函数差不多,外汇返佣平台,不过数据源变为数组

  从数组中不但可以求得移动平均值,还可以求得RSI等指标值

  4、求自定义指标的值

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

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

  如果自定义指标只有一根指标线,则自定义指标线的编号为0。

  如果自定义指标有多根指标线,则第一条自定义指标线的编号为0,第二条为1,第三条为2。。。

  例如:iCustom(NULL,0,mymacd,12,26,9,2,0) (12,26,9)为自定义指标mymacd的三个参数

  表示:求当前图表中,自定义指标mymacd(12,26,9)的第3条指标线在最新位置的值

  抛砖引玉,这里只是有代表性地列了几个函数,详细请查阅《MT4编程手册》

  MT4编程入门6:判断语句

  一、if语句

  if语句很常用,也比较简单。

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

  例如:

  if(a==1)

   {

   b=c+1;

   }

  我们在编写报警指标的时候,就经常用到这一语句:

  如果“价格向上达到指定价位”,则“报警”

  如果“MACD上穿”,则“报警”

  如果“均线金叉”,则“报警”。等等

  例:

  int mark=0;

  if( High[1]<1.0000 High[0]>=1.0000 mark!=1)

   {

   Alert(symbol(),价格向上触及1.0000);

   mark=1;

   }

  if( Low[1]>1.0000 Low[0]<=1.0000 mark!=2)

   {

   Alert(symbol(),价格向下触及1.0000);

   mark=2;

   }

  这是一个价格上、下穿1.0000时报警的判断语句:

  上穿报警条件:当第二根K线最高价小于1.0000,并且最新K线最高价大等于1.0000

  下穿报警条件:当第二根K线最低价大于1.0000,并且最新K线最低价小等于1.0000

  这里,mark是用作报警标记,mark的初值是0,

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

  当mark=0时,说明从未报过警,上、下穿都能报警;

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

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

  二、if ... else语句

  规则:如果小括号中的条件成立,则执行if下大括号中的语句1;如果不成立,则执行else下大括号中的语句2。

  if(条件)

   {

   语句1;

   }

  else

   {

   语句2;

   }

  三、注意事项

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

  2、语句用大括号括起来,但如果只有一行语句,则大括号可以省略

   if(条件) 语句1;

  MT4编程入门7:循环

  一幅K线图有几千上万条K线,每根K线又各有开收盘价、最高低价等数值,而且还有很多移动平均线、MACD、RSI等指标值。

  面对海量数据,我们必须用循环来实现数据的取值和赋值。

  一、while循环

  while(条件)

   {

   语句1

   语句2

   。。。

   }

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

  只要条件成立,程序就不停地运行大括号中的语句(循环体),直到小括号中的条件不再成立时结束循环。

  它与if语句的区别是:if语句是当条件为真时运行一次;而while语句则是只要条件为真,循环体语句就不停地运行,直到条件为假时结束循环。

  例:

   extern int 快线=12;

   extern int 慢线=26;

   double buffer[];

   int i=0;

   while(i<1000)

   {

   buffer[i]= iMA(NULL,0,快线,0,MODE_EMA,PRICE_CLOSE,i)

   -iMA(NULL,0,慢线,0,MODE_EMA,PRICE_CLOSE,i);

   i++;

   }

  这里,循环执行条件是i<1000,循环体中有两个语句,一句是把两条均线的差值赋给数组buffer,另一句“i++;”是每运行一次,i的值在原有基础上增加1。这样,随着循环的不断运行,i的值逐渐增加,循环1000次后,外汇返佣,i的值也就从0变为1000,此时“i<1000”就不再成立,循环结束。这样,数组buffer[]中也就有了1000个值。

  二、for循环

  for循环与while循环在原理上是一致的,只是书写格式上有所区别

  把上面的例子改成for语句:

   extern int 快线=12;

   extern int 慢线=26;

   double buffer[];

   for(int i=0; i<1000; i++)

   {

   buffer[i]= iMA(NULL,0,快线,0,MODE_EMA,PRICE_CLOSE,i)

   -iMA(NULL,0,慢线,0,MODE_EMA,PRICE_CLOSE,i);

   }

  与前面相比,我们注意到:

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

  “i++;”语句从循环体中移到了循环条件“i<1000”的后面;

  循环执行顺序与while循环一致:

  第一步、先执行小括号中的第1句:int i=0;

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

  第二步、再判断小括号中的第2句是否成立:i<1000;

  如果不成立,则循环结束;如果成立,则循环继续运行,执行第三步

  第三步、按顺序执行大括号中的语句

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

  然后回到第二步继续执行循环。

  再补充一点:如果循环体中(大括号中)只有一行语句,大括号可以省略

  MT4编程入门8:MT4自定义指标的结构

  MT4自定义指标一般由四个部分构成:

  (1)文件头部

  (2)参数、变量和数组的定义

  (3)初始化函数init()

  (4)主函数start()

  一、文件头部,也称为预处理程序

  预处理程序以“#”开头,行尾无语句结束符“;”

  常用的预处理程序有:

  1、#property indicator_chart_window

  把指标显示在主图。如:均线、SRA等类指标用到此语句

  2、#property indicator_separate_window

  把指标显示在副图。如:MACD、RSI、威廉等类指标用到此语句

  3、#property indicator_buffers 3

  显示3根指标线

  4、#property indicator_color1 Red

  第1根指标线的颜色为Red

  5、#property indicator_width1 1

  第1根指标线的粗细分别为1

  6、#property indicator_level1 0.00

  在0.00值位置横划1条虚线

  二、参数、变量和数组的定义

  全局性的参数、变量、数组在此定义,外汇开户网,局部变量可在start()函数中定义

  三、初始化函数init()

  init()在自定义指标加载时运行一次。

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

  四、主函数start()

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

  自定义指标的编程主要依靠此函数进行。

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

  另外,还有一个反初始化函数deinit()

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

  MT4编程入门9:画一条指标线

  要画指标线,只要在程序中写明以下几点就可以了:

  第一、明确指标线所在窗口,是主图还是副图

  第二、要建立数组,用以保存指标线在各个位置的值。

  第三、要建立指标线与数组的对应关系,哪个数组对应哪条指标线

  第四、要明确指标线的线型,是曲线还是柱线或者是箭头

  第五、如果指标线是箭头,还要说明是哪种箭头

  第六、给数组赋值

  其中:

  第一、二条写在文件头部中,

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

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

  下面以MACD为例说明

  我们知道,MACD指标由二条曲线和一组红绿柱线组成。(下图一)

  其中:

  白线是二根均线的差;

  紫线是白线的移动平均线;

  红绿柱线则是白线和紫线的差,白线上穿紫线,出现红柱,下穿则出现绿柱。

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

  下面是全部语句:

  #property indicator_separate_window

  #property indicator_color1 White

  #property indicator_level1 0

  extern int FMA=12;

  extern int SMA=26;

  double buf[];

  int init()

   {

   SetIndexBuffer(0,buf);

   SetIndexStyle(0,DRAW_LINE);

   return(0);

   }

  int start()

   {

   int limit=Bars-IndicatorCounted();

   for(int i=0; i<limit; i++)

   {

   buf[i]=

   iMA(NULL,0,FMA,0,1,0,i)

   -iMA(NULL,0,SMA,0,1,0,i);

   }

   return(0);

   }

  说明如下:

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

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

  以下为上述语句的简要说明

  #property indicator_separate_window

  指标放在副图

  #property indicator_color1 White

  第一条指标线为白色

  #property indicator_level1 0

  在副图中零值位置上画一条水平横线,

  extern int FMA=12;

  extern int SMA=26;

  设立二个整数型变量,默认值为12和26,允许外部修改值

  double buf[];

  设立一个数组

  int init()

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

   {

   SetIndexBuffer(0,buf);

   设置数组buf为第一条指标线

   SetIndexStyle(0,DRAW_LINE);

   设置第一条指标线线型为连续曲线

   return(0);

   函数结束语句

   }

  int start()

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

   {

   int limit=Bars-IndicatorCounted();

   自定义一个变量limit,并赋值

   Bars是图表中的柱数

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

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

   for(int i=0; i<limit; i++)

   循环语句。

   循环从i=0开始,每循环一次i值增加1,一直循环到i<limit不满足时结束循环

   由于循环变量i为一个新变量,所以要先定义,加上整型变量定义符int

   下面大括中为循环体,此例中只一条语句

   {

   buf[i]=

   iMA(NULL,0,FMA,0,1,0,i)

   -iMA(NULL,0,SMA,0,1,0,i);

   }

   给数组buf赋值,其值分别为相应位置上两条均线的差

   i是水平位置序号值,即烛柱从右到左的序号,右边第一个烛柱序号为0

   return(0);

   start函数结束

   }

  MT4编程入门10:MT4的报警

  报警功能是MT4的一大特色。

  它可以在预定的条件达到时,发出警报。

  与指标画线相比,报警语句显得非常简单,

  只要在判断语句中加一个报警语句即可

  报警方式有:弹出窗口报警、音乐报警、邮件报警等。

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

  1、弹出窗口报警:

  当(条件达到)执行此语句时,以弹出窗口警告。

  格式:Alert(内容1,内容2,内容3,内容4);

  报警内容为字符串型,内容之间加逗号

  例如:

  Alert( Symbol(),4小时图MACD上穿零轴);

  2、音乐报警:

  当(条件达到)执行此语句时,播放一段音乐。

  格式:PlaySound(音乐文件名.wav);

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

  文件名加引号

  3、邮件报警:

  当(条件达到)执行此语句时,发送一个邮件。

  (收发件人地址在MT4系统中设置详见《MT4编程实例1:一个简单的小程序,让你的手机摇身变成外汇行情接收机》)

  格式:SendMail(标题1+标题2, 内容1+内容2);

  标题之间以加号连接,内容之间也以加号连接

  邮件标题和邮件内容以逗号间隔

  下面是《价格穿越某均线报警》举例

  +---------------------------------

  #property indicator_chart_window

  extern int 警戒均线=20;

  int mark=0;

  int start()

  {

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

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

   mark != 1 )

   {

   Alert(Symbol(),向上触及30均线);

   mark = 1;

   }

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

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

   mark != 2 )

   {

   Alert(Symbol(),向下触及,警戒均线,均线);

   mark = 2;

   }

   return(0);

  }

  +---------------------------------

  部分语句说明:

  #property indicator_chart_window

  此句是把程序放在主图,当然这此例中放在副图也一样

  extern int 定义一个外部参数变量,整数型,允许外部值修改

  int 定义一个整数型变量

  int start() 定义触发函数

  if() 判断

  iHigh() 最高价值函数

  iLow() 最低价值函数

  iMA() 移动平均线值函数

  Alert() 报警函数

  Symbol() 商品名称函数

   逻辑运算符“并且”

  != 逻辑运算符“不等于”

  MODE_SMA 简单移动平均模式

  PRICE_CLOSE 以收盘价计算

  再说一下自定义变量mark的作用:

  mark的初值是0,当上穿报警时给mark赋值1,当下穿报警时给mark赋值2。

  这样当mark的值为1时,说明已经对上穿报过警了,就不能再次对上穿报警;

  当mark的值为2时,说明已经对下穿报过警了,就不能再次对下穿报警。

  这样就起到了消除重复报警的作用。

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

  语句简要解释如下:

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

  #property indicator_chart_window

  指标放在主图

  extern int 警戒均线=20;

  设立一个自定义变量,允许外部值修改,整数形,变量名为警戒均线,默认值20

  int mark=0;

  设立一个自定义变量,整数型,变量名为mark,并赋初值0

  此变量在后面用于记录是否报警,设计是这样的:

  如果mark=0,则从未报过警

  如果mark=1,则已经向上报过警

  如果mark=2,则已经向下报过警

  int start()

  设立触发函数start。start为系统规定函数名,函数内容自定义。当数据变动时,start函数被触发

  {

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

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

   mark != 1 )

   条件判断语句。这里用到逻辑运算符,就是“并且”,条件有三个,三个条件要同时成立,则整个条件才成立

   第一个条件:最高价大等于均线。iHigh是烛柱最高价取值函数,iMA是均线取值函数

   第二个条件:前一烛柱最高价小于均线

   第三个条件:mark不等于1。如果mark不等于1,就说明指标没有对上穿报过警

   {

   Alert(Symbol(),向上触及30均线);

   mark = 1;

   }

   花括中为条件执行语句。Alert是报警语句,Symbol()是商品名称取值函数

   报警语句执行后,给mark赋值1,这样就记录了已经向上报过警了

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

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

   mark != 2 )

   {

   Alert(Symbol(),向下触及,警戒均线,均线);

   mark = 2;

   }

   return(0);

   start函数结束语句,返回零值

  }

  MT4编程实例:箭头符号

  符号是一种断断续续的指标线。在指标线有值区域,指标线显示;在指标线无值区域,指标线隐藏。例如下图:当价格上穿、下穿均线时,均线上出现一个标记符号。

  原理也很简单:在上图中,存在二条指标线,一条是均线,另一条是笑脸符号线。

  均线在任何位置都有值,所以均线是一条连续的曲线;

  当价格上、下穿均线时,符号线被赋予了均线值;而在其他位置上,符号线被赋了空值。所以只是在价格上、下穿均线的位置上,符号线才有值,才能出现笑脸符号。因为符号线只是个别位置有值,所以符号线仅在个别位置显现。

  符号也正好落在均线上,因为符号线值=均线值。如果符号线被赋了别的值,例如(符号线=均线+10点),那么符号水平坐标不变,垂直坐标将是均线上方的10点位置。

  源码如下:

  //======================================================

  #property indicator_chart_window

  #property indicator_buffers 1

  #property indicator_color1 Yellow

  extern int 均线=10;

  double mk[];

  double temp0,temp1;

  int init()

   {

   IndicatorBuffers(1);

   SetIndexBuffer(0,mk);

   SetIndexStyle(0,DRAW_ARROW);

   SetIndexArrow(0,204);

   IndicatorDigits(Digits);

   return(0);

   }

  int start()

   {

   int limit;

   int counted_bars=IndicatorCounted();

   if(counted_bars>0) counted_bars--;

   limit=Bars-counted_bars-均线;

   for(int i=0; i<limit; i++)

   {

   temp0=iMA(NULL,0,均线,0,0,0,i);

   temp1=iMA(NULL,0,均线,0,0,0,i+1);

   mk[i]=EMPTY_VALUE;

   if(Close[i]>temp0 Close[i+1]<temp1) mk[i]=temp0;

   if(Close[i]<temp0 Close[i+1]>temp1) mk[i]=temp0;

   }

   return(0);

   }

  //源码到此已结束

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

  语句简要解释如下:

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

  #property indicator_chart_window

  指标放在主图

  #property indicator_buffers 1

  设置指标线数为1条

  #property indicator_color1 Yellow

  设置第一条指标线颜色为黄色

  extern int 均线=10;

  设立一个自定义变量,允许外部值修改,整数形,变量名为均线,默认值10

  double mk[];

  设立一个自定义数组,双精度型

  double temp0,temp1;

  设立二个自定义变量,双精度型,变量名为temp0、temp1

  int init()

  设立初始化函数init。init为系统规定函数名,函数内容自定义。该函数在指标被加载时仅运行一次

  {

   IndicatorBuffers(1);

   指标线数量为1条

   SetIndexBuffer(0,mk);

   第一条指标线的数组为mk

   SetIndexStyle(0,DRAW_ARROW);

   第一条指标线的线型为箭头符号

   SetIndexArrow(0,204);

   第一条指标线的箭头符号为第204种符号,如果换一个编号,那出现的就是另一种符号。箭头符号的编码详见《MT4编程参考》

   IndicatorDigits(Digits);

   设置指标线的小数位数

   Digits=当前汇率的小数位数,如日元叉盘Digits=2,其他币对Digits==4

   return(0);

   函数结束,返回零值

   }

  int start()

  设立触发函数start。start为系统规定函数名,函数内容自定义。当数据变动时,start函数被触发

   {

   int limit;

   设立整数型自定义变量limit

   int counted_bars=IndicatorCounted();

   设立整数型自定义变量counted_bars,并将IndicatorCounted()的值赋给counted_bars

   IndicatorCounted()为缓存数量,即已经计算过值的烛柱数

   if(counted_bars>0) counted_bars--;

   如果counted_bars大于零,现货黄金开户,则将counted_bars的值减掉1

   这是为了配合下一句,以避免limit相差1而发生出错

   limit=Bars-counted_bars-均线;

   这是给limit赋值

   Bars为图表中的柱数

   counted_bars为已经赋值的柱数

   这样limit的结果就是未赋值的烛柱数

   再减去“均线”是因为图表最右边段均线无意义

   for(int i=0; i<limit; i++)

   循环语句,括号中有三个语句:

   第一句int i=0; 表示循环从i=0开始

   第二句i<limit; 这是循环的条件,如果条件满足则执行大括号中的循环体,如果条件不满足,则中止循环,跳到大括号下面的语句执行

   第三句i++,这是循环步调控制语句,每循环一次后执行一次此语句。

   i++相当于i=i+1,即i值在原有数值上增加1

   {

   temp0=iMA(NULL,0,均线,0,0,0,i);

   把均线在i位置上的值赋给temp0

   iMA:均线取值函数

   temp1=iMA(NULL,0,均线,0,0,0,i+1);

   把均线在(i+1)位置上的值赋给temp1

   mk[i]=EMPTY_VALUE;

   给数组mk在i位置上赋空值

   EMPTY_VALUE就是空值

   if(Close[i]>temp0 Close[i+1]<temp1) mk[i]=temp0;

   条件判断语句。如果在i位置上价格大于均线,并且在(i+1)位置上价格小于均线(即价格上穿均线),则给数组mk在i位置上赋该位置的均线值

   Close[i]:在i位置上收盘价。

   :逻辑运算符“并且”

   if(Close[i]<temp0 Close[i+1]>temp1) mk[i]=temp0;

   与上一句相似

   }

   return(0);

   start函数结束语句

  MT4编程实例:在欧元图上显示英磅的RSI指标

  下面这个图是AUD图上,叠加了英磅的RSI指标。

  (当然也可以不叠加,分两个窗口)

  从RSI指标图上我们看到,英磅强势,而澳元很弱

  下面是指标源码

  -------------------------------------------------------------------------------------------------------

  #property indicator_separate_window

  #property indicator_buffers 1

  #property indicator_color1 Aqua

  #property indicator_level1 30

  #property indicator_level2 70

  extern int RSI=12;

  extern string 商品=GBPUSD;

  double ind_buffer[];

  int init()

   {

   SetIndexBuffer(0,ind_buffer);

   SetIndexStyle(0,DRAW_LINE,STYLE_SOLID,1);

   IndicatorShortName(RSI(+商品+, +RSI+));

   return(0);

   }

  int start()

   {

   int limit;

   int counted_bars=IndicatorCounted();

   if(counted_bars<0) return(-1);

   if(counted_bars>0) counted_bars--;

   limit=Bars-counted_bars;

   for(int i=0; i<limit; i++)

   ind_buffer[i]=iRSI(商品,0,RSI,PRICE_CLOSE,i);

   return(0);

   }

  -------------------------------------------------------------------------------------------------------

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

  语句简要解释如下:

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

  #property indicator_separate_window

  指标放在副图

  #property indicator_buffers 1

  设置指标线数组为1个

  #property indicator_color1 Aqua

  设置第一条指标线颜色值为Aqua,即介于蓝绿之间的一种颜色

  #property indicator_level1 30

  在副图中,30值位置上画一条水平直线

  #property indicator_level2 70

  在副图中,70值位置上画一条水平直线

  extern int RSI=12;

  设立一个自定义变量,允许外部值修改,整数型,变量名为RSI,默认值12

  extern string 商品=GBPUSD;

  设立一个自定义变量,允许外部值修改,字符串型,变量名为商品,默认值GBPUSD

  double ind_buffer[];

  设立一个自定义数组,双精度型

  int init()

  设立初始化函数init。init为系统规定函数名,函数内容自定义。该函数在指标被加载时运行一次

   {

   SetIndexBuffer(0,ind_buffer);

   设置第一条指标线的数组为ind_buffer

   SetIndexStyle(0,DRAW_LINE,STYLE_SOLID,1);

   设置第一条指标线的样式,DRAW_LINE表示连续曲线,STYLE_SOLID表示实心线,1号粗线

   IndicatorShortName(RSI(+商品+, +RSI+));

   设置指标线的显示简称

   return(0);

   初始化函数结束

   }

  int start()

  设立触发函数start。start为系统规定函数名,函数内容自定义。当数据变动时,start函数被触发

   {

   int limit;

   设立自定义变量limit,整数型

   int counted_bars=IndicatorCounted();

   设立整数型自定义变量counted_bars,并将IndicatorCounted()的值赋给counted_bars

   IndicatorCounted()为缓存数量,即已经计算过值的烛柱数

   (注:可能这里解释得不是很准确,大致就这个意思)

   if(counted_bars<0) return(-1);

   如果counted_bars值小于零,start函数结束

   if(counted_bars>0) counted_bars--;

   如果counted_bars值大于零,则counted_bars值减掉1。这是为了配合下一句,以避免limit相差1而出错

   limit=Bars-counted_bars;

   给limit赋值

   Bars为图表中的柱数

   counted_bars为已经赋值的柱数

   这样limit的值就是未赋值的烛柱数

   这样做的目的是避免重复运算,优化程序

   for(int i=0; i<limit; i++)

   循环语句,括号中有三个语句:

   第一句int i=0; 表示循环从i=0开始

   第二句i<limit; 这是循环的条件,如果条件满足则执行大括号中的循环体,如果条件不满足,则中止循环,跳到大括号下面的语句执行

   第三句i++,这是循环步调控制语句,每循环一次后执行一次此语句。

   i++相当于i=i+1,即i值在原有数值上增加1

   ind_buffer[i]=iRSI(商品,0,RSI,PRICE_CLOSE,i);

   此语句为循环体,由于只有一个语句,所以省略花括号

   i为图表烛柱的序号,从0开始,右边第1柱序号为0,从右向左递增

   iRSI为RSI指标的取值函数

   return(0);

   start函数结束

   }

  MT4编程实例:会变色的均线

  下面这个是示意图:

  均线会变色,看起来很神秘,但原理其实很简单:

  这里实际上有两条均线,一条红线,一条绿线:

  当价格在均线上方时,红线显示,绿线隐藏;

  当价格在均线下方时,红线隐藏,绿线显示,

  所以看起来就只是一条会变色的均线。

  要隐藏一条指标线中的其中一段,也很简单,只要把这一段指标线的值赋为空值(EMPTY_VALUE)就行了。

  说说容易,但实际操作的时候,我们又遇到了一个小问题,那就是红绿转换点的“断点”问题,红线和绿线不连续了。图:

  这个问题着实困扰了我好一阵,后来终于想通了。

  原来,画线的条件是:前后两个时点上都必须有值,才能画出线来。而上图中2和3之间应该画上红线,但在3点位上,红线的值为空,所以,红线画不出来。

  要让红线、绿线连续,必须使3点位上,既有绿线值又有红线值,这样2和3之间才能出现红线,红线绿才会连续。

  为了做到这一点,我们在给指标线循环赋值的时候:

  1、在 i 时点上,除了给 i 时点赋值,同时还要给 i+1时点赋同色值(以上图为例:我们在给3时点赋绿线值时,同时给4时点赋绿线值;在给2时点赋红线值时,同时再给3点赋红线值;这样3时点上就既有红线值,又有绿线值);

  2、赋值的顺序为从左向右,即递减循环,以避免前一操作所赋的值被清空。

  这样我们的目的就达到了。

  下面这是经过测试的源代码

  ---------------------------------------------------------------------------------------------------

  #property indicator_chart_window

  #property indicator_buffers 2

  #property indicator_color1 Red

  #property indicator_color2 Green

  extern int 变色均线=18;

  double duo[];

  double kong[];

  int init()

   {

   SetIndexBuffer(0,duo);

   SetIndexBuffer(1,kong);

   SetIndexStyle(0,DRAW_LINE);

   SetIndexStyle(1,DRAW_LINE);

   SetIndexDrawBegin(0,变色均线);

   SetIndexDrawBegin(1,变色均线);

   IndicatorDigits(Digits);

   return(0);

   }

  int start()

   {

   double temp0,temp1;

   int limit;

   int counted_bars=IndicatorCounted();

   if(counted_bars<0) return(-1);

   if(counted_bars>0) counted_bars--;

   limit=Bars-counted_bars;

   for(int i=limit; i>=0; i--)

   {

   duo[i]=EMPTY_VALUE;

   kong[i]=EMPTY_VALUE;

   temp0=iMA(NULL,0,变色均线,0,MODE_SMA,PRICE_CLOSE,i);

   temp1=iMA(NULL,0,变色均线,0,MODE_SMA,PRICE_CLOSE,i+1);

   if(iClose(NULL,0,i)>=iMA(NULL,0,变色均线,0,MODE_SMA,PRICE_CLOSE,i))

   {duo[i]=temp0; duo[i+1]=temp1;}

   else {kong[i]=temp0; kong[i+1]=temp1;}

   }

   return(0);

   }

  -----------------------------------------------------------------------------------------------------------

  当然,上面这个是以价格在均线上下方为条件的,我们也可以以MACD、KDJ、RSI等指标作为均线变色的条件。我们还可以更进一步,把双色线改为三色线等等

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

  语句简要解释如下:

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

  #property indicator_chart_window

  指标放在主图

  #property indicator_buffers 2

  设置指标线数组为2个

  #property indicator_color1 Red

  #property indicator_color2 Green

  设置第一条指标线颜色值为Red,第二条颜色值为Green

  extern int 变色均线=18;

  设立一个自定义变量,允许外部值修改,整数形,变量名为变色均线,默认值18

  double duo[];

  设立一个自定义数组,双精度型,名称为duo

  该数组在后面用于存储红线数据

  double kong[];

  设立一个自定义数组,双精度型,名称为kong

  该数组在后面用于存储绿线数据

  int init()

  设立初始化函数init。init为系统规定函数名,函数内容自定义。该函数在指标被加载时运行一次

   {

   SetIndexBuffer(0,duo);

   SetIndexBuffer(1,kong);

   设置第一、二条指标线的数组为duo和kong

   SetIndexStyle(0,DRAW_LINE);

   SetIndexStyle(1,DRAW_LINE);

   设置第一、二条指标线的样式,线型为连续曲线

   SetIndexDrawBegin(0,变色均线);

   SetIndexDrawBegin(1,变色均线);

   设置第一、二条指标线的最左边的起始划线位置

   IndicatorDigits(Digits);

   设置指标精确到的小数位数

   Digits是当前汇率小数位,日系Digits=2,其他币对Digits=4

   return(0);

   init函数结束,返回零值

   }

  int start()

  设立触发函数start。start为系统规定函数名,函数内容自定义。当数据变动时,start函数被触发

   {

   double temp0,temp1;

   设立双精度型自定义变量temp0、temp1

   int limit;

   设立自定义变量limit,整数型

   int counted_bars=IndicatorCounted();

   设立整数型自定义变量counted_bars,并将IndicatorCounted()的值赋给counted_bars

   IndicatorCounted()为缓存数,即已经计算过值的烛柱数

   if(counted_bars<0) return(-1);

   如果counted_bars值小于零,start函数结束

   if(counted_bars>0) counted_bars--;

   如果counted_bars值大于零,则counted_bars值减掉1。这是为了配合下一句,以避免limit相差1而出错

   limit=Bars-counted_bars;

   给limit赋值

   Bars为图表中的烛柱数

   counted_bars为缓存数,即已经运算过的烛柱数

   这样limit的值就是未经运算的烛柱数

   这样做的目的是避免重复运算,优化程序

   for(int i=limit; i>=0; i--)

   循环语句,括号中有三个语句:

   第一句int i=limit; 表示循环从i=limit开始

   第二句i>=0; 这是循环的条件,如果条件满足则执行大括号中的循环体,如果条件不满足,则中止循环,跳到大括号下面的语句执行

   第三句i--,这是循环步调控制语句,每循环一次后执行一次此语句。

   i--相当于i=i-1,即i值在原有数值上减少1

   {

   duo[i]=EMPTY_VALUE;

   kong[i]=EMPTY_VALUE;

   给数组duo和kong在i位置上赋空值

   EMPTY_VALUE:空值

   temp0=iMA(NULL,0,变色均线,0,MODE_SMA,PRICE_CLOSE,i);

   temp1=iMA(NULL,0,变色均线,0,MODE_SMA,PRICE_CLOSE,i+1);

   把均线在i和i+1位置上均线值,分别赋给temp0和temp1

   这是为了使后面的语句看起来简洁

   if(iClose(NULL,0,i)>=iMA(NULL,0,变色均线,0,MODE_SMA,PRICE_CLOSE,i))

   判断条件语句:如果价格高于均线

   {duo[i]=temp0; duo[i+1]=temp1;}

   判断执行语句:给数组元素duo[i]、duo[i+1]分别赋值

   else {kong[i]=temp0; kong[i+1]=temp1;}

   如果判断条件不成立,即价格低于均线:则给数组元素kong[i]、kong[i+1]分别赋值

   }

   return(0);

   start函数结束,返回零值

   }

  MT4编程参考

  MT4编程参考-第一节 语法

  语法 [Syntax]

  代码格式

  空格建、Tab键、换行键和换页符都可以成为代码排版的分隔符,你能使用各种符号来增加代码的可读性。

  注释

  多行注释使用 结束,在这之间不能够嵌套。单行注释使用 // 作为开始到新的一行结束,可以被嵌套到多行注释之中。

  示例:

  // 单行注释

  标识符

  标识符用来给变量、函数和数据类型进行命名,长度不能超过31个字节

  你可以使用数字0-9、拉丁字母大写A-Z和小写a-z(大小写有区分的)还有下划线(_)。此外首字母不可以是数。

现货黄金开户-专业的外汇返佣代理开户平台-第一外汇返佣网消息对炒外汇的重要性