手机版

MT4编程入门

阅读 :
外_汇_邦 WaiHuiBang.com

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(大小写有区分的)还有下划线(_)。此外首字母不可以是数字,标识符不能和保留字冲突.

示例:

// NAME1 namel Total_5 Paper

 

保留字 

下面列出的是固定的保留字。不能使用以下任何保留字进行命名。

数据类型 存储类型 操作符 其它

bool extern break false

color static case true

datetime   continue  

double   default  

int   else  

string   for  

void   if  

    return  

    switch  

    while  

第二节 数据类型

数据类型 [Data types]

数据类型概述

主要数据类型有:

• Integer (int) 

• Boolean (bool) 

• ëèòåðàëû (char) 

• String (string) 

• Floating-point number (double) 

• Color (color) 

• Datetime (datetime) 

我们用Integer类型数据来作为DateTime和Color数据的存储。

使用以下方式可以进行类型站换:

int (bool,color,datetime);

double;

string;

 

Integer 类型

十进制: 数字0-9;0不能作为第一个字母

示例:

12, 111, -956 1007

十六进制: 数字0-9;拉丁字母a-f或A-F用来表示10-15;使用0x或者0X作为开始。

示例:

0x0A, 0x12, 0X12, 0x2f, 0xA3, 0Xa3, 0X7C7

Integer 变量的取值范围为-2147483648到2147483647。

 

Literal 类型

任意在单引号中的字符或十六进制的任意ASCII码例如'\x10'都是被看作为一个字符,

