发新话题
打印

[指标EA编写讨论] mt4编程代码讲解篇

本主题由 xfxyldj 于 2008-4-5 03:47 加入精华 本主题被作者加入到个人文集中 所需阅读权限 1

mt4编程代码讲解篇

开个贴子每天解释几条语句。与君共勉!
请各位不要无意义的灌水回复。谢谢!
不知道能坚持多久。也不知道对各位是否有帮助。
先写写看吧

请各位不要在主贴中回复。
有什么问题请发在副贴。使得主贴能连续起来。谢谢!
对于所讲代码的疑问可以在主贴中回复。我会给予解答。
其他无关的我会删除。谢谢合作!


副贴链接位置 请点击这里

[ 本帖最后由 xfxyldj 于 2007-9-15 16:34 编辑 ]

TOP

第一篇 创建新文件

1、打开 MetaEditor (如何打开自己想办法)呵呵,如果这个都打不开,拜托下面的也不用看了。也许你不适合研究这个。
2、选择文件-->新文件 打开文件创建页面。
3、选择第二项 客户指标  然后点下一步。
   注:这个页面可以创建6种文件。我们常用的有 《客户指标》,《脚本》,《智能交易系统》三种。我们先从指标开始。
4、输入名字,作者等等。(支持中文)暂时不添加参数。
   注:这个位置可以添加用户变量以后讲解。
5、下一步 我们先建一个主窗口指标 所以这个页面什么都不用操作
   注:这个位置可以添加指标“线”。以后提及。
6、点击完成。
ok新的指标文件生成了。但还没有任何有用的代码。初始化代码齐全。
呵呵!下一篇继续。

[ 本帖最后由 xfxyldj 于 2007-9-15 02:25 编辑 ]

TOP

新建文件的样子和各功能区。

复制内容到剪贴板
代码:
//+------------------------------------------------------------------+
//|                                                   MT4指标编辑.mq4 |
//|                                                              ldj |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "ldj"
#property link      "http://www.metaquotes.net"

#property indicator_chart_window
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- indicators
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
   int    counted_bars=IndicatorCounted();
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
上面的就是刚刚新建的一个指标文件。
第一部分  指标注释 只是一个说明,有没有都不影响指标运行。
复制内容到剪贴板
代码:
//+------------------------------------------------------------------+
//|                                                   MT4指标编辑.mq4 |
//|                                                              ldj |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+
这部分中前面的 “//” 两个斜线 说明后面的是注释语句,不参与实际运行。
第二部分  预处理语句 这部分规定了指标的窗口性质。如下:
复制内容到剪贴板
代码:
#property copyright "ldj"
#property link      "http://www.metaquotes.net"

#property indicator_chart_window
#号表示后面是预处理语句。
property 的意思是定义mt4内部变量的性质。变量名是mt4定义好的只能用固定的变量名。
例如:版权变量 copyright 链接变量 link 以及指标窗口类型变量indicator_chart_window等等。
其中窗口类型变量有indicator_chart_window(主窗口)indicator_separate_window(副窗口)两个这里只能用一个不能两个同时用
这部分内容一般不需要修改。
第三部分  初始化函数(加载函数)
复制内容到剪贴板
代码:
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- indicators
//----
   return(0);
  }
这个函数中的代码只在只在指标(EA)加载的时候执行一次。用于对一些变量的初始化。
去初注释函数体为
复制内容到剪贴板
代码:
int init()
  {
   return(0);
  }
第三部分  卸载函数
复制内容到剪贴板
代码:
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }
当去初指标(EA)的时候执行一次。用于去除一些控件。
去除注释函数体为
复制内容到剪贴板
代码:
int deinit()
  {
    return(0);
  }
第四部分  主函数,每当价格变化时就调用执行一次。主要执行代码都在这里。
复制内容到剪贴板
代码:
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
   int    counted_bars=IndicatorCounted();
//----
   
//----
   return(0);
  }
第五部分 子函数。有些指标和EA含有子函数。我习惯写在后面。
不知道我说得清楚不。

[ 本帖最后由 xfxyldj 于 2007-9-15 03:05 编辑 ]

