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”。
ool 能否报警=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)、日K图(PERIOD_D1)、周线图(PERIOD_W1)、周线图(PERIOD_W1)、月线图(PERIOD_W1)
例:
iOpen("美元兑日元",PERIOD_H1,0) 表明USDJPY1小时图最新K线蜡烛的开盘价
iClose("欧元兑美元",PERIOD_H4,2) 表明EURUSD4小时图第3根K线蜡烛的收盘价
iClose("英镑兑美元",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)
价格种类:收盘价(PR洲际交易所_CLOSE)、开盘价(PR洲际交易所_OPEN)、最高价(PR洲际交易所_HIGH)、最低价(PR洲际交易所_LOW)、中值(PR洲际交易所_MEDIAN)、5(PR洲际交易所_TYPICAL)、6(PR洲际交易所_WEIGHTED)
例1:iMA("欧元兑美元",PERIOD_H1,20,0,MODE_SMA,PR洲际交易所_CLOSE,0)
表明:欧元1小时图上,以收盘价计算的,20小时简单移动平均线,最新K线所对应位置的值
例2:iMA(NULL,0,20,0,MODE_EMA,PR洲际交易所_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)
{
=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)
{
uffer[i]= iMA(NULL,0,快线,0,MODE_EMA,PR洲际交易所_CLOSE,i)
-iMA(NULL,0,慢线,0,MODE_EMA,PR洲际交易所_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++)
{
uffer[i]= iMA(NULL,0,快线,0,MODE_EMA,PR洲际交易所_CLOSE,i)
-iMA(NULL,0,慢线,0,MODE_EMA,PR洲际交易所_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()就运行一次。
自定义指标的编程首要依靠此函数执行。
tart()函数的作用首要是取值和给指标线赋值,报警亦在此函数内发起。
此外,仍有一个反初始化函数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 { uf[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 循环语句。 循环从i=0开始,每循环一次i值增长1,一直循环到i 受于循环变量i为一个新变量,所以要先定义,加之整型变量定义符int 下面大括中为循环体,此例中只一条语句 { uf[i]= iMA(NULL,0,FMA,0,1,0,i) -iMA(NULL,0,SMA,0,1,0,i); } 给数组buf赋值,其值分别为相应位置上两条均线的差 i是水平位置序号值,即烛柱从右到左的序号,右边第一个烛柱序号为0 return(0);
tart函数终结
}
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,PR洲际交易所_CLOSE,0)
amp;& iHigh(0,0,1) < iMA(0,0,警戒均线,0,MODE_SMA,PR洲际交易所_CLOSE,1)
amp;& mark != 1 )
{
Alert(Symbol(),"往上刷新30均线");
mark = 1;
}
if( iLow(0,0,0) <= iMA(0,0,警戒均线,0,MODE_SMA,PR洲际交易所_CLOSE,0)
amp;& iLow(0,0,1) > iMA(0,0,警戒均线,0,MODE_SMA,PR洲际交易所_CLOSE,1)
amp;& mark != 2 )
{
Alert(Symbol(),"朝下刷新",警戒均线,"均线");
mark = 2;
}
return(0);
}
+---------------------------------
部分语句表明:
#property indicator_chart_window
此句是把程序放在主图,诚然这此例中放在副图也一样
extern int 定义一个外部参数变量,整数型,允许外部值修改
int 定义一个整数型变量
int start() 定义触发函数
if() 分析
iHigh() 最高价值函数
iLow() 最低价值函数
iMA() 移动平均线值函数
Alert() 报警函数
Symbol() 商品名称函数
amp;& 逻辑运算符“而且”
!= 逻辑运算符“不等于”
MODE_SMA 简单移动平均模式
PR洲际交易所_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,PR洲际交易所_CLOSE,0)
amp;& iHigh(0,0,1) < iMA(0,0,警戒均线,0,MODE_SMA,PR洲际交易所_CLOSE,1)
amp;& 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,PR洲际交易所_CLOSE,0)
amp;& iLow(0,0,1) > iMA(0,0,警戒均线,0,MODE_SMA,PR洲际交易所_CLOSE,1)
amp;& mark != 2 )
{
Alert(Symbol(),"朝下刷新",警戒均线,"均线");
mark = 2;
}
return(0);
tart函数终结语句,返回零值
}
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 { 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] if(Close[i] } 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 循环语句,括号中有三个语句: 第一句int i=0; 表明循环从i=0开始 第二句i 第三句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] 条件分析语句。假使在i位置上价格大于均线,而且在(i+1)位置上价格差于均线(即价格上穿均线),则给数组mk在i位置上赋该位置的均线值 Close[i]:在i位置上收盘价。 amp;&:逻辑运算符“而且” if(Close[i] 与上一句类似 } return(0);
tart函数终结语句
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 商品="英镑兑美元";
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 ind_buffer[i]=iRSI(商品,0,RSI,PR洲际交易所_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 商品="英镑兑美元";
设立一个自定义变量,允许外部值修改,字符串型,变量名叫"商品",默认值"英镑兑美元"
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 循环语句,括号中有三个语句: 第一句int i=0; 表明循环从i=0开始 第二句i 第三句i++,这是循环步调控制语句,每循环一次后实施一次此语句。 i++相当于i=i+1,即i值在原有数值上增长1 ind_buffer[i]=iRSI(商品,0,RSI,PR洲际交易所_CLOSE,i); 此语句为循环体,受于只有一个语句,所以省略花括号 i为图表烛柱的序号,从0开始,右边第1柱序号为0,从右向左递增 iRSI为RSI指标的取值函数 return(0);
tart函数终结
}
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()