一些字符例如单引号('),双引号("),问号(?),反斜杠(\)和一些控制符都需要在之前加一个反斜杠(\)进行转意后表示出来:

line feed NL (LF) \n

horizontal tab HT \t

carriage return CR \r

reverse slash \ \\

single quote ' \'

double quote " \"

hexadecimal ASCII-code hh \xhh

以上字符如果不经过反斜杠进行转意将不能被使用

示例:

int a = 'A';

int b = '$';

int c = '©'; // code 0xA9

int d = '\xAE'; // symbol code ®

 

Boolean 类型

Boolean 用来表示 是 和 否, 还可以用数字 1 和 0 进行表示。True和Flase可以忽略大小写。

示例:

bool a = true;

bool b = false;

bool c = 1;

 

Floating-point number 类型

浮点型变量在整数型后面加一个点(.)用来更精确的表示十进制数字。

示例:

double a = 12.111;

double b = -956.1007;

double c = 0.0001;

double d = 16;

浮点型的取值范围从 2.2e-308 到 1.8e308.

 

String 类型

字符串型是用来表示连续的ASCII码字符的使用连续的两个双引号来包括需要表示的内容如:"Character constant".

示例:

"This is a character string"

"Copyright symbol \t\xA9"

"this line with LF symbol \n"

"A" "1234567890" "0" "$"

 

Color 类型

颜色类型可以使用以下示例里的几种方式进行定义。

示例:

// symbol constants

C'128,128,128' // gray

C'0x00,0x00,0xFF' // blue

// named color

Red

Yellow

Black

// integer-valued representation

0xFFFFFF // white

16777215 // white

0x008000 // green

32768 // green

 

Datetime 类型

时间类型使用年、月、日、时、分、秒来进行定义,你可以使用以下示例中的方式来定义变量。

示例:

D'2004.01.01 00:00' // New Year

D'1980.07.19 12:30:27'

D'19.07.1980 12:30:27'

D'19.07.1980 12' //equal to D'1980.07.19 12:00:00'

D'01.01.2004' //equal to D'01.01.2004 00:00:00'

D'12:30:27' //equal to D'[compilation date] 12:30:27'

D'' //equal to D'[compilation date] 00:00:00'

第三节 运算符和表达式

运算符和表达式 [Operations & Expressions]

表达式

一个表达式可以拥有多个字符和操作符,一个表达式可以写在几行里面。

示例:

a++; b = 10; x = (y*z)/w;

注:分号(;)是表达式的结束符。

 

算术运算符

Sum of values i = j + 2;

Difference of values i = j - 3;

Changing the operation sign x = - x;

Product of values z = 3 * x;

Division quotient i = j / 5;

Division remainder minutes = time % 60;

Adding 1 to the variable value i++;

Subtracting 1 from the variable value k--;

加减1的运算符不能被嵌套在表达式中

int a=3;

a++; // 可行的表达式

int b=(a++)*3; // 不可行的表达式

 

赋值运算符

注:将右侧的结果赋值给左侧的变量

将x的值赋值给y y = x;

将x的值加到y上面 y += x;

在y上面减去x的值 y -= x;

得到y的x倍的值 y *= x;

得到y除以x的值 y /= x;

取y除以x后的余数 y %= x;

y向右位移x位 y >>= x;

y向左位移x位 y <<= x;

得到逻辑AND的值 y &= x;

得到逻辑OR的值 y |= x;

得到逻辑非OR的值 y ^= x;

注:一个表达式只能有一个赋值运算符.

 

关系运算符

用返回0(False)或1(True)来表示两个量之间的关系。

a是否等于b a == b;

a是否不等于b a != b;

a是否小于b a < b;

a是否大于b a > b;

a是否小于等于b a <= b;

a是否大于等于b a >= b;

 

真假运算符

否定运算符(!),用来表示真假的反面的结果。

// 如果a不是真的

if(!a)

Print("not 'a'");

逻辑运算符或(||)用来表示两个表达式只要有一个成立即可。

示例:

if(xl)

Print("out of range");

逻辑运算符和(&&)用来表示两个表达式要同时成立才行。

示例:

if(p!=x && p>y)

Print("true");

n++;

 

位逻辑运算符

~ 运算符对操作数执行按位求补操作。

b = ~n;

>> 运算符对操作数执行向右位移操作。

x = x >> y;

<< 运算符对操作数执行向左位移操作。

x = x << y;

一元 & 运算符返回操作数的地址

为整型和 bool 类型预定义了二进制 & 运算符。对于整型,& 计算操作数的按位“与”。对于 bool 操作数,& 计算操作数的逻辑“与”;也就是说,当且仅当两个操作数均为 true 时,其结果才为 true。

b = ((x & y) != 0);

二进制 | 运算符是为整型和 bool 类型预定义的。对于整型,| 对操作数进行按位“或”运算。对于 bool 操作数,| 对操作数进行逻辑“或”计算,也就是说,当且仅当两个操作数均为 false 时,其结果才为 false。

b = x | y;

为整型和 bool 类型预定义了 ^ 二进制操作数。对于整型,^ 计算操作数的按位“异或”。对于 bool 操作数,^ 计算操作数的逻辑“异或”;也就是说,当且仅当只有一个操作数为 true 时,其结果才为 true。

b = x ^ y;

注:位逻辑运算符只作用于Integers类型

 

其它运算符

索引。定位在数组中i位置的值。

array[i] = 3;

//将3负值到array数组第i位置上

使用 x1,x2,...,xn 这样的方法将各种值传送到function中进行运算。

示例:

double SL=Ask-25*Point;

double TP=Ask+25*Point;

int ticket=OrderSend(Symbol(),OP_BUY,1,Ask,3,SL,TP,

"My comment",123,0,Red);

 

优先级规则

下面是从上到下的运算优先规则,优先级高的将先被运算。

() Function call From left to right

[] Array element selection

! Negation From left to right

~ Bitwise negation

- Sign changing operation

* Multiplication From left to right

/ Division

% Module division

+ Addition From left to right

- Subtraction

<< Left shift From left to right

>> Right shift

< Less than From left to right

<= Less than or equals

> Greater than

>= Greater than or equals

== Equals From left to right

!= Not equal

& Bitwise AND operation From left to right

^ Bitwise exclusive OR From left to right

| Bitwise OR operation From left to right

&& Logical AND From left to right

|| Logical OR From left to right

= Assignment From right to left

+= Assignment addition

-= Assignment subtraction

*= Assignment multiplication

/= Assignment division

%= Assignment module

>>= Assignment right shift

<<= Assignment left shift

&= Assignment bitwise AND

|= Assignment bitwise OR

^= Assignment exclusive OR

, Comma From left to right

第四节 操作符

操作符 [Operators] 

格式和嵌套

格式.一个操作符可以占用一行或者多行,两个或多个操作符可以占用更多的行。

嵌套.执行控制符(if, if-else, switch, while and for)可以进行任意嵌套.

 

复合操作符

一个复合操作符有一个(一个区段)和由一个或多个任何类型的操作符组成的的附件{}. 每个表达式使用分号作为结束(;)

示例:

if(x==0)

{

x=1; y=2; z=3;

}

 

表达式操作符

任何以分号(;)结束的表达式都被视为是一个操作符。

Assignment operator.

Identifier=expression;

标识符=表达式;

示例:

x=3;

y=x=3; // 这是错误的

一个操作符中只能有一个表达式。

调用函数操作符

Function_name(argument1,..., argumentN);

函数名称(参数1,...,参数N);

示例:

fclose(file);

空操作符

只有一个分号组成(;).我们用它来表示没有任何表达式的空操作符.

 

停止操作符

一个break; , 我们将其放在嵌套内的指定位置,用来在指定情况下跳出循环操作.

示例:

// 从0开始搜索数组

for(i=0;i<ARRAY_SIZE;I++)

if((array[i]==0)

break;

 

继续操作符

一个continue;我们将其放在嵌套内的指定位置,用来在指定情况下跳过接下来的运算,直接跳入下一次的循环。

示例:

// summary of nonzero elements of array

int func(int array[])

{

int array_size=ArraySize(array);

int sum=0;

for(int i=0;i

{

if(a[i]==0) continue;

sum+=a[i];

}

return(sum);

}

 

返回操作符

一个return;将需要返回的结果放在return后面的()中。

示例:

return(x+y);

 

条件操作符 if

if (expression)

operator;

如果表达式为真那么执行操作。

示例:

if(a==x)

temp*=3;

temp=MathAbs(temp);

 

条件操作符 if-else

if (expression)

operator1

else

operator2

如果表达式为真那么执行operator1,如果为假执行operator2,else后还可以跟进多个if执行多项选择。详见示例。

示例:

if(x>1)

if(y==2)

z=5;

else

z=6;

if(x>l)

{

if(y==2) z=5;

}

else

{

z=6;

}

// 多项选择

if(x=='a')

{

y=1;

}

else if(x=='b')

{

y=2;

z=3;

}

else if(x=='c')

{

y = 4;

}

else

{

Print("ERROR");

}

 

选择操作符 switch

switch (expression)

{

case constant1: operators; break;

case constant2: operators; break;

...

default: operators; break;

}

当表达式expression的值等于结果之一时,执行其结果下的操作。不管结果如何都将执行default中的操作。

示例:

case 3+4: //正确的

case X+Y: //错误的

被选择的结果只可以是常数,不可为变量或表达式。

示例:

switch(x)

{

case 'A':

Print("CASE A\n");

break;

case 'B':

case 'C':

Print("CASE B or C\n");

break;

default:

Print("NOT A, B or C\n");

break;

}

 

循环操作符 while

while (expression)

operator;

只要表达式expression为真就执行操作operator

示例:

while(k<N)

{

y=y*x;

k++;

}

 

循环操作符 for

for (expression1; expression2; expression3)

operator;

用表达式1(expression1)来定义初始变量,当表达式2(expression2)为真的时候执行操作operator,在每次循环结束后执行表达式3(expression3)

用while可以表示为这样:

expression1;

while (expression2)

{

operator;

expression3;

};

示例:

for(x=1;x<=7;x++)

Print(MathPower(x,2));

使用for(;;)可以造成一个死循环如同while(true)一样.

表达式1和表达式3都可以内嵌多个用逗号(,)分割的表达式。

示例:

for(i=0,j=n-l;i<N;I++,J--)

a[i]=a[j];

第五节 函数

函数 [Function]

函数定义

一个函数是由返回值、输入参数、内嵌操作所组成的。

示例:

double // 返回值类型

linfunc (double x, double a, double b) // 函数名和输入参数

{

// 内嵌的操作

return (a*x + b); // 返回值

}

如果没有返回值那么返回值的类型可以写为void

示例:

void errmesg(string s)

{

Print("error: "+s);

}

 

函数调用

function_name (x1,x2,...,xn)

示例:

int somefunc()

{

double a=linfunc(0.3, 10.5, 8);

}

double linfunc(double x, double a, double b)

{

return (a*x + b);

}

 

特殊函数 init()、deinit()和start()

init()在载入时调用,可以用此函数在开始自定义指标或者自动交易之前做初始化操作。

deinit()在卸载时调用,可以用此函数在去处自定义指标或者自动交易之前做初始化操作。

start()当数据变动时触发,对于自定义指标或者自动交易的编程主要依靠此函数进行。

 

第六节 变量

变量 [Variables]

定义变量

定义基本类型

基本类型包括

• string - 字符串型; 

• int - 整数型; 

• double - 双精度浮点数型; 

• bool - 布尔型 

示例:

string MessageBox;

int Orders;

double SymbolPrice;

bool bLog;

 

定义附加类型

附加类型包括

• datetime - 时间型,使用无符号整型数字存储,是1970.1.1 0:0:0开始的秒数 

• color - 颜色,使用三色的整型数字编码而成 

示例:

extern datetime tBegin_Data = D'2004.01.01 00:00';

extern color cModify_Color = C'0x44,0xB9,0xE6';

 

定义数组类型

示例:

int a[50]; //一个一维由五十个int组成的数组

double m[7][50]; //一个两维由7x50个double组成的数组

内部变量定义

内部变量顾名思义是在内部使用的,可以理解为在当前嵌套内所使用的变量。

 

函数参数定义

示例:

void func(int x, double y, bool z)

{

...

}

函数的参数内的变量只能在函数内才生效,在函数外无法使用,而且在函数内对变量进行的修改在函数外无法生效。

调用函数示例:

func(123, 0.5);

如果有需要在变量传入由参数传入函数内操作后保留修改在函数外生效的情况的话,可以在参数定义的类型名称后加上修饰符(&)。

示例:

void func(int& x, double& y, double& z[])

{

...

}

 

静态变量定义

在数据类型前加上static就可以将变量定义成静态变量

示例:

{

static int flag

}

 

全局变量定义

全局变量是指在整个程序中都能够调用的变量,只需将变量定义卸载所有嵌套之外即可。

示例:

int Global_flag;

int start()

{

...

}

 

附加变量定义

附加变量可以允许由用户自己输入。

示例:

extern double InputParameter1 = 1.0;

int init()

{

...

}

 

初始化变量

变量必须经过初始化才可以使用。

 

基本类型

示例:

int mt = 1; // integer 初始化

// double 初始化

double p = MarketInfo(Symbol(),MODE_POINT);

// string 初始化

string s = "hello";

 

数组类型

示例:

int mta[6] = {1,4,9,16,25,36};

 

外部函数引用

示例:

#import "user32.dll"

int MessageBoxA(int hWnd ,string szText,

string szCaption,int nType);

int SendMessageA(int hWnd,int Msg,int wParam,int lParam);

#import "lib.ex4"

double round(double value);

#import

第七节 预处理程序

预定义变量 [Pre-defined Variables] 

double Ask

通货的买入价

示例:

if(iRSI(NULL,0,14,PRICE_CLOSE,0)<25)

{

OrderSend(Symbol(),OP_BUY,Lots,Ask,3,Ask-StopLoss*Point,Ask+TakeProfit*Point,

"My order #2",3,D'2005.10.10 12:30',Red);

return;

}

 

int Bars

返回图表中的柱数

示例:

int counter=1;

for(int i=1;i<=Bars;i++)

{

Print(Close[i-1]);

}

 

double Bid

通货的卖价

示例:

if(iRSI(NULL,0,14,PRICE_CLOSE,0)>75)

{

OrderSend("EURUSD",OP_SELL,Lots,Bid,3,Bid+StopLoss*Point,Bid-TakeProfit*Point,

"My order #2",3,D'2005.10.10 12:30',Red);

return(0);

}

 

double Close[]

返回指定索引位置的收盘价格

示例:

int handle, bars=Bars;

handle=FileOpen("file.csv",FILE_CSV|FILE_WRITE,';');

if(handle>0)

{

// write table columns headers

FileWrite(handle, "Time;Open;High;Low;Close;Volume");

// write data

for(int i=0; i

FileWrite(handle, Time[i], Open[i], High[i], Low[i], Close[i], Volume[i]);

FileClose(handle);

}

 

int Digits

返回当前通货的汇率小数位

示例:

Print(DoubleToStr(Close[i-1], Digits));

 

double High[]

返回指定索引位置的最高价格

示例:

int handle, bars=Bars;

handle=FileOpen("file.csv", FILE_CSV|FILE_WRITE, ';');

if(handle>0)

{

// write table columns headers

FileWrite(handle, "Time;Open;High;Low;Close;Volume");

// write data

for(int i=0; i

FileWrite(handle, Time[i], Open[i], High[i], Low[i], Close[i], Volume[i]);

FileClose(handle);

}

 

double Low[]

返回指定索引位置的最低价格

示例:

int handle, bars=Bars;

handle=FileOpen("file.csv", FILE_CSV|FILE_WRITE, ";");

if(handle>0)

{

// write table columns headers

FileWrite(handle, "Time;Open;High;Low;Close;Volume");

// write data

for(int i=0; i

FileWrite(handle, Time[i], Open[i], High[i], Low[i], Close[i], Volume[i]);

FileClose(handle);

}

 

double Open[]

返回指定索引位置的开盘价格

示例:

int handle, bars=Bars;

handle=FileOpen("file.csv", FILE_CSV|FILE_WRITE, ';');

if(handle>0)

{

// write table columns headers

FileWrite(handle, "Time;Open;High;Low;Close;Volume");

// write data

for(int i=0; i

FileWrite(handle, Time[i], Open[i], High[i], Low[i], Close[i], Volume[i]);

FileClose(handle);

}

 

double Point

返回当前图表的点值

示例:

OrderSend(Symbol(),OP_BUY,Lots,Ask,3,0,Ask+TakeProfit*Point,Red);

 

datetime Time[]

返回指定索引位置的时间

示例:

int handle, bars=Bars;

handle=FileOpen("file.csv", FILE_CSV|FILE_WRITE, ';');

if(handle>0)

{

// write table columns headers

FileWrite(handle, "Time;Open;High;Low;Close;Volume");

// write data

for(int i=0; i

FileWrite(handle, Time[i], Open[i], High[i], Low[i], Close[i], Volume[i]);

FileClose(handle);

}

 

double Volume[]

返回指定索引位置的成交量

示例:

int handle, bars=Bars;

handle=FileOpen("file.csv", FILE_CSV|FILE_WRITE, ';');

if(handle>0)

{

// write table columns headers

FileWrite(handle, "Time;Open;High;Low;Close;Volume");

// erite data

for(int i=0; i

FileWrite(handle, Time[i], Open[i], High[i], Low[i], Close[i], Volume[i]);

FileClose(handle);

)

字符串函数 [String Functions]

string StringConcatenate( ... ) 

字符串连接

:: 输入参数

... - 任意值,用逗号分割

示例:

string text;

text=StringConcatenate("Account free margin is ", AccountFreeMargin(), "Current time is ", TimeToStr(CurTime()));

// slow text="Account free margin is " + AccountFreeMargin() + "Current time is " + TimeToStr(CurTime())

Print(text);

 

int StringFind( string text, string matched_text, int start=0)

在字符串中寻找符合条件的字符串返回索引位置

:: 输入参数

text - 被搜索的字符串 

matched_text - 需要搜索的字符串

start - 搜索开始索引位置

示例:

string text="The quick brown dog jumps over the lazy fox";

int index=StringFind(text, "dog jumps", 0);

if(index!=16)

Print("oops!");

 

int StringGetChar( string text, int pos)

取字符串中的某一个字符

:: 输入参数

text - 字符串 

pos - 取字符的位置

示例:

int char_code=StringGetChar("abcdefgh", 3);

// char code 'c' is 99

 

int StringLen( string text)

返回字符串长度

:: 输入参数

text - 字符串

示例:

string str="some text";

if(StringLen(str)<5) return(0);

 

string StringSetChar( string text, int pos, int value)

在字符串中设置一个字符

:: 输入参数

text - 字符串 

pos - 设置字符的位置

value - 新的字符

示例:

string str="abcdefgh";

string str1=StringSetChar(str, 3, 'D');

// str1 is "abcDefgh"

 

string StringSubstr( string text, int start, int count=EMPTY)

从字符串中截取一段字符串

:: 输入参数

text - 字符串 

start - 开始索引位置

count - 截取字符数

示例:

string text="The quick brown dog jumps over the lazy fox";

string substr=StringSubstr(text, 4, 5);

// subtracted string is "quick" word

 

string StringTrimLeft( string text)

字符串左侧去空格

:: 输入参数

text - 字符串

示例:

string str1=" Hello world ";

string str2=StringTrimLeft(str);

// after trimming the str2 variable will be "Hello World "

 

string StringTrimRight( string text)

字符串右侧去空格

:: 输入参数

text - 字符串

示例:

string str1=" Hello world ";

string str2=StringTrimRight(str);

// after trimming the str2 variable will be " Hello World"

第八节 帐户信息

账户信息 [Account Information]

double AccountBalance()

返回账户余额

示例:

Print("Account balance = ",AccountBalance());

 

double AccountCredit()

返回账户信用点数

示例:

Print("Account number ", AccountCredit());

 

string AccountCompany()

返回账户公司名

示例:

Print("Account company name ", AccountCompany());

 

string AccountCurrency()

返回账户所用的通货名称

示例:

Print("account currency is ", AccountCurrency());

 

double AccountEquity()

返回资产净值

示例:

Print("Account equity = ",AccountEquity());

 

double AccountFreeMargin()

Returns free margin value of the current account.

示例:

Print("Account free margin = ",AccountFreeMargin());

 

int AccountLeverage()

返回杠杆比率

示例:

Print("Account #",AccountNumber(), " leverage is ", AccountLeverage());

 

double AccountMargin()

Returns margin value of the current account.

示例:

Print("Account margin ", AccountMargin());

 

string AccountName()

返回账户名称

示例:

Print("Account name ", AccountName());

 

int AccountNumber()

返回账户数字

示例:

Print("account number ", AccountNumber());

 

double AccountProfit()

返回账户利润

示例:

Print("Account profit ", AccountProfit());

第九节 数组函数

数组函数 [Array Functions]

int ArrayBsearch( double array[], double value, int count=WHOLE_ARRAY, int start=0, int direction=MODE_ASCEND)

搜索一个值在数组中的位置

此函数不能用在字符型或连续数字的数组上.

:: 输入参数

array[] - 需要搜索的数组

value - 将要搜索的值 

count - 搜索的数量,默认搜索所有的数组

start - 搜索的开始点,默认从头开始

direction - 搜索的方向,MODE_ASCEND 顺序搜索 MODE_DESCEND 倒序搜索

示例:

datetime daytimes[];

int shift=10,dayshift;

// All the Time[] timeseries are sorted in descendant mode

ArrayCopySeries(daytimes,MODE_TIME,Symbol(),PERIOD_D1);

if(Time[shift]&gt>=daytimes[0]) dayshift=0;

else

{

dayshift=ArrayBsearch(daytimes,Time[shift],WHOLE_ARRAY,0,MODE_DESCEND);

if(Period()<PERIOD_D1)

dayshift++;

}

Print(TimeToStr(Time[shift])," corresponds to ",dayshift," day bar opened at ",

TimeToStr(daytimes[dayshift]));

 

int ArrayCopy( object& dest[], object source[], int start_dest=0, int start_source=0, int count=WHOLE_ARRAY)

复制一个数组到另外一个数组。

只有double[], int[], datetime[], color[], 和 bool[] 这些类型的数组可以被复制。

:: 输入参数

dest[] - 目标数组 

source[] - 源数组 

start_dest - 从目标数组的第几位开始写入,默认为0

start_source - 从源数组的第几位开始读取,默认为0

count - 读取多少位的数组

示例:

double array1[][6];

double array2[10][6];

// fill array with some data

ArrayCopyRates(array1);

ArrayCopy(array2, array1,0,Bars-9,10);

// now array2 has first 10 bars in the history

 

int ArrayCopyRates( double& dest_array[], string symbol=NULL, int timeframe=0)

复制一段走势图上的数据到一个二维数组,数组的第二维只有6个项目分别是:

0 - 时间,

1 - 开盘价,

2 - 最低价,

3 - 最高价,

4 - 收盘价,

5 - 成交量.

:: 输入参数

dest_array[] - 目标数组

symbol - 标示,当前所需要的通货的标示

timeframe - 图表的时间线

示例:

double array1[][6];

ArrayCopyRates(array1,"EURUSD", PERIOD_H1);

Print("Current bar ",TimeToStr(array1[0][0]),"Open", array1[0][1]);

 

int ArrayCopySeries( double& array[], int series_index, string symbol=NULL, int timeframe=0)

复制一个系列的走势图数据到数组上

注: 如果series_index是MODE_TIME, 那么第一个参数必须是日期型的数组

:: 输入参数

dest_array[] - 目标数组

series_index - 想要取的系列的名称或编号,0-5

symbol - 标示,当前所需要的通货的标示

timeframe - 图表的时间线

示例:

datetime daytimes[];

int shift=10,dayshift;

// All the Time[] timeseries are sorted in descendant mode

ArrayCopySeries(daytimes,MODE_TIME,Symbol(),PERIOD_D1);

if(Time[shift]>=daytimes[0]) dayshift=0;

else

{

dayshift=ArrayBsearch(daytimes,Time[shift],WHOLE_ARRAY,0,MODE_DESCEND);

if(Period()

}

Print(TimeToStr(Time[shift])," corresponds to ",dayshift," day bar opened at ", TimeToStr(daytimes[dayshift]));

 

int ArrayDimension( int array[])

返回数组的维数

:: 输入参数

array[] - 需要检查的数组

示例:

int num_array[10][5];

int dim_size;

dim_size=ArrayDimension(num_array);

// dim_size is 2

 

bool ArrayGetAsSeries(object array[])

检查数组是否是有组织序列的数组(是否从最后到最开始排序过的),如果不是返回否

:: 输入参数

array[] - 需要检查的数组

示例:

if(ArrayGetAsSeries(array1)==true)

Print("array1 is indexed as a series array");

else

Print("array1 is indexed normally (from left to right)");

 

int ArrayInitialize( double& array[], double value)

对数组进行初始化,返回经过初始化的数组项的个数

:: 输入参数

array[] - 需要初始化的数组

value - 新的数组项的值

示例:

//---- 把所有数组项的值设置为2.1

double myarray[10];

ArrayInitialize(myarray,2.1);

 

bool ArrayIsSeries( object array[])

检查数组是否连续的(time,open,close,high,low, or volume).

:: 输入参数

array[] - 需要检查的数组

示例:

if(ArrayIsSeries(array1)==false)

ArrayInitialize(array1,0);

else

{

Print("Series array cannot be initialized!");

return(-1);

}

 

int ArrayMaximum( double array[], int count=WHOLE_ARRAY, int start=0)

找出数组中最大值的定位

:: 输入参数

array[] - 需要检查的数组

count - 搜索数组中项目的个数

start - 搜索的开始点

示例:

double num_array[15]={4,1,6,3,9,4,1,6,3,9,4,1,6,3,9};

int maxValueIdx=ArrayMaximum(num_array);

Print("Max value = ", num_array[maxValueIdx]);

 

int ArrayMinimum( double array[], int count=WHOLE_ARRAY, int start=0)

找出数组中最小值的定位

:: 输入参数

array[] - 需要检查的数组

count - 搜索数组中项目的个数

start - 搜索的开始点

示例:

double num_array[15]={4,1,6,3,9,4,1,6,3,9,4,1,6,3,9};

double minValueidx=ArrayMinimum(num_array);

Print("Min value = ", num_array[minValueIdx]);

 

int ArrayRange( object array[], int range_index)

取数组中指定维数中项目的数量。

:: 输入参数

array[] - 需要检查的数组

range_index - 指定的维数

示例:

int dim_size;

double num_array[10,10,10];

dim_size=ArrayRange(num_array, 1);

 

int ArrayResize( object& array[], int new_size)

重定义数组大小

:: 输入参数

array[] - 需要检查的数组

new_size - 第一维中数组的新大小

示例:

double array1[][4];

int element_count=ArrayResize(array, 20);

// 数组中总项目数为80

 

bool ArraySetAsSeries( double& array[], bool set)

设置指数数组为系列数组,数组0位的值是最后的值。返回之前的数组状态

:: 输入参数

array[] - 需要处理的数组

set - 是否是设置为系列数组,true或者false

示例:

double macd_buffer[300];

double signal_buffer[300];

int i,limit=ArraySize(macd_buffer);

ArraySetAsSeries(macd_buffer,true);

for(i=0; i

 

macd_buffer[i]=iMA(NULL,0,12,0,MODE_EMA,PRICE_CLOSE,i)-iMA(NULL,0,26,0,MODE_EMA,PRICE_CLOSE,i);

for(i=0; i

signal_buffer[i]=iMAOnArray(macd_buffer,limit,9,0,MODE_SMA,i);

 

int ArraySize( object array[])

返回数组的项目数

:: 输入参数

array[] - 需要处理的数组

示例:

int count=ArraySize(array1);

for(int i=0; i

{

// do some calculations.

}

 

int ArraySort( double& array[], int count=WHOLE_ARRAY, int start=0, int sort_dir=MODE_ASCEND)

对数组进行排序,系列数组不可进行排序

:: 输入参数

array[] - 需要处理的数组

count - 对多少个数组项进行排序

start - 排序的开始点

sort_dir - 排序方式,MODE_ASCEND顺序排列 MODE_DESCEND倒序排列

示例:

double num_array[5]={4,1,6,3,9};

// now array contains values 4,1,6,3,9

ArraySort(num_array);

// now array is sorted 1,3,4,6,9

ArraySort(num_array,MODE_DESCEND);

// now array is sorted 9,6,4,3,1

类型转换函数 [Conversion Functions]

string CharToStr( int char_code) 

将字符型转换成字符串型结果返回

:: 输入参数

char_code - 字符的ACSII码

示例:

string str="WORL" + CharToStr(44); // 44 is code for 'D'

// resulting string will be WORLD

 

string DoubleToStr( double value, int digits)

将双精度浮点型转换成字符串型结果返回

:: 输入参数

value - 浮点型数字

digits - 小数点后多少位,0-8

示例:

string value=DoubleToStr(1.28473418, 5);

// value is 1.28473

 

double NormalizeDouble( double value, int digits)

将双精度浮点型格式化后结果返回

:: 输入参数

value - 浮点型数字

digits - 小数点后多少位,0-8

示例:

double var1=0.123456789;

Print(NormalizeDouble(var1,5));

// output: 0.12346

 

double StrToDouble( string value)

将字符串型转换成双精度浮点型结果返回

:: 输入参数

value - 数字的字符串

示例:

double var=StrToDouble("103.2812");

 

int StrToInteger( string value)

将字符串型转换成整型结果返回

:: 输入参数

value - 数字的字符串

示例:

int var1=StrToInteger("1024");

 

datetime StrToTime( string value)

将字符串型转换成时间型结果返回,输入格式为 yyyy.mm.dd hh:mi

:: 输入参数

value - 时间的字符串

示例:

datetime var1;

var1=StrToTime("2003.8.12 17:35");

var1=StrToTime("17:35"); // returns with current date

var1=StrToTime("2003.8.12"); // returns with midnight time "00:00"

 

string TimeToStr( datetime value, int mode=TIME_DATE|TIME_MINUTES)

将时间型转换成字符串型返回

:: 输入参数

value - 时间的数字,从1970.1.1 0:0:0 到现在的秒数

mode - 返回字符串的格式TIME_DATE(yyyy.mm.dd),TIME_MINUTES(hh:mi),TIME_SECONDS(hh:mi:ss)

示例:

strign var1=TimeToStr(CurTime(),TIME_DATE|TIME_SECONDS);

第十节 公用函数

公用函数 [Common Functions]

void Alert( ... ) 

弹出一个显示信息的警告窗口

:: 输入参数

... - 任意值,如有多个可用逗号分割

示例:

if(Close[0]>SignalLevel)

Alert("Close price coming ", Close[0],"!!!");

 

string ClientTerminalName()

返回客户终端名称

示例:

Print("Terminal name is ",ClientTerminalName());

 

string CompanyName()

返回公司名称

示例:

Print("Company name is ",CompanyName());

 

void Comment( ... )

显示信息在走势图左上角

:: 输入参数

... - 任意值,如有多个可用逗号分割

示例:

double free=AccountFreeMargin();

Comment("Account free margin is ",DoubleToStr(free,2),"\n","Current time is ",TimeToStr(CurTime()));

 

int GetLastError()

取最后错误在错误中的索引位置

示例:

int err;

int handle=FileOpen("somefile.dat", FILE_READ|FILE_BIN);

if(handle<1)

{

err=GetLastError();

Print("error(",err,"): ",ErrorDescription(err));

return(0);

}

 

int GetTickCount()

取时间标记,函数取回用毫秒标示的时间标记。

示例:

int start=GetTickCount();

// do some hard calculation...

Print("Calculation time is ", GetTickCount()-start, " milliseconds.");

 

void HideTestIndicators(bool hide)

使用此函数设置一个在Expert Advisor的开关,在测试完成之前指标不回显示在图表上。

:: 输入参数

hide - 是否隐藏 True或者False

示例:

HideTestIndicators(true);

 

bool IsConnected()

返回客户端是否已连接

示例:

if(!IsConnected())

{

Print("Connection is broken!");

return(0);

}

// Expert body that need opened connection

// ...

 

bool IsDemo()

返回是否是模拟账户

示例:

if(IsDemo()) Print("I am working on demo account");

else Print("I am working on real account");

 

bool IsDllsAllowed()

返回是否允许载入Dll文件

示例:

#import "user32.dll"

int MessageBoxA(int hWnd ,string szText, string szCaption,int nType);

...

...

if(IsDllsAllowed()==false)

{

Print("DLL call is not allowed. Experts cannot run.");

return(0);

}

// expert body that calls external DLL functions

MessageBoxA(0,"an message","Message",MB_OK);

 

bool IsLibrariesAllowed()

返回是否允许载入库文件

示例:

#import "somelibrary.ex4"

int somefunc();

...

...

if(IsLibrariesAllowed()==false)

{

Print("Library call is not allowed. Experts cannot run.");

return(0);

}

// expert body that calls external DLL functions

somefunc();

 

bool IsStopped()

返回是否处于停止状态

示例:

while(expr!=false)

{

if(IsStopped()==true) return(0);

// long time procesing cycle

// ...

}

 

bool IsTesting()

返回是否处于测试模式

示例:

if(IsTesting()) Print("I am testing now");

 

bool IsTradeAllowed()

返回是否允许交易

示例:

if(IsTradeAllowed()) Print("Trade allowed");

 

double MarketInfo( string symbol, int type)

返回市场当前情况

:: 输入参数

symbol - 通货代码

type - 返回结果的类型

示例:

double var;

var=MarketInfo("EURUSD",MODE_BID);

 

int MessageBox( string text=NULL, string caption=NULL, int flags=EMPTY)

弹出消息窗口,返回消息窗口的结果

:: 输入参数

text - 窗口显示的文字

caption - 窗口上显示的标题

flags - 窗口选项开关

示例:

#include

if(ObjectCreate("text_object", OBJ_TEXT, 0, D'2004.02.20 12:30', 1.0045)==false)

{

int ret=MessageBox("ObjectCreate() fails with code "+GetLastError()+"\nContinue?", "Question", MB_YESNO|MB_ICONQUESTION);

if(ret==IDNO) return(false);

}

// continue

 

int Period()

返回图表时间线的类型

示例:

Print("Period is ", Period());

 

void PlaySound( string filename)

播放音乐文件

:: 输入参数

filename - 音频文件名

示例:

if(IsDemo()) PlaySound("alert.wav");

 

void Print( ... )

将文本打印在结果窗口内

:: 输入参数

... - 任意值,复数用逗号分割

示例:

Print("Account free margin is ", AccountFreeMargin());

Print("Current time is ", TimeToStr(CurTime()));

double pi=3.141592653589793;

Print("PI number is ", DoubleToStr(pi,8));

// Output: PI number is 3.14159265

// Array printing

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

Print(Close[i]);

 

bool RefreshRates()

返回数据是否已经被刷新过了

示例:

int ticket;

while(true)

{

ticket=OrderSend(Symbol(),OP_BUY,1.0,Ask,3,0,0,"expert comment",255,0,CLR_NONE);

if(ticket<=0)

{

int error=GetLastError();

if(error==134) break; // not enough money

if(error==135) RefreshRates(); // prices changed

break;

}

else { OrderPrint(); break; }

//---- 10 seconds wait

Sleep(10000);

}

 

void SendMail( string subject, string some_text)

发送邮件到指定信箱,需要到菜单 Tools -> Options -> Email 中将邮件打开.

:: 输入参数

subject - 邮件标题

some_text - 邮件内容

示例:

double lastclose=Close[0];

if(lastclose<MY_SIGNAL)

SendMail("from your expert", "Price dropped down to "+DoubleToStr(lastclose));

 

string ServerAddress()

返回服务器地址

示例:

Print("Server address is ", ServerAddress());

 

void Sleep( int milliseconds)

设置线程暂停时间

:: 输入参数

milliseconds - 暂停时间 1000 = 1秒

示例:

Sleep(5);

 

void SpeechText( string text, int lang_mode=SPEECH_ENGLISH)

使用Speech进行语音输出

:: 输入参数

text - 阅读的文字

lang_mode - 语音模式 SPEECH_ENGLISH (默认的) 或 SPEECH_NATIVE

示例:

double lastclose=Close[0];

SpeechText("Price dropped down to "+DoubleToStr(lastclose));

 

string Symbol()

返回当前当前通货的名称

示例:

int total=OrdersTotal();

for(int pos=0;pos<TOTAL;POS++)

{

// check selection result becouse order may be closed or deleted at this time!

if(OrderSelect(pos, SELECT_BY_POS)==false) continue;

if(OrderType()>OP_SELL || OrderSymbol()!=Symbol()) continue;

// do some orders processing...

}

 

int UninitializeReason()

取得程序末初始化的理由

示例:

// this is example

int deinit()

{

switch(UninitializeReason())

{

case REASON_CHARTCLOSE:

case REASON_REMOVE: CleanUp(); break; // clean up and free all expert's resources.

case REASON_RECOMPILE:

case REASON_CHARTCHANGE:

case REASON_PARAMETERS:

case REASON_ACCOUNT: StoreData(); break; // prepare to restart

}

//...

}

第十一节 自定义函数

自定义指标函数 [Custom Indicator Functions]

void IndicatorBuffers(int count)

设置自定义指标缓存数

:: 输入参数

count - 缓存数量

示例:

#property indicator_separate_window

#property indicator_buffers 1

#property indicator_color1 Silver

//---- indicator parameters

extern int FastEMA=12;

extern int SlowEMA=26;

extern int SignalSMA=9;

//---- indicator buffers

double ind_buffer1[];

double ind_buffer2[];

double ind_buffer3[];

//+------------------------------------------------------------------+

//| Custom indicator initialization function |

//+------------------------------------------------------------------+

int init()

{

//---- 2 additional buffers are used for counting.

IndicatorBuffers(3);

//---- drawing settings

SetIndexStyle(0,DRAW_HISTOGRAM,STYLE_SOLID,3);

SetIndexDrawBegin(0,SignalSMA);

IndicatorDigits(MarketInfo(Symbol(),MODE_DIGITS)+2);

//---- 3 indicator buffers mapping

SetIndexBuffer(0,ind_buffer1);

SetIndexBuffer(1,ind_buffer2);

SetIndexBuffer(2,ind_buffer3);

//---- name for DataWindow and indicator subwindow label

IndicatorShortName("OsMA("+FastEMA+","+SlowEMA+","+SignalSMA+")");

//---- initialization done

return(0);

}

 

int IndicatorCounted()

返回缓存数量

示例:

int start()

{

int limit;

int counted_bars=IndicatorCounted();

//---- check for possible errors

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

//---- last counted bar will be recounted

if(counted_bars>0) counted_bars--;

limit=Bars-counted_bars;

//---- main loop

for(int i=0; i

 

{

//---- ma_shift set to 0 because SetIndexShift called abowe

ExtBlueBuffer[i]=iMA(NULL,0,JawsPeriod,0,MODE_SMMA,PRICE_MEDIAN,i);

ExtRedBuffer[i]=iMA(NULL,0,TeethPeriod,0,MODE_SMMA,PRICE_MEDIAN,i);

ExtLimeBuffer[i]=iMA(NULL,0,LipsPeriod,0,MODE_SMMA,PRICE_MEDIAN,i);

}

//---- done

return(0);

}

 

void IndicatorDigits( int digits)

设置指标精确度

:: 输入参数

digits - 小数点后的小数位数

示例:

#property indicator_separate_window

#property indicator_buffers 1

#property indicator_color1 Silver

//---- indicator parameters

extern int FastEMA=12;

extern int SlowEMA=26;

extern int SignalSMA=9;

//---- indicator buffers

double ind_buffer1[];

double ind_buffer2[];

double ind_buffer3[];

//+------------------------------------------------------------------+

//| Custom indicator initialization function |

//+------------------------------------------------------------------+

int init()

{

//---- 2 additional buffers are used for counting.

IndicatorBuffers(3);

//---- drawing settings

SetIndexStyle(0,DRAW_HISTOGRAM,STYLE_SOLID,3);

SetIndexDrawBegin(0,SignalSMA);

IndicatorDigits(MarketInfo(Symbol(),MODE_DIGITS)+2);

//---- 3 indicator buffers mapping

SetIndexBuffer(0,ind_buffer1);

SetIndexBuffer(1,ind_buffer2);

SetIndexBuffer(2,ind_buffer3);

//---- name for DataWindow and indicator subwindow label

IndicatorShortName("OsMA("+FastEMA+","+SlowEMA+","+SignalSMA+")");

//---- initialization done

return(0);

}

 

void IndicatorShortName( string name)

设置指标的简称

:: 输入参数

name - 新的简称

示例:

#property indicator_separate_window

#property indicator_buffers 1

#property indicator_color1 Silver

//---- indicator parameters

extern int FastEMA=12;

extern int SlowEMA=26;

extern int SignalSMA=9;

//---- indicator buffers

double ind_buffer1[];

double ind_buffer2[];

double ind_buffer3[];

//+------------------------------------------------------------------+

//| Custom indicator initialization function |

//+------------------------------------------------------------------+

int init()

{

//---- 2 additional buffers are used for counting.

IndicatorBuffers(3);

//---- drawing settings

SetIndexStyle(0,DRAW_HISTOGRAM,STYLE_SOLID,3);

SetIndexDrawBegin(0,SignalSMA);

IndicatorDigits(MarketInfo(Symbol(),MODE_DIGITS)+2);

//---- 3 indicator buffers mapping

SetIndexBuffer(0,ind_buffer1);

SetIndexBuffer(1,ind_buffer2);

SetIndexBuffer(2,ind_buffer3);

//---- name for DataWindow and indicator subwindow label

IndicatorShortName("OsMA("+FastEMA+","+SlowEMA+","+SignalSMA+")");

//---- initialization done

return(0);

}

 

void SetIndexArrow( int index, int code)

在指标上设置一个箭头符号

:: 输入参数

index - 第几根指标线 0-7

code - 符号的编码,参照 Wingdings 字体

示例:

SetIndexArrow(0, 217);

 

bool SetIndexBuffer( int index, double array[])

设置指标线的缓存数组

:: 输入参数

index - 第几根指标线 0-7

array[] - 缓存的数组

示例:

double ExtBufferSilver[];

int init()

{

SetIndexBuffer(0, ExtBufferSilver); // set buffer for first line

// ...

}

 

void SetIndexDrawBegin( int index, int begin)

设置划线的开始点

:: 输入参数

index - 第几根指标线 0-7

begin - 划线的开始点

示例:

#property indicator_separate_window

#property indicator_buffers 1

#property indicator_color1 Silver

//---- indicator parameters

extern int FastEMA=12;

extern int SlowEMA=26;

extern int SignalSMA=9;

//---- indicator buffers

double ind_buffer1[];

double ind_buffer2[];

double ind_buffer3[];

//+------------------------------------------------------------------+

//| Custom indicator initialization function |

//+------------------------------------------------------------------+

int init()

{

//---- 2 additional buffers are used for counting.

IndicatorBuffers(3);

//---- drawing settings

SetIndexStyle(0,DRAW_HISTOGRAM,STYLE_SOLID,3);

SetIndexDrawBegin(0,SignalSMA);

IndicatorDigits(MarketInfo(Symbol(),MODE_DIGITS)+2);

//---- 3 indicator buffers mapping

SetIndexBuffer(0,ind_buffer1);

SetIndexBuffer(1,ind_buffer2);

SetIndexBuffer(2,ind_buffer3);

//---- name for DataWindow and indicator subwindow label

IndicatorShortName("OsMA("+FastEMA+","+SlowEMA+","+SignalSMA+")");

//---- initialization done

return(0);

}

 

void SetIndexEmptyValue( int index, double value)

设置划线的空值,空值不划在和出现在数据窗口

:: 输入参数

index - 第几根指标线 0-7

value - 新的空值

示例:

SetIndexEmptyValue(6,0.0001);

 

void SetIndexLabel( int index, string text)

设置指标线的名称

:: 输入参数

index - 第几根指标线 0-7

text - 线的名称,Null不会显示在数据窗口中

示例:

//+------------------------------------------------------------------+

//| Ichimoku Kinko Hyo initialization function |

//+------------------------------------------------------------------+

int init()

{

//----

SetIndexStyle(0,DRAW_LINE);

SetIndexBuffer(0,Tenkan_Buffer);

SetIndexDrawBegin(0,Tenkan-1);

SetIndexLabel(0,"Tenkan Sen");

//----

SetIndexStyle(1,DRAW_LINE);

SetIndexBuffer(1,Kijun_Buffer);

SetIndexDrawBegin(1,Kijun-1);

SetIndexLabel(1,"Kijun Sen");

//----

a_begin=Kijun; if(a_begin SetIndexStyle(2,DRAW_HISTOGRAM,STYLE_DOT);

SetIndexBuffer(2,SpanA_Buffer);

SetIndexDrawBegin(2,Kijun+a_begin-1);

SetIndexShift(2,Kijun);

//---- Up Kumo bounding line does not show in the DataWindow

SetIndexLabel(2,NULL);

SetIndexStyle(5,DRAW_LINE,STYLE_DOT);

SetIndexBuffer(5,SpanA2_Buffer);

SetIndexDrawBegin(5,Kijun+a_begin-1);

SetIndexShift(5,Kijun);

SetIndexLabel(5,"Senkou Span A");

//----

SetIndexStyle(3,DRAW_HISTOGRAM,STYLE_DOT);

SetIndexBuffer(3,SpanB_Buffer);

SetIndexDrawBegin(3,Kijun+Senkou-1);

SetIndexShift(3,Kijun);

//---- Down Kumo bounding line does not show in the DataWindow

SetIndexLabel(3,NULL);

//----

SetIndexStyle(6,DRAW_LINE,STYLE_DOT);

SetIndexBuffer(6,SpanB2_Buffer);

SetIndexDrawBegin(6,Kijun+Senkou-1);

SetIndexShift(6,Kijun);

SetIndexLabel(6,"Senkou Span B");

//----

SetIndexStyle(4,DRAW_LINE);

SetIndexBuffer(4,Chinkou_Buffer);

SetIndexShift(4,-Kijun);

SetIndexLabel(4,"Chinkou Span");

//----

return(0);

}

 

void SetIndexShift( int index, int shift)

设置指标线的位移数

:: 输入参数

index - 第几根指标线 0-7

shift - 位移多少

示例:

//+------------------------------------------------------------------+

//| Alligator initialization function |

//+------------------------------------------------------------------+

int init()

{

//---- line shifts when drawing

SetIndexShift(0,JawsShift);

SetIndexShift(1,TeethShift);

SetIndexShift(2,LipsShift);

//---- first positions skipped when drawing

SetIndexDrawBegin(0,JawsShift+JawsPeriod);

SetIndexDrawBegin(1,TeethShift+TeethPeriod);

SetIndexDrawBegin(2,LipsShift+LipsPeriod);

//---- 3 indicator buffers mapping

SetIndexBuffer(0,ExtBlueBuffer);

SetIndexBuffer(1,ExtRedBuffer);

SetIndexBuffer(2,ExtLimeBuffer);

//---- drawing settings

SetIndexStyle(0,DRAW_LINE);

SetIndexStyle(1,DRAW_LINE);

SetIndexStyle(2,DRAW_LINE);

//---- index labels

SetIndexLabel(0,"Gator Jaws");

SetIndexLabel(1,"Gator Teeth");

SetIndexLabel(2,"Gator Lips");

//---- initialization done

return(0);

}

 

void SetIndexStyle( int index, int type, int style=EMPTY, int width=EMPTY, color clr=CLR_NONE)

设置指标线的样式

:: 输入参数

index - 第几根指标线 0-7

type - 线形状的种类,详见线条种类

style - 划线的样式

width - 显得宽度(1,2,3,4,5)

clr - 线的颜色

示例:

SetIndexStyle(3, DRAW_LINE, EMPTY, 2, Red);

第十二节 时间函数

日期时间函数 [Date & Time Functions]    

datetime CurTime( )

返回当前时间

示例:

if(CurTime()-OrderOpenTime()<360) return(0);

 

int Day()

返回当前日期

示例:

if(Day()<5) return(0);

 

int DayOfWeek( )

返回当前日期是星期几 0-星期天,1,2,3,4,5,6

示例:

// do not work on holidays.

if(DayOfWeek()==0 || DayOfWeek()==6) return(0);

 

int DayOfYear( )

返回当前日期在年内的第几天

示例:

if(DayOfYear()==245)

return(true);

 

int Hour()

返回当前的小时数 0-23

示例:

bool is_siesta=false;

if(Hour()>=12 || Hour()<17)

is_siesta=true;

 

datetime LocalTime()

返回当前电脑时间

示例:

if(LocalTime()-OrderOpenTime()<360) return(0);

 

int Minute()

返回当前分钟

示例:

if(Minute()<=15)

return("first quarter");

 

int Month()

返回当前月份

示例:

if(Month()<=5)

return("first half of year");

 

int Seconds()

返回当前秒数

示例:

if(Seconds()<=15)

return(0);

 

int TimeDay( datetime date)

返回输入日期中的日期

:: 输入参数

date - 输入日期

示例:

int day=TimeDay(D'2003.12.31');

// day is 31

 

int TimeDayOfWeek( datetime date)

返回输入日期中的日期是星期几 (0-6)

:: 输入参数

date - 输入日期

示例:

int weekday=TimeDayOfWeek(D'2004.11.2');

// day is 2 - tuesday

 

int TimeDayOfYear( datetime date)

返回输入日期中的日期在当年中的第几天

:: 输入参数

date - 输入日期

示例:

int day=TimeDayOfYear(CurTime());

 

int TimeHour( datetime time)

返回输入日期中的小时

:: 输入参数

date - 输入日期

示例:

int h=TimeHour(CurTime());

 

int TimeMinute( datetime time)

返回输入日期中的分钟

:: 输入参数

date - 输入日期

示例:

int m=TimeMinute(CurTime());

 

int TimeMonth( datetime time)

返回输入日期中的月份

:: 输入参数

date - 输入日期

示例:

int m=TimeMonth(CurTime());

 

int TimeSeconds( datetime time)

返回输入日期中的秒钟

:: 输入参数

date - 输入日期

示例:

int m=TimeSeconds(CurTime());

 

int TimeYear( datetime time)

返回输入日期中的年份

:: 输入参数

date - 输入日期

示例:

int y=TimeYear(CurTime());

 

int TimeYear( datetime time)

返回当前年份

示例:

// return if date before 1 May 2002

if(Year()==2002 && Month()<5)

return(0);

第十三节 文件函数

文件处理函数 [File Functions]

void FileClose(int handle)

关闭正在已经打开的文件.

:: 输入参数

handle - FileOpen()返回的句柄

示例:

int handle=FileOpen("filename", FILE_CSV|FILE_READ);

if(handle>0)

{

// working with file ...

FileClose(handle);

}

 

void FileDelete(string filename)

删除文件,如果发生错误可以通过GetLastError()来查询

注:你只能操作terminal_dir\experts\files目录下的文件

:: 输入参数

filename - 目录和文件名

示例:

// file my_table.csv will be deleted from terminal_dir\experts\files directory

int lastError;

FileDelete("my_table.csv");

lastError=GetLastError();

if(laseError!=ERR_NOERROR)

{

Print("An error ocurred while (",lastError,") deleting file my_table.csv");

return(0);

}

 

void FileFlush(int handle)

将缓存中的数据刷新到磁盘上去

:: 输入参数

handle - FileOpen()返回的句柄

示例:

int bars_count=Bars;

int handle=FileOpen("mydat.csv",FILE_CSV|FILE_WRITE);

if(handle>0)

{

FileWrite(handle, "#","OPEN","CLOSE","HIGH","LOW");

for(int i=0;i<BARS_COUNT;I++)

FileWrite(handle, i+1,Open[i],Close[i],High[i], Low[i]);

FileFlush(handle);

...

for(int i=0;i<BARS_COUNT;I++)

FileWrite(handle, i+1,Open[i],Close[i],High[i], Low[i]);

FileClose(handle);

}

 

bool FileIsEnding(int handle)

检查是否到了文件尾.

:: 输入参数

handle - FileOpen()返回的句柄

示例:

if(FileIsEnding(h1))

{

FileClose(h1);

return(false);

}

 

bool FileIsLineEnding( int handle)

检查行是否到了结束

:: 输入参数

handle - FileOpen()返回的句柄

示例:

if(FileIsLineEnding(h1))

{

FileClose(h1);

return(false);

}

 

int FileOpen( string filename, int mode, int delimiter=';')

打开文件,如果失败返回值小于1,可以通过GetLastError()获取错误

注:只能操作terminal_dir\experts\files目录的文件

:: 输入参数

filename - 目录文件名

mode - 打开模式 FILE_BIN, FILE_CSV, FILE_READ, FILE_WRITE.

delimiter - CSV型打开模式用的分割符,默认为分号(;).

示例:

int handle;

handle=FileOpen("my_data.csv",FILE_CSV|FILE_READ,';');

if(handle<1)

{

Print("File my_data.dat not found, the last error is ", GetLastError());

return(false);

}

 

int FileOpenHistory( string filename, int mode, int delimiter=';')

打开历史数据文件,如果失败返回值小于1,可以通过GetLastError()获取错误

:: 输入参数

filename - 目录文件名

mode - 打开模式 FILE_BIN, FILE_CSV, FILE_READ, FILE_WRITE.

delimiter - CSV型打开模式用的分割符,默认为分号(;).

示例:

int handle=FileOpenHistory("USDX240.HST",FILE_BIN|FILE_WRITE);

if(handle<1)

{

Print("Cannot create file USDX240.HST");

return(false);

}

// work with file

// ...

FileClose(handle);

 

int FileReadArray( int handle, object& array[], int start, int count)

将二进制文件读取到数组中,返回读取的条数,可以通过GetLastError()获取错误

注:在读取之前要调整好数组大小

:: 输入参数

handle - FileOpen()返回的句柄

array[] - 写入的数组

start - 在数组中存储的开始点

count - 读取多少个对象

示例:

int handle;

double varray[10];

handle=FileOpen("filename.dat", FILE_BIN|FILE_READ);

if(handle>0)

{

FileReadArray(handle, varray, 0, 10);

FileClose(handle);

}

 

double FileReadDouble( int handle, int size=DOUBLE_VALUE)

从文件中读取浮点型数据,数字可以是8byte的double型或者是4byte的float型。

:: 输入参数

handle - FileOpen()返回的句柄

size - 数字个是大小,DOUBLE_VALUE(8 bytes) 或者 FLOAT_VALUE(4 bytes).

示例:

int handle;

double value;

handle=FileOpen("mydata.dat",FILE_BIN);

if(handle>0)

{

value=FileReadDouble(handle,DOUBLE_VALUE);

FileClose(handle);

}

 

int FileReadInteger( int handle, int size=LONG_VALUE)

从文件中读取整形型数据,数字可以是1,2,4byte的长度

:: 输入参数

handle - FileOpen()返回的句柄

size - 数字个是大小,CHAR_VALUE(1 byte), SHORT_VALUE(2 bytes) 或者 LONG_VALUE(4 bytes).

示例:

int handle;

int value;

handle=FileOpen("mydata.dat", FILE_BIN|FILE_READ);

if(handle>0)

{

value=FileReadInteger(h1,2);

FileClose(handle);

}

 

double FileReadNumber( int handle)

从文件中读取数字,只能在CSV里使用

:: 输入参数

handle - FileOpen()返回的句柄

示例:

int handle;

int value;

handle=FileOpen("filename.csv", FILE_CSV, ';');

if(handle>0)

{

value=FileReadNumber(handle);

FileClose(handle);

}

 

string FileReadString( int handle, int length=0)

从文件中读取字符串

:: 输入参数

handle - FileOpen()返回的句柄

length - 读取字符串长度

示例:

int handle;

string str;

handle=FileOpen("filename.csv", FILE_CSV|FILE_READ);

if(handle>0)

{

str=FileReadString(handle);

FileClose(handle);

}

 

bool FileSeek( int handle, int offset, int origin)

移动指针移动到某一点,如果成功返回true

:: 输入参数

handle - FileOpen()返回的句柄

offset - 设置的原点

origin - SEEK_CUR从当前位置开始 SEEK_SET从文件头部开始 SEEK_END 从文件尾部开始

示例:

int handle=FileOpen("filename.csv", FILE_CSV|FILE_READ, ';');

if(handle>0)

{

FileSeek(handle, 10, SEEK_SET);

FileReadInteger(handle);

FileClose(handle);

handle=0;

}

 

int FileSize( int handle)

返回文件大小

:: 输入参数

handle - FileOpen()返回的句柄

示例:

int handle;

int size;

handle=FileOpen("my_table.dat", FILE_BIN|FILE_READ);

if(handle>0)

{

size=FileSize(handle);

Print("my_table.dat size is ", size, " bytes");

FileClose(handle);

}

 

int FileTell( int handle)

返回文件读写指针当前的位置

:: 输入参数

handle - FileOpen()返回的句柄

示例:

int handle;

int pos;

handle=FileOpen("my_table.dat", FILE_BIN|FILE_READ);

// reading some data

pos=FileTell(handle);

Print("current position is ", pos);

 

int FileWrite( int handle, ... )

向文件写入数据

:: 输入参数

handle - FileOpen()返回的句柄

... - 写入的数据

示例:

int handle;

datetime orderOpen=OrderOpenTime();

handle=FileOpen("filename", FILE_CSV|FILE_WRITE, ';');

if(handle>0)

{

FileWrite(handle, Close[0], Open[0], High[0], Low[0], TimeToStr(orderOpen));

FileClose(handle);

}

 

int FileWriteArray( int handle, object array[], int start, int count)

向文件写入数组

:: 输入参数

handle - FileOpen()返回的句柄

array[] - 要写入的数组

start - 写入的开始点

count - 写入的项目数

示例:

int handle;

double BarOpenValues[10];

// copy first ten bars to the array

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

BarOpenValues[i]=Open[i];

// writing array to the file

handle=FileOpen("mydata.dat", FILE_BIN|FILE_WRITE);

if(handle>0)

{

FileWriteArray(handle, BarOpenValues, 3, 7); // writing last 7 elements

FileClose(handle);

}

 

int FileWriteDouble( int handle, double value, int size=DOUBLE_VALUE)

向文件写入浮点型数据

:: 输入参数

handle - FileOpen()返回的句柄

value - 要写入的值

size - 写入的格式,DOUBLE_VALUE (8 bytes, default)或FLOAT_VALUE (4 bytes).

示例:

int handle;

double var1=0.345;

handle=FileOpen("mydata.dat", FILE_BIN|FILE_WRITE);

if(handle<1)

{

Print("can't open file error-",GetLastError());

return(0);

}

FileWriteDouble(h1, var1, DOUBLE_VALUE);

//...

FileClose(handle);

 

int FileWriteInteger( int handle, int value, int size=LONG_VALUE)

向文件写入整型数据

:: 输入参数

handle - FileOpen()返回的句柄

value - 要写入的值

size - 写入的格式,CHAR_VALUE (1 byte),SHORT_VALUE (2 bytes),LONG_VALUE (4 bytes, default).

示例:

int handle;

int value=10;

handle=FileOpen("filename.dat", FILE_BIN|FILE_WRITE);

if(handle<1)

{

Print("can't open file error-",GetLastError());

return(0);

}

FileWriteInteger(handle, value, SHORT_VALUE);

//...

FileClose(handle);

 

int FileWriteString( int handle, string value, int length)

向文件写入字符串数据

:: 输入参数

handle - FileOpen()返回的句柄

value - 要写入的值

length - 写入的字符长度

示例:

int handle;

string str="some string";

handle=FileOpen("filename.bin", FILE_BIN|FILE_WRITE);

if(handle<1)

{

Print("can't open file error-",GetLastError());

return(0);

}

FileWriteString(h1, str, 8);

FileClose(handle);

第十四节 全局变量函数

bool GlobalVariableCheck( string name)

检查全局变量是否存在 

:: 输入参数

name - 全局变量的名称

示例:

// check variable before use

if(!GlobalVariableCheck("g1"))

GlobalVariableSet("g1",1);

 

bool GlobalVariableDel( string name)

删除全局变量

:: 输入参数

name - 全局变量的名称

示例:

// deleting global variable with name "gvar_1"

GlobalVariableDel("gvar_1");

 

double GlobalVariableGet( string name)

获取全局变量的值

:: 输入参数

name - 全局变量的名称

示例:

double v1=GlobalVariableGet("g1");

//---- check function call result

if(GetLastError()!=0) return(false);

//---- continue processing

 

double GlobalVariableGet( string name)

获取全局变量的值

:: 输入参数

name - 全局变量的名称

示例:

double v1=GlobalVariableGet("g1");

//---- check function call result

if(GetLastError()!=0) return(false);

//---- continue processing

 

datetime GlobalVariableSet( string name, double value )

设置全局变量的值

:: 输入参数

name - 全局变量的名称

value - 全局变量的值

示例:

//---- try to set new value

if(GlobalVariableSet("BarsTotal",Bars)==0)

return(false);

//---- continue processing

 

bool GlobalVariableSetOnCondition( string name, double value, double check_value)

有条件的设置全局变量的值

:: 输入参数

name - 全局变量的名称

value - 全局变量的值

check_value - 检查变量的值

示例:

int init()

{

//---- create global variable

GlobalVariableSet("DATAFILE_SEM",0);

//...

}

int start()

{

//---- try to lock common resource

while(!IsStopped())

{

//---- locking

if(GlobalVariableSetOnCondition("DATAFILE_SEM",1,0)==true) break;

//---- may be variable deleted?

if(GetLastError()==ERR_GLOBAL_VARIABLE_NOT_FOUND) return(0);

//---- sleeping

Sleep(500);

}

//---- resource locked

// ... do some work

//---- unlock resource

GlobalVariableSet("DATAFILE_SEM",0);

}

 

void GlobalVariablesDeleteAll( )

删除所有全局变量

示例:

GlobalVariablesDeleteAll();

第十五节  数学运算函数

double MathAbs( double value) 

返回数字的绝对值 

:: 输入参数

value - 要处理的数字

示例:

double dx=-3.141593, dy;

// calc MathAbs

dy=MathAbs(dx);

Print("The absolute value of ",dx," is ",dy);

// Output: The absolute value of -3.141593 is 3.141593

 

double MathArccos( double x)

计算反余弦值

:: 输入参数

value - 要处理的数字,范围-1到1

示例:

double x=0.32696, y;

y=asin(x);

Print("Arcsine of ",x," = ",y);

y=acos(x);

Print("Arccosine of ",x," = ",y);

//Output: Arcsine of 0.326960=0.333085

//Output: Arccosine of 0.326960=1.237711

 

double MathArcsin( double x)

计算反正弦值

:: 输入参数

x - 要处理的值

示例:

double x=0.32696, y;

y=MathArcsin(x);

Print("Arcsine of ",x," = ",y);

y=acos(x);

Print("Arccosine of ",x," = ",y);

//Output: Arcsine of 0.326960=0.333085

//Output: Arccosine of 0.326960=1.237711

 

double MathArctan( double x)

计算反正切值

:: 输入参数

x - 要处理的值

示例:

double x=-862.42, y;

y=MathArctan(x);

Print("Arctangent of ",x," is ",y);

//Output: Arctangent of -862.42 is -1.5696

 

double MathCeil( double x)

返回向前进位后的值

:: 输入参数

x - 要处理的值

示例:

double y;

y=MathCeil(2.8);

Print("The ceil of 2.8 is ",y);

y=MathCeil(-2.8);

Print("The ceil of -2.8 is ",y);

 

 

double MathCos( double value)

计算余弦值

:: 输入参数

value - 要处理的值

示例:

double pi=3.1415926535;

double x, y;

x=pi/2;

y=MathSin(x);

Print("MathSin(",x,") = ",y);

y=MathCos(x);

Print("MathCos(",x,") = ",y);

//Output: MathSin(1.5708)=1

// MathCos(1.5708)=0

 

double MathExp( double d)

Returns value the number e raised to the power d. On overflow, the function returns INF (infinite) and on underflow, MathExp returns 0.

:: 输入参数

d - A number specifying a power.

示例:

double x=2.302585093,y;

y=MathExp(x);

Print("MathExp(",x,") = ",y);

//Output: MathExp(2.3026)=10

 

double MathFloor( double x)

返回向后进位后的值

:: 输入参数

x - 要处理的值

示例:

double y;

y=MathFloor(2.8);

Print("The floor of 2.8 is ",y);

y=MathFloor(-2.8);

Print("The floor of -2.8 is ",y);

 

 

double MathLog( double x)

计算对数

:: 输入参数

x - 要处理的值

示例:

double x=9000.0,y;

y=MathLog(x);

Print("MathLog(",x,") = ", y);

//Output: MathLog(9000)=9.10498

 

double MathMax( double value1, double value2)

计算两个值中的最大值

:: 输入参数

value1 - 第一个值 

value2 - 第二个值

示例:

double result=MathMax(1.08,Bid);

 

double MathMin( double value1, double value2)

计算两个值中的最小值

:: 输入参数

value1 - 第一个值 

value2 - 第二个值

示例:

double result=MathMin(1.08,Ask);

 

double MathMod( double value, double value2)

计算两个值相除的余数

:: 输入参数

value - 被除数 

value2 - 除数

示例:

double x=-10.0,y=3.0,z;

z=MathMod(x,y);

Print("The remainder of ",x," / ",y," is ",z);

//Output: The remainder of -10 / 3 is -1

 

double MathPow( double base, double exponent)

计算指数

:: 输入参数

base - 基数

exponent - 指数

示例:

double x=2.0,y=3.0,z;

z=MathPow(x,y);

Printf(x," to the power of ",y," is ", z);

//Output: 2 to the power of 3 is 8

 

int MathRand( )

取随机数

示例:

MathSrand(LocalTime());

// Display 10 numbers.

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

Print("random value ", MathRand());

 

double MathRound( double value)

取四舍五入的值

:: 输入参数

value - 要处理的值

示例:

double y=MathRound(2.8);

Print("The round of 2.8 is ",y);

y=MathRound(2.4);

Print("The round of -2.4 is ",y);

//Output: The round of 2.8 is 3

// The round of -2.4 is -2

 

double MathSin( double value)

计算正弦数

:: 输入参数

value - 要处理的值

示例:

double pi=3.1415926535;

double x, y;

x=pi/2;

y=MathSin(x);

Print("MathSin(",x,") = ",y);

y=MathCos(x);

Print("MathCos(",x,") = ",y);

//Output: MathSin(1.5708)=1

// MathCos(1.5708)=0

 

double MathSqrt( double x)

计算平方根

:: 输入参数

x - 要处理的值

示例:

double question=45.35, answer;

answer=MathSqrt(question);

if(question<0)

Print("Error: MathSqrt returns ",answer," answer");

else

Print("The square root of ",question," is ", answer);

//Output: The square root of 45.35 is 6.73

 

void MathSrand( int seed)

通过Seed产生随机数

:: 输入参数

seed - 随机数的种子

示例:

MathSrand(LocalTime());

// Display 10 numbers.

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

Print("random value ", MathRand());

 

double MathTan( double x)

计算正切值

:: 输入参数

x - 要计算的角度

示例:

double pi=3.1415926535;

double x,y;

x=MathTan(pi/4);

Print("MathTan(",pi/4," = ",x);

//Output: MathTan(0.7856)=1

第十五节 物体函数 [Object Functions]

bool ObjectCreate( string name, int type, int window, datetime time1, double price1, datetime time2=0, double price2=0, datetime time3=0, double price3=0)

创建物件 

:: 输入参数

name - 物件名称

type - 物件类型.

window - 物件所在窗口的索引值

time1 - 时间点1

price1 - 价格点1

time2 - 时间点2

price2 - 价格点2

time3 - 时间点3

price3 - 价格点3

示例:

// new text object

if(!ObjectCreate("text_object", OBJ_TEXT, 0, D'2004.02.20 12:30', 1.0045))

{

Print("error: can't create text_object! code #",GetLastError());

return(0);

}

// new label object

if(!ObjectCreate("label_object", OBJ_LABEL, 0, 0, 0))

{

Print("error: can't create label_object! code #",GetLastError());

return(0);

}

ObjectSet("label_object", OBJPROP_XDISTANCE, 200);

ObjectSet("label_object", OBJPROP_YDISTANCE, 100);

 

bool ObjectDelete( string name)

删除物件

:: 输入参数

name - 物件名称

示例:

ObjectDelete("text_object");

 

string ObjectDescription( string name)

返回物件描述

:: 输入参数

name - 物件名称

示例:

// writing chart's object list to the file

int handle, total;

string obj_name,fname;

// file name

fname="objlist_"+Symbol();

handle=FileOpen(fname,FILE_CSV|FILE_WRITE);

if(handle!=false)

{

total=ObjectsTotal();

for(int i=-;i<TOTAL;I++)

{

obj_name=ObjectName(i);

FileWrite(handle,"Object "+obj_name+" description= "+ObjectDescription(obj_name));

}

FileClose(handle);

}

 

int ObjectFind( string name)

寻找物件,返回物件的索引值

:: 输入参数

name - 物件名称

示例:

if(ObjectFind("line_object2")!=win_idx) return(0);

 

double ObjectGet( string name, int index)

获取物件的值

:: 输入参数

name - 物件名称

index - 取值属性的索引

示例:

color oldColor=ObjectGet("hline12", OBJPROP_COLOR);

 

string ObjectGetFiboDescription( string name, int index)

取物件的斐波纳契数列地描述

:: 输入参数

name - 物件名称

index - 斐波纳契数列的等级索引

示例:

#include

...

string text;

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

{

text=ObjectGetFiboDescription(MyObjectName,i);

//---- check. may be objects's level count less than 32

if(GetLastError()!=ERR_NO_ERROR) break;

Print(MyObjectName,"level: ",i," description: ",text);

}

 

int ObjectGetShiftByValue( string name, double value)

取物件的位移值

:: 输入参数

name - 物件名称

value - 价格

示例:

int shift=ObjectGetShiftByValue("MyTrendLine#123", 1.34);

 

double ObjectGetValueByShift( string name, int shift)

取物件位移后的值

:: 输入参数

name - 物件名称

shift - 位移数

示例:

double price=ObjectGetValueByShift("MyTrendLine#123", 11);

 

bool ObjectMove( string name, int point, datetime time1, double price1)

移动物件

:: 输入参数

name - 物件名称

point - 调整的索引 

time1 - 新的时间 

price1 - 新的价格

示例:

ObjectMove("MyTrend", 1, D'2005.02.25 12:30', 1.2345);

 

string ObjectName( int index)

取物件名称

:: 输入参数

index - 物件的索引

示例:

int obj_total=ObjectsTotal();

string name;

for(int i=0;i<OBJ_TOTAL;I++)

{

name=ObjectName(i);

Print(i,"Object name is " + name);

}

 

int ObjectsDeleteAll( int window, int type=EMPTY)

删除所有物件

:: 输入参数

window - 物件所在的窗口索引

type - 删除物件的类型

示例:

ObjectsDeleteAll(2, OBJ_HLINE); // removes all horizontal line objects from window 3 (index 2).

 

bool ObjectSet( string name, int index, double value)

设置物件的值

:: 输入参数

name - 物件的名称

index - 物件属性的索引值 

value - 新的属性值

示例:

// moving first coord to last bar time

ObjectSet("MyTrend", OBJPROP_TIME1, Time[0]);

// setting second fibo level

ObjectSet("MyFibo", OBJPROP_FIRSTLEVEL+1, 1.234);

// setting object visibility. object will be shown only on 15 minute and 1 hour charts

ObjectSet("MyObject", OBJPROP_TIMEFRAMES, OBJ_PERIOD_M15 | OBJ_PERIOD_H1);

 

bool ObjectSetFiboDescription( string name, int index, string text)

设置物件斐波纳契数列的描述

:: 输入参数

name - 物件的名称

index - 物件斐波纳契数列的索引值 

text - 新的描述

示例:

ObjectSetFiboDescription("MyFiboObject,2,"Second line");

 

bool ObjectSetText( string name, string text, int font_size, string font=NULL, color text_color=CLR_NONE)

设置物件的描述

:: 输入参数

name - 物件的名称

text - 文本

font_size - 字体大小 

font - 字体名称 

text_color - 字体颜色

示例:

ObjectSetText("text_object", "Hello world!", 10, "Times New Roman", Green);

 

void ObjectsRedraw( )

重绘所有物件

示例:

ObjectsRedraw();

 

int ObjectsTotal( )

取物件总数

示例:

int obj_total=ObjectsTotal();

string name;

for(int i=0;i<OBJ_TOTAL;I++)

{

name=ObjectName(i);

Print(i,"Object name is for object #",i," is " + name);

}

 

int ObjectType( string name)

取物件类型

:: 输入参数

name - 物件的名称

示例:

if(ObjectType("line_object2")!=OBJ_HLINE) return(0);

第十五节 标准常量

标准常量 [Standard Constants] 

Applied price enumeration

价格类型枚举

示例:

 

Constant Value Description

PRICE_CLOSE 0 收盘价

PRICE_OPEN 1 开盘价

PRICE_HIGH 2 最高价

PRICE_LOW 3 最低价

PRICE_MEDIAN 4 最高价和最低价的平均价

PRICE_TYPICAL 5 最高价、最低价和收盘价的平均价

PRICE_WEIGHTED 6 开、收盘价和最高最低价的平均价

 

 

Drawing shape style enumeration

画图形状样式枚举,

形状:

 

Constant Value Description

DRAW_LINE 0 Drawing line.

DRAW_SECTION 1 Drawing sections.

DRAW_HISTOGRAM 2 Drawing histogram.

DRAW_ARROW 3 Drawing arrows (symbols).

DRAW_NONE 12 No drawing.

 

样式:

 

Constant Value Description

STYLE_SOLID 0 The pen is solid.

STYLE_DASH 1 The pen is dashed.

STYLE_DOT 2 The pen is dotted.

STYLE_DASHDOT 3 The pen has alternating dashes and dots.

STYLE_DASHDOTDOT 4 The pen has alternating dashes and double dots.

 

Ichimoku Kinko Hyo modes enumeration

Ichimoku指标模式枚举

 

Constant Value Description

MODE_TENKANSEN 1 Tenkan-sen.

MODE_KIJUNSEN 2 Kijun-sen.

MODE_SENKOUSPANA 3 Senkou Span A.

MODE_SENKOUSPANB 4 Senkou Span B.

MODE_CHINKOUSPAN 5 Chinkou Span.

 

Indicators line identifiers

指标线标示符

指标线模式,使用在 iMACD(), iRVI() 和 iStochastic() 中:

 

Constant Value Description

MODE_MAIN 0 Base indicator line.

MODE_SIGNAL 1 Signal line.

 

指标线模式,使用在 iADX() 中:

 

Constant Value Description

MODE_MAIN 0 Base indicator line.

MODE_PLUSDI 1 +DI indicator line.

MODE_MINUSDI 2 -DI indicator line.

 

指标线模式,使用在 iBands(), iEnvelopes(), iEnvelopesOnArray(), iFractals() and iGator() 中:

 

Constant Value Description

MODE_UPPER 1 Upper line.

MODE_LOWER 2 Lower line.

 

Market information identifiers

市场信息标识

 

Constant Value Description

MODE_LOW 1 Low day price.

MODE_HIGH 2 High day price.

MODE_TIME 5 The last incoming quotation time.

MODE_BID 9 Last incoming bid price.

MODE_ASK 10 Last incoming ask price.

MODE_POINT 11 Point size.

MODE_DIGITS 12 Digits after decimal point.

MODE_SPREAD 13 Spread value in points.

MODE_STOPLEVEL 14 Stop level in points.

MODE_LOTSIZE 15 Lot size in the base currency.

MODE_TICKVALUE 16 Tick value.

MODE_TICKSIZE 17 Tick size.

MODE_SWAPLONG 18 Swap of the long position.

MODE_SWAPSHORT 19 Swap of the short position.

MODE_STARTING 20 Market starting date (usually used for future markets).

MODE_EXPIRATION 21 Market expiration date (usually used for future markets).

MODE_TRADEALLOWED 22 Trade is allowed for the symbol.

 

Moving Average method enumeration

移动平均线模式枚举,iAlligator(), iEnvelopes(), iEnvelopesOnArray, iForce(), iGator(), iMA(), iMAOnArray(), iStdDev(), iStdDevOnArray(), iStochastic()这些会调用此枚举

 

Constant Value Description

MODE_SMA 0 Simple moving average,

MODE_EMA 1 Exponential moving average,

MODE_SMMA 2 Smoothed moving average,

MODE_LWMA 3 Linear weighted moving average.

 

 

Object properties enumeration

物件属性枚举

 

Constant Value Description

OBJPROP_TIME1 0 Datetime value to set/get first coordinate time part.

OBJPROP_PRICE1 1 Double value to set/get first coordinate price part.

OBJPROP_TIME2 2 Datetime value to set/get second coordinate time part.

OBJPROP_PRICE2 3 Double value to set/get second coordinate price part.

OBJPROP_TIME3 4 Datetime value to set/get third coordinate time part.

OBJPROP_PRICE3 5 Double value to set/get third coordinate price part.

OBJPROP_COLOR 6 Color value to set/get object color.

OBJPROP_STYLE 7 Value is one of STYLE_SOLID, STYLE_DASH, STYLE_DOT, STYLE_DASHDOT, STYLE_DASHDOTDOT constants to set/get object line style.

OBJPROP_WIDTH 8 Integer value to set/get object line width. Can be from 1 to 5.

OBJPROP_BACK 9 Boolean value to set/get background drawing flag for object.

OBJPROP_RAY 10 Boolean value to set/get ray flag of object.

OBJPROP_ELLIPSE 11 Boolean value to set/get ellipse flag for fibo arcs.

OBJPROP_SCALE 12 Double value to set/get scale object property.

OBJPROP_ANGLE 13 Double value to set/get angle object property in degrees.

OBJPROP_ARROWCODE 14 Integer value or arrow enumeration to set/get arrow code object property.

OBJPROP_TIMEFRAMES 15 Value can be one or combination (bitwise addition) of object visibility constants to set/get timeframe object property.

 

OBJPROP_DEVIATION 16 Double value to set/get deviation property for Standard deviation objects.

OBJPROP_FONTSIZE 100 Integer value to set/get font size for text objects.

OBJPROP_CORNER 101 Integer value to set/get anchor corner property for label objects. Must be from 0-3.

OBJPROP_XDISTANCE 102 Integer value to set/get anchor X distance object property in pixels.

OBJPROP_YDISTANCE 103 Integer value is to set/get anchor Y distance object property in pixels.

OBJPROP_FIBOLEVELS 200 Integer value to set/get Fibonacci object level count. Can be from 0 to 32.

OBJPROP_FIRSTLEVEL+ n 210 Fibonacci object level index, where n is level index to set/get. Can be from 0 to 31.

 

 

Object type enumeration

物件类型枚举

 

Constant Value Description

OBJ_VLINE 0 Vertical line. Uses time part of first coordinate.

OBJ_HLINE 1 Horizontal line. Uses price part of first coordinate.

OBJ_TREND 2 Trend line. Uses 2 coordinates.

OBJ_TRENDBYANGLE 3 Trend by angle. Uses 1 coordinate. To set angle of line use ObjectSet() function.

 

OBJ_REGRESSION 4 Regression. Uses time parts of first two coordinates.

OBJ_CHANNEL 5 Channel. Uses 3 coordinates.

OBJ_STDDEVCHANNEL 6 Standard deviation channel. Uses time parts of first two coordinates.

OBJ_GANNLINE 7 Gann line. Uses 2 coordinate, but price part of second coordinate ignored.

OBJ_GANNFAN 8 Gann fan. Uses 2 coordinate, but price part of second coordinate ignored.

OBJ_GANNGRID 9 Gann grid. Uses 2 coordinate, but price part of second coordinate ignored.

OBJ_FIBO 10 Fibonacci retracement. Uses 2 coordinates.

OBJ_FIBOTIMES 11 Fibonacci time zones. Uses 2 coordinates.

OBJ_FIBOFAN 12 Fibonacci fan. Uses 2 coordinates.

OBJ_FIBOARC 13 Fibonacci arcs. Uses 2 coordinates.

OBJ_EXPANSION 14 Fibonacci expansions. Uses 3 coordinates.

OBJ_FIBOCHANNEL 15 Fibonacci channel. Uses 3 coordinates.

OBJ_RECTANGLE 16 Rectangle. Uses 2 coordinates.

OBJ_TRIANGLE 17 Triangle. Uses 3 coordinates.

OBJ_ELLIPSE 18 Ellipse. Uses 2 coordinates.

OBJ_PITCHFORK 19 Andrews pitchfork. Uses 3 coordinates.

OBJ_CYCLES 20 Cycles. Uses 2 coordinates.

OBJ_TEXT 21 Text. Uses 1 coordinate.

OBJ_ARROW 22 Arrows. Uses 1 coordinate.

OBJ_LABEL 23 Text label. Uses 1 coordinate in pixels.

 

 

Object visibility enumeration

物件显示枚举

 

Constant Value Description

OBJ_PERIOD_M1 0x0001 Object shown is only on 1-minute charts.

OBJ_PERIOD_M5 0x0002 Object shown is only on 5-minute charts.

OBJ_PERIOD_M15 0x0004 Object shown is only on 15-minute charts.

OBJ_PERIOD_M30 0x0008 Object shown is only on 30-minute charts.

OBJ_PERIOD_H1 0x0010 Object shown is only on 1-hour charts.

OBJ_PERIOD_H4 0x0020 Object shown is only on 4-hour charts.

OBJ_PERIOD_D1 0x0040 Object shown is only on daily charts.

OBJ_PERIOD_W1 0x0080 Object shown is only on weekly charts.

OBJ_PERIOD_MN1 0x0100 Object shown is only on monthly charts.

OBJ_ALL_PERIODS 0x01FF Object shown is on all timeframes.

NULL 0 Object shown is on all timeframes.

EMPTY -1 Hidden object on all timeframes.

 

Series array identifier

系列数组标识符

 

Constant Value Description

MODE_OPEN 0 Open price.

MODE_LOW 1 Low price.

MODE_HIGH 2 High price.

MODE_CLOSE 3 Close price.

MODE_VOLUME 4 Volume, used in Lowest() and Highest() functions.

MODE_TIME 5 Bar open time, used in ArrayCopySeries() function.

 

Special constants

特殊常量

 

Constant Value Description

NULL 0 Indicates empty state of the string.

EMPTY -1 Indicates empty state of the parameter.

EMPTY_VALUE 0x7FFFFFFF Default custom indicator empty value.

CLR_NONE 0xFFFFFFFF Indicates empty state of colors.

WHOLE_ARRAY 0 Used with array functions. Indicates that all array elements will be processed.

 

Time frame enumeration

特殊常量

 

Constant Value Description

PERIOD_M1 1 1 minute.

PERIOD_M5 5 5 minutes.

PERIOD_M15 15 15 minutes.

PERIOD_M30 30 30 minutes.

PERIOD_H1 60 1 hour.

PERIOD_H4 240 4 hour.

PERIOD_D1 1440 Daily.

PERIOD_W1 10080 Weekly.

PERIOD_MN1 43200 Monthly.

0 (zero) 0 Time frame used on the chart.

 

Trade operation enumeration

交易类型

 

Constant Value Description

OP_BUY 0 Buying position.

OP_SELL 1 Selling position.

OP_BUYLIMIT 2 Buy limit pending position.

OP_SELLLIMIT 3 Sell limit pending position.

OP_BUYSTOP 4 Buy stop pending position.

OP_SELLSTOP 5 Sell stop pending position.

 

 

 

 

 

1、MT4智能交易系统编写举例

我们现在就创建智能交易系统,并在运行标准的平滑异同移动平均线指标,该系统具有较强的获利能力,支持追踪止损和最大的保障安全操作。 下面所给的例子,交易通过对单一的部位进行开仓和控制。

交易原则:

?        多头进场– MACD指标在零点之下, 向上走,或由下行信号线穿过。

?        空头进场– MACD指标在零点以上, 向下走,或由上行信号线穿过。

?        多头出场-通过执行获利限额,移动止损或当MACD指标穿过信号线(MACD指标在零点以上, 向下走,或由上行信号线穿过)

• 空头出场-通过执行获利限额,移动止损或当MACD指标穿过信号线(MACD指标在零点以下, 向上走,或由下行信号线穿过)

重要提示: 为了排除MACD指针于我们的分析出现的微不足道的变化(图表上的“小山丘”),我们引入另外一种控制绘图中的“小山丘的大小”的方法如下: 指针大小应至少为最低价格的5个单位(5*Point,表示USD/CHF = 0.0005和USD/JPY = 0.05)。

步骤 I : 编写智能交易系统描述 

 

将鼠标指针点到导航窗口的智能交易系统区,按鼠标右键,在出现的菜单里选中“创建”指令。智能交易系统的启动向导要求你进入某些数据。在出现的窗口,我们写入智能交易系统名称(Name)-MACD 样本,作者(Author)-指示你的名字,连接(Link)-连接到网站,在注解(Notes)里写入-以MACD为基础的智能交易系统测试样本。 

 

第二步: 创建程序的主结构

智能交易系统代码只有几页,即便是这几页代码也挺难掌握,特别是考虑这个事实:我们不是专业的程序开发商,另外,我们根本不需要专业性的描述,对吗? 

为了对标准智能交易系统的结构有些了解,我们现在就看看下面的这个描述吧:

 

1.      原始数据检查

•        检查图表、图表上的条形数

•        核查外部变量值:单位、Lots, S/L, T/P, T/S。

2.      设定快速数据存取内部变量;

 

3.      检查交易终端-是否可用?若是的话,那么:

•        检查账户资金的可用性,等。

•        是否可能来做多头买卖(买单)?

•        开仓(买)并离开

•        是否能做空仓(卖出)?

•        空仓(卖)并离开

退出智能交易系统

4.      控制循环周期中前期的开仓部位

•       如果是做多头

•        是否应出仓?

•        是否应该设置追踪止损单?

•        如果是做多头

•        是否应该出仓?

•        是否应该设置追踪止损单?

结果相当简单,只有4个主区块。

现在,请跟随着每个结构的步骤来创建代码:

 

1.      原始数据的检索

这条代码通常从智能交易系统移到另一个稍微更改的另一个代码-实际上为检索的标准区块:

若Bars<200,就离开;//图表不足200bars-退出。

 

        若获利<10,则退出;//错误获利参数

  2. 为了加快数据存取,设置内部变量

在程序代码中,很有必要存取指标值或处理计算值。为了简化代码和加速存储,初始状态下,数据嵌套在内部变量里。

MacdCurrent=iMACD(12,26,9,MODE_MAIN,0);     // MACD value on the current bar

MacdPrevious=iMACD(12,26,9,MODE_MAIN,1);    // MACD value on the previous bar

SignalCurrent=iMACD(12,26,9,MODE_SIGNAL,0); // Signal Line value on the current bar

SignalPrevious=iMACD(12,26,9,MODE_SIGNAL,1);// Signal Line value on the previous bar

MaCurrent=iMA(MATrendPeriod,MODE_EMA,0);    // moving average value on the current bar

MaPrevious=iMA(MATrendPeriod,MODE_EMA,1);   // moving average value on the previous bar

现在,不用晦涩难懂的iMACD(12,26,9,MODE_MAIN,0) 符号,我们在程序中用简单的写入字符 MacdCurrent程序文本取而代之。所有的智能交易系统中的变量都依据MQL II语言进行基本的解释。所以,我们在程序的开头加入这段说明。

var: MacdCurrent(0), MacdPrevious(0), SignalCurrent(0), SignalPrevious(0);

var: MaCurrent(0), MaPrevious(0);

MQL 4语言还另外推出了另外一个用户自定义变量概念,它可以在程序外设定,而不会对任何系统程序下的源程序文本造成干扰。这个特点使程序更具灵活性。 MATrendPeriod变量就是这种类型的一个用户自定义变量,所以,我们在程序的开头加入这段说明。

defines: MATrendPeriod(56);

3.      检查交易终端-是否可用? 若是,那么:

在智能交易系统里,我们只能使用当前头寸而不能操作延迟的订单。然而,为了安全起见,我们介绍如何利用交易终端建检查前期提交的订单。

If TotalTrades<1 then   // no opened orders identified

{

?        检查: 账户的可用资金等。在分析市场状况之前,最好先检查一下你的账户的资金情况, 以确保账户中有充足的开仓头寸的资金。

如果净保证金<1000,那么退出;//无资金-退出。

?        可否做多头(买入)?

多头买入的条件:MACD指标在0轴以下,为向上趋势且与向下趋势的信号线相交。这和我们在MQL II语言中所描述的一样(注意:我们可以按照原已保存在变量中的这个指标值进行操作。) 

If MacdCurrent<0 and MacdCurrent>SignalCurrent and

   MacdPrevious<SignalPrevious and              // a cross-section exists

   Abs(MacdCurrent)>(MACDOpenLevel*Point) and   // the indicator plotted a decent 'hillock'

   MaCurrent>MaPrevious then                    // 'bull' trend

{

      SetOrder(OP_BUY,Lots,Ask,3,0,Ask+TakeProfit*Point,RED); // executing

      Exit; // exiting, since after the execution of a trade

            // there is a 10-second trading timeout

};

前面我们提到了一种监控图表中所要显示“小丘”的大小的一种方法。MACDOpenLevel 变量是一个用户定义变量,可以在不影响程序文本的情况下,进行更改,以确保更多的灵活性。在程序的开始部分,我们加入一段这个变量的描述(以及下面所用到的变量描述)。

defines: MACDOpenLevel(3), MACDCloseLevel(2);

?        是否可以做空头(卖出)?空头卖出的条件:MACD指标在0轴以上,为向下趋势且与向上趋势的信号线相交。符号表示如下:

If MacdCurrent>0 and MacdCurrent<SignalCurrent and

   MacdPrevious>SignalPrevious and MacdCurrent>(MACDOpenLevel*Point) and

   MaCurrent<MaPrevious then

{

      SetOrder(OP_SELL,Lots,Bid,3,0,Bid-TakeProfit*Point,RED); // executing

      Exit; // exiting

};

   Exit;   // no new positions opened - just exit

};

 

4.      控制循环周期中前期已开仓的头寸

for cnt=1 to TotalTrades

{

   if OrderValue(cnt,VAL_TYPE)<=OP_SELL and   // is it an open position?

      OrderValue(cnt,VAL_SYMBOL)=Symbol then // position from "our" chart?

     {

CNT是周期变量,是在程序的开始部分加以描述的,具体如下:

var: Cnt(0);

?        若是多头买入

If OrderValue(cnt,VAL_TYPE)=OP_BUY then // long position opened

{

?        是否需要平仓?存在平仓的条件:MACD指针与信号线相交,MACD指针在0轴以上,为向下趋势且与向上趋势的信号线相交。

If MacdCurrent>0 and MacdCurrent<SignalCurrent and

   MacdPrevious>SignalPrevious and MacdCurrent>(MACDCloseLevel*Point) then

{

    CloseOrder(OrderValue(cnt,VAL_TICKET),OrderValue(cnt,VAL_LOTS),Bid,3,Violet);

    Exit; // exit

};

?        是否应该需要重新设定移动止损点?仅在持仓并已超过移动止损点数点并获利的情况下,而且新的移动止损点比前期的要更有理一些,我们才重新设置移动止损点。

If TrailingStop>0 then // if trailing stops are used

{

    If (Bid-OrderValue(cnt,VAL_OPENPRICE))>(Point*TrailingStop) then

      {

        If OrderValue(cnt,VAL_STOPLOSS)<(Bid-Point*TrailingStop) then

          {

             ModifyOrder(OrderValue(cnt,VAL_TICKET),OrderValue(cnt,VAL_OPENPRICE),

                         Bid-Point*TrailingStop,OrderValue(cnt,VAL_TAKEPROFIT),Red);

             Exit;

          };

       };

};

}

?        若是处在空头部位

else // otherwise it is a short position

{

?        是否应该平仓?出现空头的条件: MACD指针与信号线相交,MACD指针在0轴以下,为向上趋势且与向下趋势的信号线相交。

If MacdCurrent<0 and MacdCurrent>SignalCurrent and

   MacdPrevious<SignalPrevious and Abs(MacdCurrent)>(MACDCloseLevel*Point) then

{

    CloseOrder(OrderValue(cnt,VAL_TICKET),OrderValue(cnt,VAL_LOTS),Ask,3,Violet);

    Exit; // exit

};

?        是否应该重新设定移动止损点?仅在持仓并已超过移动止损点数点并获利的情况下,而且新的移动止损点比前期的要更有理一些,我们才重新设置移动止损点。

If TrailingStop>0 then // the user has put a trailing stop in his settings

{                // so, we set out to check it

    If (OrderValue(cnt,VAL_OPENPRICE)-Ask)>(Point*TrailingStop) then

      {

        If OrderValue(cnt,VAL_STOPLOSS)=0 or

           OrderValue(cnt,VAL_STOPLOSS)>(Ask+Point*TrailingStop) then

          {

            ModifyOrder(OrderValue(cnt,VAL_TICKET),OrderValue(cnt,VAL_OPENPRICE),

                        Ask+Point*TrailingStop,OrderValue(cnt,VAL_TAKEPROFIT),Red);

            Exit;

          };

      };

};

// end. 结束所有的花括号,但仍然有效。

    };

};

};

所以,按照步骤,循序渐进地学习,我们已经学会了编写智能交易系统。

第三步:将所有程序代码集合起来

 

我们将前面章节的所有的代码集合起来:

defines: MACDOpenLevel(3),MACDCloseLevel(2);

defines: MATrendPeriod(56);

var: MacdCurrent(0),MacdPrevious(0),SignalCurrent(0),SignalPrevious(0);

var: MaCurrent(0),MaPrevious(0);

var: cnt(0);

// 原始数据检查

//确保智能交易系统在正常图表上运行,这很重要。

// 用户正确设置外部变量 (单位数, 止损,

// 获利、移动止损)

// 在我们看来,我们只需检查获利就行了

若Bars<200或获利<10,那么就退出;//图表上少于200 bars

//简化和加速操作程序,我们需要作必要的保存

//临时变量中的指标数据

MacdCurrent=iMACD(12,26,9,0,MODE_MAIN);

MacdPrevious=iMACD(12,26,9,1,MODE_MAIN);

SignalCurrent=iMACD(12,26,9,0,MODE_SIGNAL);

SignalPrevious=iMACD(12,26,9,1,MODE_SIGNAL);

MaCurrent=iMA(MATrendPeriod,MODE_EMA,0);

MaPrevious=iMA(MATrendPeriod,MODE_EMA,1);

//现在我们必须检查交易终端的状况

// 我们要看一看是否还有任何前期开仓部位或订单。

如果总交易<1, 那么

{//没有已开仓订单

    // 为了安全期间,我们要确保账户有充足的资金。.

//比如说,取值为“1000”,通常可能就是提交1个单位

如果净保证金<1000,那么退出;//没有资金-我们退出

//检查做多头(买入)的可能性

   If MacdCurrent<0 and MacdCurrent>SignalCurrent and

      MacdPrevious<SignalPrevious and Abs(MacdCurrent)>(MACDOpenLevel*Point) and

      MaCurrent>MaPrevious then

     {

      SetOrder(OP_BUY,Lots,Ask,3,0,Ask+TakeProfit*Point,RED); // 执行

      Exit; // 既然交易已经执行,退出

            // 有10秒钟的交易暂停时间

     };

//检查空头(卖出)的可能性

   If MacdCurrent>0 and MacdCurrent<SignalCurrent and

      MacdPrevious>SignalPrevious and MacdCurrent>(MACDOpenLevel*Point) and

      MaCurrent<MaPrevious then

     {

      SetOrder(OP_SELL,Lots,Bid,3,0,Bid-TakeProfit*Point,RED); // executing

      Exit; // exiting

     };

//这里我们完成了对新的开仓部位可行性检查

//没有新的开仓部位,我们就用退出命令退出程序

//没有要分析的任何东西

   Exit;

};

//我们进入到智能交易系统的重要部分-控制开仓部位

// 正确进入市场很重要,但是退出市场更重要。

for cnt=1 to TotalTrades

{

   if OrderValue(cnt,VAL_TYPE)<=OP_SELL and   //这是开仓部位吗? OP_BUY or OP_SELL      

OrderValue(cnt,VAL_SYMBOL)=Symbol then // 工具匹配吗?

     {

      If OrderValue(cnt,VAL_TYPE)=OP_BUY then // 多头开仓

        {

        // 我们检查-可能,尚有时间平仓吗?

         If MacdCurrent>0 and MacdCurrent<SignalCurrent and

            MacdPrevious>SignalPrevious and MacdCurrent>(MACDCloseLevel*Point) then

           {

             CloseOrder(OrderValue(cnt,VAL_TICKET),OrderValue(cnt,VAL_LOTS),Bid,3,Violet);

             Exit; // 退出

           };

         // 我们检查-可能,我可能已经或该是设置移动止损的时候了吗?

         If TrailingStop>0 then //用户已经将移动止损进行了设置

           {                     // 所以,我们开始着手检查

            If (Bid-OrderValue(cnt,VAL_OPENPRICE))>(Point*TrailingStop) then

              {

               If OrderValue(cnt,VAL_STOPLOSS)<(Bid-Point*TrailingStop) then

                 {

                   ModifyOrder(OrderValue(cnt,VAL_TICKET),OrderValue(cnt,VAL_OPENPRICE),

                               Bid-Point*TrailingStop,OrderValue(cnt,VAL_TAKEPROFIT),Red);

                   Exit;

                 };

              };

           };

        }

      else // 否则,就是多头。

        {

       // 我们检查-可能,尚有时间平仓吗?

         If MacdCurrent<0 and MacdCurrent>SignalCurrent and 

            MacdPrevious<SignalPrevious and Abs(MacdCurrent)>(MACDCloseLevel*Point) then

            {

             CloseOrder(OrderValue(cnt,VAL_TICKET),OrderValue(cnt,VAL_LOTS),Ask,3,Violet);

             Exit; // 退出

            };

         //我们检查-可能,我可能已经或该是设置移动止损的时候了吗?

         If TrailingStop>0 then // 用户已经把移动止损进行了设置

           {                // 所以,我开始着手检查。

            If (OrderValue(cnt,VAL_OPENPRICE)-Ask)>(Point*TrailingStop) then

             {

               If OrderValue(cnt,VAL_STOPLOSS)=0 or 

                  OrderValue(cnt,VAL_STOPLOSS)>(Ask+Point*TrailingStop) then

                 {

                   ModifyOrder(OrderValue(cnt,VAL_TICKET),OrderValue(cnt,VAL_OPENPRICE),

                              Ask+Point*TrailingStop,OrderValue(cnt,VAL_TAKEPROFIT),Red);

                   Exit;

                 };

              };

           };

        };

     };

};

// 结束 。

要完成对智能交易系统的设置,我只需要对外部变量进行设定,Lots = 1, Stop Loss (S/L) = 0 (未使用), Take Profit (T/P) = 120 (适用于一个小时的间隔),Trailing Stop (T/S) = 30。当然,你还可以设置自己的数值。

按Compile按钮,如果没有错误信息,就按SAVE按钮保存智能交易系统(顺便说,你还可以将上述程序的灰色背景打印文本保存到MetaEditor)。

现在,我们来编辑智能交易系统, 在MQL编辑器点击顶端的Compile图示(像一张有检查标记的纸)。 

步骤 IV: 测试智能交易系统的历史数据

我们已经编写了智能交易系统,我们通过对测试历史数据,现在急于要对其进行评估。 我们就以15分钟间隔的EUR/USD为例,大约为4000基准值。

打开智能交易系统测试器:

在软件下部会出现智能交易系统测试器:

在智能交易系统测试器中选择EUR/USD,M15,设置测试历史数据的起始日期和结束日期,开始测试

测试完成后,可查看测试记录、净值图,在报告栏中可查看统计报表,并可将完整的包括净值图、交易记录、分析报表完整地保存下来。

智能交易系统不仅提供建议和信号,而且允许交易账户上进行自动交易,用附加到图表指令(通过在导航窗口用鼠标指针选中MACD样本,按鼠标右键选中出现的菜单命令)将MACD 样本智能交易系统附加到图表中,然后点击“启用智能交易系统”按钮。

或点击该智能交易系统,在对话框中选择“允许实时自动交易”并点确定。智能交易系统就会工作了

智能交易系统所有代码在 Ready Expert Advisors页都可找到

当你对智能交易系统做出编写时,必须谨记:

编写和测试交易平台的智能交易系统具有许多细节特征:

?        在开仓之前,必须检查你账户上可用保证金的有效性。假如可用保证金不足时,则开仓部位交易将失败。必须注意的是,为了达到测试的目的,可用保证金最少应在1000,因为一个单位的测试价格为1000。

If FreeMargin < 1000 Then Exit;   //如果保证金< 1000,那么退出,无资金-退出。

?        在开仓、平仓或者修改已有部位或删除延迟订单(一经执行以下任何的操作:SetOrder, CloseOrder, ModifyOrder or DeleteOrder)之后,建议使用Exit语句完成智能交易系统的这部分的操作,这将有10秒钟的限定时间间隔来执行该项操作。还应注意,10秒钟的限定时间不适用于测试模式(你可以连续做几次交易)。另外,假如不是用Exit语句来完成智能交易系统的上述交易操作,智能交易系统的测试结果将和真实交易不同。

SetOrder(OP_SELL,Lots,Bid,3,0,Bid-TakeProfit*Point,RED); // 执行

Exit;                   //退出

为了防止在测试模式中用少于10秒的间隔来执行几项交易,你只需确保从上一次交易到下一次的交易已经超过10秒。

//确保当前的时值离上次交易的执行大于10秒。

If CurTime > LastTradeTime + 10 Then Begin

    SetOrder(OP_SELL,Lots,Bid,3,0,Bid-TakeProfit*Point,RED); // 执行

   Exit;

End;

?        历史数据可以用已引索的预设变量OPEN、 CLOSE、 HIGH、 LOW、 VOLUME来存取。在这种情况下,指数是指必须回头计算的期间数。

// 如果上个BAR柱状线的收缩小于倒数第二个BAR柱状线的收缩少

If Close[1] < Close[2] Then Exit;

?        交易平台中的智能交易系统支持4种模式:

?        OHLC 点(Open/High/Low/Close)模式。 因为系统在此的测试目的仅限于开盘价、收盘价、最高价、最低价,所以这个测试系统是最快的。 但是, 这个测试结果与智能交易系统执行的实际交易的结果可能会不同。

?        每3点一次模式:在测试智能交易系统时,每增加三点就会模拟产生一个烛台图示。

?        每2点一次模式: 在测试智能交易系统时,每增加二点就会模拟产生一个烛台图示。

?        每1点一次模式:在测试智能交易系统时,每增加一点就会模拟产生一个烛台图,这种模式是最慢的但是测试结果是最接近智能交易系统的实际交易的结果的。(交易中间每间隔10秒钟,观察结果)

?        在编写和检验智能交易系统过程中,以及在对任何其他程序测试过程中,有时, 需要输出一些额外的调试信息。MQL II语言还提供这类信息输出的若干可能性。

?        将ALERT函数以及包含用户自定义的数据发送到屏幕对话框。

Alert("Free margin is ", FreeMargin);

?        COMMENT函数将由用户定义的数据放置在图表的左上角。“\n” 字符用于结束一行。

Comment("Free margin is ", FreeMargin, "\nEquity is ", Equity);

?        Print 函数是将由用户定义的数据输至系统日志。

Print("Total trades are ", TotalTrades, "; Equity is ", Equity, "; Credit is ", Credit);

?        PrintTrade函数是将指定的未平仓合约的具体细节输出到系统日志中。 

PrintTrade(1);

?        当 智能交易系统 已测试完毕,测试结果会以扩展名为.log的文件形式储藏在你安装该交易平台所在的日志的子目录中。如果你经常性地测试你的智能交易系统,别忘了定期删除log档,因为它们可能累计达到数兆字节。

 

智能交易系统用户重要提示――智能交易系统并不能提供万能保证。你应对任何你所使用智能交易系统创建的交易自行负责。现特别提醒:你使用任何系统在模拟账户上进行延时练习,均要确认该系统实际上满足了你的要求。请注意,虽然模拟环境和实战黄将相似,当在交易执行方式上还是有差别的。 外汇交易平台对任何使用智能交易系统过程中所发生的任何电子上的或技术上的错误均不承担责任

2、MT4使用说明——技术指标③

资金流量指数指标

资金流量指标(MFI)是测算资金投入证券并从证券市场中收回时的。速率的技术指标。对于该指标的构筑和解释与相对强弱指标相似,区别只是在于:成交量对于资金流量指数是重要的

当我们分析资金流量指数时,必须考虑下列几点 :

• 指标和价格移动的偏离,如果价格上升而指标下降的话(或者相反),则价格存在一个极有可能的变化;

• 资金流量指数值,如果超过80或者是低于20的话,则分别可以表明市场潜在的上升或探底趋势。

计算方法

资金流量指标的计算方法包括几个步骤。首先我们要定义一个需要研究时段的典型价。.

TP = (HIGH + LOW + CLOSE)/3

然后我们计算资金流量的数额:

MF = TP * VOLUME

如果当天的典型价格高于昨天的典型价格,那么资金流量指数应该是个正数。如果今天的典型价格低于昨天的典型价格,那么资金流量的指数应该是个负数。

正资金流量是在一定时段里,正资金流量的一个总和。负资金流量是一定时段里,负资金流量的一个总和。

然后我们计算资金比率(MR),把正资金流量以负资金流量:

MR = Positive Money Flow (PMF)/Negative Money Flow (NMF) 

最后我们用资金比率来计算资金流量指数:

MFI = 100 - (100 / (1 + MR))

移动平均线

移动平均线指标显示某一个时间段平均工具性价格的数值。当我们计算移动平均线的时候,其实我们是在平均这段时间内工具性价格的数值。由于价格的变化,移动平均线指标要么增加要么减少。

有四种不同类型的移动平均线: 简单(也被成为算术)移动平均线, 指数移动平均线, 通畅移动平均线和 线形权数移动平均线。。我们可以为任何一套顺序排列的数据来进行移动平均线的计算,包括开市和闭市价格,最高和最低价格,交易量和任何其他的指标。同时有两条移动平均线被使用的情况比较普遍。

只有在一种情况下,不同种类的移动平均线会产生相当大的分离,就是当权数系数不同的情况下(该系数是被安排到最近的一个数据里的),我们在讨论简单移动平均线的时候,我们研究的时间段的所有价格都在数值上相等。指数和线形权数移动平均线的数值更趋向于最近的价格

解释价格平均移动最普遍的方法是就是将其动量与价格运动相比较。当工具性价格上升到其移动平均线之上时,购买信号出现了;当价格下落到移动平均线下面时,我们所得到的是一个卖出信号。

这种基于移动平均线的贸易体系,并不是设计用来提供给我们一个通道的:市场处于低潮期的时候让我们进入,在进入高峰期的时候让我们出来。根据下列市场趋势的变化,它可以使得我们作出相应的行动:一旦价格探底,我们就开始买进;一旦价格攀升,我们就开始卖出。

移动平均线也可被运用于各种指标。那就是移动平均指标的解释和价格移动平均线解释相似的地方。如果指标上升到移动平均线上面的时候,那就意味着上升的指标运动还将继续。指标若是低于移动平均线,那就表明指标有可能继续下滑。

这是图表上移动平均线:

• 简单移动平均线(SMA)

• 指数移动平均线 (EMA)

• 通畅移动平均线 (SMMA)

• 线性权数移动平均线 (LWMA)

计算方法:

简单移动平均线(SMA)

简单,或者说是算术移动平均线的计算:汇总某几个单一时间段内闭合的工具性价格(比如,12个小时)然后这个汇总的数值在除以时段数

SMA = SUM(CLOSE, N) / N

 

注解:

N — 计算用的时段数目。

指数移动平均线(EMA)

指数通畅移动平均线的计算:把某一份额的当前收市价格的移动平均线与上一个这样的数值相加有指数通畅移动平均线的当前价格的数值最大,P百分率的指数移动平均数率表示为 :

EMA = (CLOSE(i) * P) + (EMA(i - 1) * (100 - P))

 

注解: 

CLOSE(i) — 当前时段收市价格;

EMA(i-1) — 上一收市时段移动平均线;

P — 使用价格数值的百分比。

通畅移动平均线 (SMMA)

该通畅移动平均线的第一个数值的计算和简单移动平均线一样(SMA):

SUM1 = SUM(CLOSE, N)

SMMA1 = SUM1/N

第二个和接下来的数值的计算,可参照下列公式:

PREVSUM = SMMA(i - 1) * N

SMMA(i) = (PREVSUM - SMMA(i - 1) + CLOSE(i)) / N 

Where: 

SUM1 —N个时间段收市价格的总值; 

SMMA1 — 第一个柱形的通畅移动平均线;

SMMA(i) — 当前柱形的通畅移动平均线(除了第一个以外);

CLOSE(i) — 当前收市价格;

N — 通畅时段;

线性权数移动平均线(LWMA)

就线性权术移动平均线而言,其最新的数据值大于它早期的数值。权数移动平均线的计算:在所考虑的一系列数据里,两两相乘每一个收市价格,然后在比上某一个特定的权数系数。

LWMA = SUM(Close(i)*i, N) / SUM(i, N)

 

Where: 

SUM(i, N) — 权数系数的总合。

移动振动平均震荡器指标

震荡移动平均指数的数值是振荡指数和震荡通畅指数的差额。在这种情况下,MACD的基本曲线被作为振荡指标。信号曲线被作为通畅指标。

计算方法

OSMA = MACD-SIGNAL

能量潮指标

能量潮技术指标是关联成交量和价格变化的一个冲量指标。JOSEPH GRANVELLE提出的这个指标相当简单。当证券收市价格高于前一收市价格,当天所有的交易都被称为上能量潮;当证券收市价格低于前一收市价格时,当天所有交易都被称为下能量潮。

有关能量潮交易的一个最基本的假设是:该指标的变化先于价格的变化。该理论意思就是说,通过上升的能量潮交易量指标,我们可以看到游动资金流入证券市场。当大众都纷纷进入证券市场的时候,证券和能量潮交易量指标都会上升。

如果证券的价格移动先于能量潮交易量的移动,“非确认“将会产生。这种情况会出现在牛力占据市场主导地位的时候(那时证券价格单独上涨或者是先于能量潮指数上升);同样,这种情况也会出现在熊力占市场主导地位的时候(那时证券价格单独下降,或先于能量潮指数下降).

当能量潮技术指标每一个高峰高于上一个的时候,或者它的每一个低谷都高于上一个的时候,那么我们就说能量潮处于一个上升趋势。同样,与上面情况相反的话,那么我们就说能量潮技术指标处于一个下降的趋势。当指数进行边际移动或者没有进行上下的波动时,那能量潮技术指标就处于一个怀疑趋势。

一旦这个趋势建立以后,只有当它被打破时,该趋势的作用才会消失。我们有两种打破能量潮指标趋势的方法。第一种就是趋势从高到低的运动,或者从低到高的运动。

第二种就是如果当指标进入怀疑趋势或者在处于怀疑趋势三天以上的,我们也可以打破这个指标趋势。如果证券价格的变化遵循从上升趋势进入怀疑趋势,并只要能在回复到上升趋势之前在怀疑趋势中保持两天的话,那我么就认定这个能量潮指数可以一直处于上升阶段。

当移动平衡指数变化到上升或是下降趋势的时候,"爆发"就发生了。由于该指标的"爆发"先于价格的“爆发”,投资者应该在指标向下"爆发"时买进长线;同样,投资者在该指标向上"爆发"的时候,卖出长线。应该等到趋势变化的时候在收线。

计算方法

如果当天的收盘价高于昨天的话,那么: OBV(i) = OBV(i-1)+VOLUME(i)

如果当天的收盘价低于昨天的话,那么: OBV(i) = OBV(i-1)-VOLUME(i)

如果当前的收盘价等于昨天的话,那么: OBV(i) = OBV(i-1)

注解:

OBV(i) —当前时段指标值;

OBV(i-1) —上一时段的指标值 ; 

VOLUME(i) —当前柱形的成交量。

抛物线状止损和反转指标

抛物线状止损和反转技术指标是用来分析市场的趋势变化的。这个指标是构件于价格图表之上的。抛物线状止损和反转技术指标与移动平均线技术指标相似,唯一的差别就是:抛物线技术指标是以越来越快的速度加速移动的,并且就价格而改变自己的位置的。该指标在牛力时(上升趋势) 低于价格水平,在熊力时(下降趋势)高于价格水平。

如果价格穿过抛物线指数时,那么该指标开始反转,它的进一步的价值会落在价格水平的另外一面。当该指标的反转确实发生时,上一个时间段的最高和最低值将作为一个开始点。当该指标反转,它就会给出一个市场趋势结束或者是开始的信号(修正阶段或无波动阶段)如果价格穿过抛物线指数时,那么该指标开始反转,它的进一步的价值会落在价格水平的另外一面。当该指标的反转确实发生时,上一个时间段的最高和最低值将作为一个开始点。当该指标反转,它就会给出一个市场趋势结束或者是开始的信号(修正阶段或无波动阶段)

抛物线指标在出市点方面的表现十分出色。当价格下沉到低于抛物线指标时,我们应该关闭长线的交易;当价格上升到超过该指标时,我们则应该关闭短线交易。通常情况下,该指标作为轨迹终止曲线。

如果长线位置开放的时候(价格高于抛物线指标),不管价格采取如何方向的走势,指标总是向上运动的。指标曲线移动的长度取决于价格移动的规模。

计算方法

SAR(i) = SAR(i-1)+ACCELERATION*(EPRICE(i-1)-SAR(i-1))

注解:

SAR(i-1) — 上一柱形的指标数值; 

ACCELERATION —加速的因素 ;

EPRICE(i-1) —上一时间段的最高(最低)价格,EPRICE=HIGH是长线的价格(EPRICE=LOW是短线的价格)。

如果当前柱形的价格高于上一个牛力的价格,那么抛物线指标数值增加;反之,则指标值下降。与此同时,加速因素(ACELERATION)会以成一倍的方式增加,这时,抛物线指标和价格趋于同一。换句话说,就是价格上升或下降的越快,指标就会更快的趋向于价格水平。

相对强弱指数指标

相对强弱指数技术指标(RSI)是追寻震荡指标的价格,该震荡指标的取值范围在0-100之间。当WILDER在引进这个指数时,他建议使用一个14天的RSI指标。自他提出这个建议以后,人们使用9天和25天的RSI指标也非常的普遍了。

分析RSI指标最为普遍的方法是:我们要寻找这样一个分离的情况,在那点上,证券的价格是创新高的,但RSI指标并未能超过它以前的那个高度。这样的分离暗示着一个迫近的相反趋势。当RSI指标那时开始反转,并且下降到它最近的那个低谷,人们称之为"失败摇摆","失败摇摆"被看作为是即将到来的一个相反趋势的确认。

使用RSI指标来做图表分析的方法:

• 顶部和底部

RSI指标通常上升到70以上或者是下降到30以下。在构成价格图表之前,该指标一般形成这样的顶部和底部趋势;

• 图表的形成

RSI指标一般会形成象头,肩膀和三角形这样的图表图案,这些图形可能在价格图表上是看不到了;

• 失败摇摆 (支持或抗拒;渗透或爆发)

在这个时候,RSI指标一般会超过上一个高点(波峰)或下降到下一个低点(低谷);

• 支持或抗拒水平

RSI指标在表现支持或抗拒水平的时候比价格本身更为的清楚。

• 分离

就上述讨论的一样,当价格水平创出新高(低),但这种新高(低)的趋势并没有被RSI指标所确认的时候,分离的情况就发生了。价格通常会修正并且沿着RSI指标的方向进行移动。

计算方法

RSI = 100-(100/(1+U/D))

注解:

U —价格变化正值的平均数;

D — 价格变化负值的平均数。

相对活力指数指标

相对活力指数技术指标(RVI)的技术特点就是,原则上,在牛力上,收盘价格高于开盘价格;在熊力的时候,情况则相反。所以蕴涵在该RVI之后的原理就是:指数移动的活力或能量是由价格在收市时的那个数值所确立的。为了使得该指标正常于当日的交易范围,我们根据当日价格范围的最大值来划分价格的变动情况。为了进行更为便利的运算,我们应该使用简单移动平均线指标。10是最好的时间段。为了避免可能的混淆,我们必须构建一个信号曲线,这一曲线是RVI指标数值的4段对称加权平均线。曲线之间的汇合被认为是购买或者是卖出的信号。.

计算方法

RVI = (CLOSE-OPEN)/(HIGH-LOW) 

注解:

OPEN — OPEN —开盘价格;

HIGH — 最大价格;

LOW — 最低价格 ;

CLOSE —收盘价格。

标准离差

标准离差 —是市场上的一种易变得价值尺寸。标准离差指标是对简单移动平均线价格涨落变化的描述。所以,如果指标的价值为高,说明市场是易变的,价格柱将会随着简单移动平均线而涨落。如果指标的价值为低,市场的浮动则会降低,价格柱也会随着简单移动平均线涨落。

正常情况下,标准离差指标作为其他指标的组成部分应用。由于,当计算 保力加通道指标时,需要添加标准离差指标到它的 移动平均线。

计算方法

StdDev = SQRT (SUM (CLOSE - SMA (CLOSE, N), N)^2)/N 

注解:

SQRT — 正方体根;

SUM (..., N) — N个周期内的总和; 

SMA (..., N) — 简单移动平均线 存在N个周期;

N —计算周期。

随机震荡指标

随机震荡技术指标比较一定时段里,价格的范围同证券价格收市值的相关情况。该振荡指标以双线来显示。主线被称为%K线,第二根线被称为%D线,它的数值是主线%K的移动平均线。%K通常显示为一个固定的曲线,而%D线则显示为点状曲线。

我们有很多方法来解释这个震荡指标,其中有三种方法比较普遍:

• 当震荡指标(%K或是%D)下降到低于某一个具体水平的时候(比如20),然后又上升到高于那个水平的时候,我们可以进行买入。当指标上升到高于某一个具体水平时(比如80),然后又回落到低于那个水平时,我们就可以卖出了;

• 我们可以在%K曲线高于%D曲线的情况下进行买入,或者在%K曲线低于%D曲线的情况下卖出;

• 寻找分离点。比如:当价格不断的创出新高,随机震荡指数未能突破它之前的新高的时候。

计算方法

随机震荡指标有四种变形:

• %K 时段:这是在计算震荡指标过程中所用到的时间段的数值;

• %K减速时段:这个数值控制着%K的内部通畅度。数值一被看作是快速随机震荡指标,而数值三则被视为慢速随机指标;

• %D时段:在计算%K移动平均线时,所用到的时间段的数值;

• %D方法:在计算%D时所使用的方法(包括简单,指数,通畅和加权)。

%K的方程式: %K = (CLOSE-LOW(%K))/(HIGH(%K)-LOW(%K))*100

注解:

CLOSE —当天的收盘价格;

LOW(%K) —%K的最低最低值; 

HIGH(%K) — %K的最高最高值

根据公式,我们可以计算出%D的移动平均线: %D = SMA(%K, N) 

注解:

N — 通畅时间段;

SMA — 简单移动平均线。

威廉指标

威廉指标是一个动态技术指标,由它来决定市场是否过度买入或买进。威廉的%R曲线和与随机震荡指标非常类似。唯一的区别在与%R曲线有上下运动的标尺,而随机震荡指标有振动指数有内部的舒张。

为了表明威廉指标的上下运动方式,我们应该在其指数前添加负号,(例如-30)不过在进行指标分析的时候,我们应忽略那个负号的存在。

在80到100%范围内变化的指标数值表明市场处于一种过度卖出状态。在0到20%范围内变化的指标数值则表示市场处于过度买入状态。

就所有过度买入或过度卖出的指标,你最好在下单之前,等待证券价格改变它的走向。如果在过度买入或是过度卖出的指标显示出过度买入的条件,那你在卖出某个证券之前等待价格的回落是非常明智的。

威廉技术指标有趣的一个现象就是它能大胆的预测基本证券价格相反趋势的能力。指标总是在证券在进行上下运动之前的几天里形成自己的波动。同样,威廉指标通常会形成一个低谷,并且在证券价格出现之前保持几天的时间。

计算方法

TBELOW是计算%R指标的方程式,这个公式和 随机震荡指标的计算方法相似: %R = (HIGH(i-n)-CLOSE)/(HIGH(i-n)-LOW(i-n))*100

注解:

CLOSE —当日收盘价

HIGH(i-n) —过去时段的最高值

外_汇_邦 WaiHuiBang.com
本文标题:MT4编程入门 - MT4平台MQL4编程学习
本文地址:https://www.waihuibang.com/fxschool/autotrading/mql4/67618.html

相关文章

  • 智能外汇交易系统是什么

    在关于投资交易的建议中笔者一直强调依赖外汇交易系统做交易的重要性,因为对于无规律的行情只有坚持固定的交易方式才能够取得更好的成功率。由此可以推出这样一个问题--智能外汇交易系统是否可靠?智能外汇交易系统...

    MQL4编程学习
  • 外汇EA的那些误区你信了吗?
    外汇EA的那些误区你信了吗?

    外汇EA交易工具相信做外汇的投资者都不陌生,甚至不少投资者如今正在使用中。它能按照您事先设定好的条件自动的买卖与交易,并且由于它是电脑自动下单,因此可以更加快速地下单和平仓。但是市场上对于外汇EA的说法却是分...

    MQL4编程学习
  • 你的EA交易为什么不能获利?

    近来从我自己以及朋友身边的一些故事有些感受,要成功使用EA获利不仅仅是一个EA的问题,还有很大部分因素“人”因为最终执行EA的是人,如果这个“人”对EA不了解,没有执行力,那么他的EA交易也是不成功的。 所以在这里我总...

    MQL4编程学习
  • 交易系统设计的原则与流程

    浅谈交易系统设计的原则与流程所谓“交易系统”,按照波涛先生的说法,就是“完整的交易规则体系”。如果把交易活动视为经营一家公司或一项事业,我们就可以借鉴企业管理的原理和方法,综合考虑人财物、产供销、信息等管...

    MQL4编程学习
  • 阿里云产品代金券、阿里云ECS云服务器优惠券及其他Aliyun ECS最新优惠活动
    阿里云产品代金券、阿里云ECS云服务器优惠券及其他Aliyun ECS最新优惠活动

    最近几年国内云主机/VPS市场竞争异常激烈,包括阿里云、腾讯云等巨头纷纷涉足云计算市场。阿里云从开始合并万网域名开始,然后单独阿里云品牌平台,通过各种资源整合、高性价比的产品和活动促销吸引到很多的国内用户,逐渐坐...

    MQL4编程学习
你可能感兴趣