TOP


好贴一定要顶!!没想到斑竹半夜起来为我们讲解呀!!真是另人感动呀!!
希望以后再接再厉让我们多了解些您的好东西!!谢谢!!!

TOP

首先表示感谢,也希望大家一起写,以后我们整理成一个电子书,那就非常好了

TOP

今天我们做一个双线MACD(带柱线)

代码部分!后面的帖子逐条语句分析
复制内容到剪贴板
代码:
//+------------------------------------------------------------------+
//| macd vs macd[1] |
//+------------------------------------------------------------------+
#property indicator_buffers 3
#property indicator_separate_window
#property indicator_color1 White
#property indicator_color2 Red
#property indicator_color3 Silver
//---- buffers
double Buffer1[];
double Buffer2[];
double Buffer3[];
extern int Fast = 10;
extern int Slow = 22;
extern int Signal = 7;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
  {
//---- indicators
   //IndicatorBuffers(3);
   SetIndexStyle(0,DRAW_LINE,0,1);
   SetIndexStyle(1,DRAW_LINE,0,1);
   SetIndexStyle(2,DRAW_HISTOGRAM,0,1);
   SetIndexBuffer(0,Buffer1);
   SetIndexBuffer(1,Buffer2);
   SetIndexBuffer(2,Buffer3);
   IndicatorShortName("MACD("+Fast+","+Slow+","+Signal+")");
   SetIndexLabel(0,"MACD_MAIN");
   SetIndexLabel(1,"MACD_SIGNAL");
   SetIndexLabel(2,"MAIN-SIGNAL");
   IndicatorDigits(Digits+2);
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custor indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
{
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
   int limit,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<limit; i++)
     {
      Buffer1[i]=iMACD(NULL,0,Fast,Slow,Signal,PRICE_CLOSE,MODE_MAIN,i);
      Buffer2[i]=iMACD(NULL,0,Fast,Slow,Signal,PRICE_CLOSE,MODE_SIGNAL,i);
      Buffer3[i]=Buffer1[i] - Buffer2[i];
     }
//----
   return(0);
  }
//+------------------------------------------------------------------+
附件: 您所在的用户组无法下载或查看附件

TOP

MACD1

下面我们来逐步实现这个指标。
我们要形成双线MACD和一个柱状指标。
因此我们在副图上要形成3个指标线。
主指标
信号指标
柱状指标

1、第一步确认指标显示的窗口
复制内容到剪贴板
代码:
#property indicator_separate_window
//     #property indicator_chart_window
这条代码决定了指标在副图窗口显示。下面那条注释语句表示在主图窗口也就是K线图上显示。
2、预定义3个缓冲区来显示这三个指标线
复制内容到剪贴板
代码:
#property indicator_buffers 3
#property indicator_color1 White
#property indicator_color2 Red
#property indicator_color3 Silver
#property indicator_buffers 3 语句预定义三个指标缓存区。

#property indicator_color1 White
#property indicator_color2 Red
#property indicator_color3 Silver
这三条语句为这三个指标预定义了三种颜色。
3、定义这三个指标的数组变量。
复制内容到剪贴板
代码:
double Buffer1[];
double Buffer2[];
double Buffer3[];
double定义一个浮点变量。因为是一组数所以要定义一个数组“[]”。
4、在init()函数中初始化这三个指标。
复制内容到剪贴板
代码:
//IndicatorBuffers(3);
   SetIndexStyle(0,DRAW_LINE,0,1);
   SetIndexStyle(1,DRAW_LINE,0,1);
   SetIndexStyle(2,DRAW_HISTOGRAM,0,1);
   SetIndexBuffer(0,Buffer1);
   SetIndexBuffer(1,Buffer2);
   SetIndexBuffer(2,Buffer3);
   IndicatorShortName("MACD("+Fast+","+Slow+","+Signal+")");
   SetIndexLabel(0,"MACD_MAIN");
   SetIndexLabel(1,"MACD_SIGNAL");
   SetIndexLabel(2,"MAIN-SIGNAL");
   IndicatorDigits(Digits+2);
IndicatorBuffers(3);//定义缓冲区的数量最多八个。因为这个指标只需要三个主缓冲区。所有这个有无都可以。有些需要辅助数组就需要定义这个。以后用到的时候再提起。

SetIndexStyle(0,DRAW_LINE,0,1);//定义指标的显示形式。DRAW_LINE标示画线指标。
看下这个内置函数的定义
SetIndexStyle( int index, int type, int style=EMPTY, int width=EMPTY, color clr=CLR_NONE)
  index:索引号。0就是第一个指标线1就是第二个指标线。
  type: 指标类型 下面是可选参数都是MT4的标准常量。
       DRAW_LINE      = 0 画线
       DRAW_SECTION   = 1 画线段
       DRAW_HISTOGRAM = 2 画柱状图
       DRAW_ARROW     = 3 画箭头符号(需要设置符号代码)
       DRAW_ZIGZAG    = 4 画锯齿图
       DRAW_NONE      = 12 不画图
  style:指标线型 0~4的选择。也可以不要,默认为0。
  Width:指标线宽 1~5的选择。也可以不要,默认为1。
  clr:  指标颜色 一般用#property indicator_color1 White语句定义。前面定义了所以我们这里没有定义。

SetIndexBuffer(0,Buffer1);//为定义的指标变量数组标记索引号。就是使他们一一对应。
  0号索引对应Buffer1[]变量。依此类推

IndicatorShortName("MACD("+Fast+","+Slow+","+Signal+")");//设置指标显示的名称,内容是用+号连接的字符串。
   就是当鼠标放在指标上所看到的指标名称。与文件名不相关。

SetIndexLabel(0,"MACD_MAIN");//设置指标的标记。就是当鼠标放在指标线上显示的第三行的名称。
   这条语句的意思是0号索引对应的指标变量标记是MACD_MAIN。其他类推。

IndicatorDigits(Digits+2);//定义指标的小数点位数数值是整数。这里Digits是MT4的预定义变量。其值为当前货币兑的小数位。

注:郁闷,东西不多解释起来还真麻烦,希望大家能看懂

[ 本帖最后由 xfxyldj 于 2007-9-15 20:38 编辑 ]

TOP

解释得很清楚。谢谢啊。
哪里能看到内置函数的定义?
另外,这些:
       DRAW_LINE      = 0 画线
       DRAW_SECTION   = 1 画线段
       DRAW_HISTOGRAM = 2 画柱状图
       DRAW_ARROW     = 3 画箭头符号(需要设置符号代码)
       DRAW_ZIGZAG    = 4 画锯齿图
       DRAW_NONE      = 12 不画图
从哪里能够看到?
认真地坚持做自己喜欢做的事情。兴趣比结果更重要。
我的blog:http://linlisun.blog.hexun.com/

TOP

回复 8楼 的帖子

在MetaEditor的《导航》面板区域可以找到。
不过全都是英文的。我英文巨烂。
字典选项里面有。
这些都是帮助文件里的。

TOP

主函数体

有点儿失眠,又静不下心写程序。所以来把最后一段说明下。
复制内容到剪贴板
代码:
int start()
  {
   int limit,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++)
     {
      Buffer1[i]=iMACD(NULL,0,Fast,Slow,Signal,PRICE_CLOSE,MODE_MAIN,i);
      Buffer2[i]=iMACD(NULL,0,Fast,Slow,Signal,PRICE_CLOSE,MODE_SIGNAL,i);
      Buffer3[i]=Buffer1[i] - Buffer2[i];
     }
   return(0);
  }
1、int limit,counted_bars=IndicatorCounted();//定义两个整形变量,并给counted_bars变量负值。
   这里面IndicatorCounted()函数是mt4内置函数不需要参数,其返回值为已经计算过的指标数组数量。
   如果指标错误则这个函数会返回一个负数。
2、if(counted_bars<0) return(-1); //如果条件成立说明指标调用运行错误。则退出程序。
3、if(counted_bars>0) counted_bars--;//从已经计算的指标中去除最后一条。
   这条语句用来修正counted_bars使得已经计算的最后一个数值可以在接下来的运算中重新计算一次。
4、limit=Bars-counted_bars;//计算需要计算的指标数据的柱数。
   这里需要说明。在mt4中指标数组的索引和K线的索引标记相同,是从后向前递增的从0开使的整数。
   也就是说,最后一条K线的索引是0同时K线所对应的指标索引也是0。
   那么倒数第2条的索引标记为1。倒数第三条的索引标记为2。
   这一点一定要理解清楚。不然写程序的时候就会发生错误。
   语句中的Bars是mt4预定义变量,其值是当前图表中K线的条数。
   
   这里详细说下为什么有个counted_bars--;的语句,这个语句的意思是对变量counted_bars进行自减一操作。
   因为主函数是每次价格变动就会运行一次。当运行完成后。IndicatorCounted()值应该等于Bars也就是K线的条数
   如果没有上面的自减一操作,那么当价格变动有了新的收盘价但并没有生成新的K线。这时候计算limit的值将=0.
   那么下面的for循环体将不会再计算最后一条k线相对应的指标数值。
   实际上这个是需要计算的(因为有了新的收盘价)。而有了自减一的操作就可以对最有一个,也就是当前K线对应的指标值进行运算。
   (不知道能看明白不自己慢慢捉摸捉摸)。这个自减一是必需的。
5、for(int i=0; i<limit; i++) for 循环语句(因为有了前面的自减一操作,这里limit最小等于1)
   关于for循环的运行不作解释。各位自己找资料学习。
6、Buffer1[ i ]=iMACD(NULL,0,Fast,Slow,Signal,PRICE_CLOSE,MODE_MAIN,i); //调用MACD指标函数为Buffer1数组负值。
   看下iMACD()这个内置指标函数的定义。
   iMACD( string symbol, int timeframe, int fast_ema_period, int slow_ema_period, int signal_period, int applied_price, int mode, int shift)
   symbol:           货币标识。通用指标用NULL常量。
   timeframe:        计算所依据的图表时间周期 。0表示依据当前图表周期。
   fast_ema_period: 快线周期
   slow_ema_period: 慢线周期
   signal_period:   信号线周期
   applied_price:   计算所用价格模式
   mode:             指标索引模式。MACD指标有两条线,因此这个位置有0,1两个选择。也可以用mt4预定义常量。
   shift:            索引号
  
   这里Buffer1取macd主线数据。Buffer2取macd信号线数据。
7、Buffer3[ i ]=Buffer1[ i ] - Buffer2[ i ];//计算MACD两条线之间的距离。

8、这里用到了外部变量。也可以叫用户自定义变量。这种变量在加载图表的时候可以修改。
复制内容到剪贴板
代码:
extern int Fast = 10;
extern int Slow = 22;
extern int Signal = 7;
extern 关键字说明后面定义的变量是外部变量。
这里贴下iMACD()函数的英文说明。
double iMACD( string symbol, int timeframe, int fast_ema_period, int slow_ema_period, int signal_period, int applied_price, int mode, int shift)
Calculates the Moving averages convergence/divergence and returns its value. In the systems where OsMA is called MACD Histogram, this indicator is displayed as two lines. In the Client Terminal, the Moving Average Convergence/Divergence is drawn as a histogram.
Parameters:
symbol   -   Symbol the data of which should be used to calculate indicator. NULL means the current symbol.
timeframe   -   Timeframe. It can be any of Timeframe enumeration values. 0 means the current chart timeframe.
fast_ema_period   -   Number of periods for fast moving average calculation.
slow_ema_period   -   Number of periods for slow moving average calculation.
signal_period   -   Number of periods for signal moving average calculation.
applied_price   -   Applied price. It can be any of Applied price enumeration values.
mode   -   Indicator line index. It can be any of the Indicators line identifiers enumeration value.
shift   -   Index of the value taken from the indicator buffer (shift relative to the current bar the given amount of periods ago).

Sample:
if(iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,0)>iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_SIGNAL,0)) return(0);
英文好的自己看吧。我看着很累。

[ 本帖最后由 xfxyldj 于 2007-9-16 02:44 编辑 ]

TOP

发新话题