下载MetaTrader 5

创建具有图形控制选项的指标

4 十二月 2013, 07:16
Vasily
1
1 012

简介

熟悉市场情绪的人都知道 MACD 指标(其全称为平滑异同移动平均线)- 自计算机分析方法面世以来即已被交易人员用于分析价格变动的强大工具。

长久以来,我都在研究这个在图表中占得一席之地的 MACD 指标。我接触过这一指标的多种不同类型,它们具有不同的选项和不同的计算算法,因此我决定在指标中结合我所知道的所有类型。

MACD 指标的类型

指标将具有传统的 MACD 线和 oSMA 直方图。下面我们定义 MACD 的主要变型:
  1. Elder MACD,也称为冲量系统;
  2. Elder MACD,无移动线检查;
  3. oSMA,使用不同的颜色绘制上涨和下跌情形;
  4. 仅绘制 oSMA 直方图;
  5. 仅绘制 MACD 线;

指标的初始设置

我们将需要以下参数用于计算:

  1. MACD 快线的值;
  2. MACD 慢线的值;
  3. MACD 信号线的值;
  4. Elder 方法的趋势检验线的值;

要绘制该指标,我们还需要以下内容:

  1. MACD 线;
  2. 信号线;
  3. 三色 OSMA 直方图。

转到“MQL5 向导”菜单:

图 1. 使用“MQL5 向导”创建指标


图 2. 在“MQL5 向导”中定义常用指标参数


图 3. 在“MQL5 向导”中定义指标的绘图属性

创建指标

我们已获得指标的初始模板。首先,我们需要计算指标的 MACD 线。

我们不会深入探究计算该线的精确公式 - 我们将使用 iMACD 函数:

int iMACD (
   string symbol,           // 交易品种名称
   ENUM_TIMEFRAMES period,   // 时间周期
   int fast_ema_period,    //  快速EMA周期
   int slow_ema_period,    // 慢速EMA周期
   int signal_period,      // 信号线的平滑周期
   ENUM_APPLIED_PRICE applied_price // 价格类型或者是一个句柄
   )

该函数返回合适指标副本的句柄。使用此句柄,就有可能获得该指标计算得到的数据。可使用函数 CopyBuffer() 复制来自指标缓冲区的数据(技术指标在其自身的内部缓冲区中包含计算得出的数据,取决于指标,最多可以有 5 个缓冲区)。

接下来,我们使用函数 iMACD 为 MACD 数据生成请求:

int MACDhadling =  iMACD(NULL,0,Fast,Slow,Signal,PRICE_CLOSE);

它将返回指标副本的句柄。

我们通过函数 CopyBuffer 将数据复制到必要缓冲区中:

int  CopyBuffer(
   int       indicator_handle,     // 指标句柄
   int       buffer_num,           // 指标的缓存数量
   int       start_pos,            // 开始位置 
   int       count,                // 要复制的数据数量
   double    buffer[]              // 用于复制数据的目标数组
   );

现在,让我们请求指标的 MACD 线:

CopyBuffer(MACDhadling,0,0,NewData,MACDlineBuffer);

我们获得指标的信号线:

CopyBuffer(MACDhadling,1,0,NewData,SignallineBuffer);

我们将其聚集在一起,看看我们获得了什么:

int MACDhadling=iMACD(NULL,0,Fast,Slow,Signal,PRICE_CLOSE);
CopyBuffer(MACDhadling,0,0,rates_total,MACDlineBuffer);
CopyBuffer(MACDhadling,1,0,rates_total,SignallineBuffer);

现在我们有了计算的 MACD 和信号线。

我们继续。

由于来自

MACDlineBuffer

缓冲区的数据以及

SignallineBuffer

缓冲区是通过复制获得的,它们的索引从图表末尾处开始。

以往,对价格数组数据的访问是从数据的末尾执行。实际上,新数据总是写入数组的末尾,而当前(未完成)柱的索引始终等于零。在时序数组中,索引为 0 表示当前柱的数据,当前柱对应于该时间表的未完成时间间隔。

为了在所有缓冲区中使用相同的索引方向,我们应将其他缓冲区定义为时序型。

ArraySetAsSeries(HistogramBuffer,false);
ArraySetAsSeries(HistogramColors,false);

我们需要获得直方图的数据,这通过从 MACD 线减去信号线计算得出:

for(int i=0;i<rates_total;i++)
  {
   HistogramBuffer[i]=MACDlineBuffer[i]-SignallineBuffer[i];
  
}

我们将所有内容结合在一起:

ArraySetAsSeries(HistogramBuffer,false);
ArraySetAsSeries(HistogramColors,false);

int MACDhadling=iMACD(NULL,0,Fast,Slow,Signal,PRICE_CLOSE);
CopyBuffer(MACDhadling,0,0,rates_total,MACDlineBuffer);
CopyBuffer(MACDhadling,1,0,rates_total,SignallineBuffer);

for(int i=0;i<rates_total;i++)
  {
   HistogramBuffer[i]=MACDlineBuffer[i]-SignallineBuffer[i];
   HistogramColors[i]=1; 
  
}


创建指标控制的图形系统

我们有该指标的 5 种变型。

首先,我们实施第三项和第四项。

    3. 仅绘制 oSMA 直方图;
    4. 仅绘制 MACD 线。

我们来创建适当的按钮。

项目 4:

ObjectCreate(0,"ShowMACD",OBJ_BUTTON,ChartWindowFind(),100,100);   //创建按钮
ObjectSetInteger(0,"ShowMACD",OBJPROP_XDISTANCE,75);              //分配坐标
ObjectSetInteger(0,"ShowMACD",OBJPROP_YDISTANCE,5);
ObjectSetInteger(0,"ShowMACD",OBJPROP_CORNER,CORNER_RIGHT_UPPER);  // 以及一个标定点
ObjectSetString(0,"ShowMACD",OBJPROP_TEXT,"ShowMACD");            // 按钮标签 
ObjectSetInteger(0,"ShowMACD",OBJPROP_FONTSIZE,8);
ObjectSetInteger(0,"ShowMACD",OBJPROP_XSIZE,70);                 //按钮大小 
ObjectSetInteger(0,"ShowMACD",OBJPROP_YSIZE,20);
ObjectSetInteger(0,"ShowMACD",OBJPROP_SELECTABLE,false);         // 使它可选

对于意外按钮删除或其在下一订单号的平移,按钮将返回。

项目 3:

ObjectCreate(0,"ShowOsMA",OBJ_BUTTON,ChartWindowFind(),100,100);
ObjectSetInteger(0,"ShowOsMA",OBJPROP_XDISTANCE,75);
ObjectSetInteger(0,"ShowOsMA",OBJPROP_YDISTANCE,30);
ObjectSetInteger(0,"ShowOsMA",OBJPROP_CORNER,CORNER_RIGHT_UPPER);
ObjectSetString (0,"ShowOsMA",OBJPROP_TEXT,"Show OsMA");
ObjectSetInteger(0,"ShowOsMA",OBJPROP_FONTSIZE,8);
ObjectSetInteger(0,"ShowOsMA",OBJPROP_XSIZE,70);
ObjectSetInteger(0,"ShowOsMA",OBJPROP_YSIZE,20);
ObjectSetInteger(0,"ShowOsMA",OBJPROP_SELECTABLE,false);

让我们针对情形 4 的按下和未按下按钮创建实施。

这要求查看缓冲区索引。

SetIndexBuffer(0,MACDlineBuffer,INDICATOR_DATA);
SetIndexBuffer(1,SignallineBuffer,INDICATOR_DATA);
SetIndexBuffer(2,HistogramBuffer,INDICATOR_DATA);
SetIndexBuffer(3,HistogramColors,INDICATOR_COLOR_INDEX);
if(ObjectGetInteger(0,"ShowMACD",OBJPROP_STATE)!=1)
  {
   PlotIndexSetInteger(0,PLOT_DRAW_TYPE,DRAW_NONE); // 索引为0的缓存不绘制
   PlotIndexSetInteger(1,PLOT_DRAW_TYPE,DRAW_NONE); // 索引为1的缓存也不绘制
  
}
else
  {
   PlotIndexSetInteger(0,PLOT_DRAW_TYPE,DRAW_LINE); // 索引为0的缓存绘制成线
   PlotIndexSetInteger(1,PLOT_DRAW_TYPE,DRAW_LINE); // 索引为1的缓存也绘制成线
  
}

按下按钮,绘制 MACD 线;未按下则不会绘制 MACD 线。

让我们针对情形 3 的按下和未按下按钮创建实施。

if(ObjectGetInteger(0,"ShowOsMA",OBJPROP_STATE)!=1)
  {
   //索引为2的缓存不绘制
   PlotIndexSetInteger(2,PLOT_DRAW_TYPE,DRAW_NONE);
  
}
else
  {
   //索引为2的缓存绘制成一个彩色直方图
   PlotIndexSetInteger(2,PLOT_DRAW_TYPE,DRAW_COLOR_HISTOGRAM);
  
}

我们创建两个按钮:"2color" 和 "Impulse",并将它们放置在图表的右下角处。

ObjectCreate(0,"2color",OBJ_BUTTON,ChartWindowFind(),100,100);
ObjectSetInteger(0,"2color",OBJPROP_XDISTANCE,75);
ObjectSetInteger(0,"2color",OBJPROP_YDISTANCE,50);
ObjectSetInteger(0,"2color",OBJPROP_CORNER,CORNER_RIGHT_LOWER);
ObjectSetInteger(0,"2color",OBJPROP_FONTSIZE,8);
ObjectSetInteger(0,"2color",OBJPROP_XSIZE,70);
ObjectSetInteger(0,"2color",OBJPROP_YSIZE,20);
ObjectSetInteger(0,"2color",OBJPROP_SELECTABLE,false);
ObjectSetString (0,"2color",OBJPROP_TEXT,"MultiColor");

ObjectCreate(0,"Impulse",OBJ_BUTTON,ChartWindowFind(),100,100);
ObjectSetInteger(0,"Impulse",OBJPROP_XDISTANCE,75);
ObjectSetInteger(0,"Impulse",OBJPROP_YDISTANCE,25);
ObjectSetInteger(0,"Impulse",OBJPROP_CORNER,CORNER_RIGHT_LOWER);
ObjectSetInteger(0,"Impulse",OBJPROP_FONTSIZE,8);
ObjectSetInteger(0,"Impulse",OBJPROP_XSIZE,70);
ObjectSetInteger(0,"Impulse",OBJPROP_YSIZE,20);
ObjectSetInteger(0,"Impulse",OBJPROP_SELECTABLE,false);

对于基于 Elder 系统的冲量检查,我们需要添加一个新的数组用于放置 EldersMA 值。

为此,我们需要将缓冲区的总数量加一。+

#property indicator_buffers 4

应更改为:

#property indicator_buffers 5

并声明一个新缓冲区。

double EldersiEMA[];

我们将它定义为缓冲区以用于内部计算:

SetIndexBuffer(4,EldersiEMA,INDICATOR_CALCULATIONS);

现在,我们将指数移动平均线值复制到缓冲区:

// you can do all in single line
CopyBuffer(iMA(NULL,0,EldersEMA,0,MODE_EMA,PRICE_CLOSE),0,0,rates_total,EldersiEMA); 

由于缓冲区通过复制功能获得,其索引和图表其他缓冲区的索引一样,都是从图表末尾开始。

现在,让我们写下 2 色 OsMA 的条件:

if (ObjectGetInteger(0,"2color",OBJPROP_STATE))
  {
   for(int i=1;i<rates_total;i++)
     {
      // 如果直方图上升,则将颜色设置为0
      if(HistogramBuffer[i] > HistogramBuffer[i-1]) HistogramColors[i]=0;
      // 如果直方图下降,则将颜色设置为1
      if(HistogramBuffer[i] < HistogramBuffer[i-1]) HistogramColors[i]=1;
     
}
  
}
else
  {
   ObjectSetString(0,"2color",OBJPROP_TEXT,"MultiColor");
   // 这里是多种颜色OSMA的条件
  
}

颜色索引在线中指定:

#property indicator_label3  "Histogram"
#property indicator_type3   DRAW_COLOR_HISTOGRAM
#property indicator_color3  DeepSkyBlue,Red,Green

第一种颜色的索引等于 0,第二种颜色的索引等于 1,依此类推。

现在,让我们写下冲量系统变型的条件:

if (ObjectGetInteger(0,"Impulse",OBJPROP_STATE)) // // "Impulse" 按钮被点击
  {
   ObjectSetString(0,"Impulse",OBJPROP_TEXT,"Impulse");  // 使用MACD线来判断趋势
   for(int i=1;i<rates_total;i++)
     {
      // 直方图上升并且MACD线上升
      if((HistogramBuffer[i]>HistogramBuffer[i-1]) && (MACDlineBuffer[i]>MACDlineBuffer[i-1])) HistogramColors[i]=0;
      else
        {
         // 直方图下降并且MACD线下降 
         if((HistogramBuffer[i]<HistogramBuffer[i-1]) && (MACDlineBuffer[i]<MACDlineBuffer[i-1])) HistogramColors[i]=1;
         else HistogramColors[i]=2; // 如果不符合任何条件
        
}
     
}
  
}
else 
  {
   ObjectSetString(0,"Impulse",OBJPROP_TEXT,"Elder's");  // 使用EMA线检查是否出现趋势
   for(int i=1;i<rates_total;i++)
     {
      // 直方图上升并且EMA线上升
      if((HistogramBuffer[i]>HistogramBuffer[i-1]) && (EldersiEMA[i]>EldersiEMA[i-1])) HistogramColors[i]=0;
      else
        {
         // 直方图下降并且EMA线下降 
         if((HistogramBuffer[i]<HistogramBuffer[i-1]) && (EldersiEMA[i]<EldersiEMA[i-1])) HistogramColors[i]=1;
         else HistogramColors[i]=2;// 如果不符合任何条件
        
}
     
}
  
}

现在,我们将冲量系统条件添加至 OsMA 绘制条件:

if (ObjectGetInteger(0,"2color",OBJPROP_STATE))
  {
   for(int i=1;i<rates_total;i++)
     {
      if(HistogramBuffer[i] > HistogramBuffer[i-1]) HistogramColors[i]=0;
      if(HistogramBuffer[i] < HistogramBuffer[i-1]) HistogramColors[i]=1;
     
}
  
}
else
  {
   ObjectSetString(0,"2color",OBJPROP_TEXT,"MultiColor");
   if(ObjectGetInteger(0,"Impulse",OBJPROP_STATE))
     {
      ObjectSetString(0,"Impulse",OBJPROP_TEXT,"Impulse");
      for(int i=1;i<rates_total;i++)
        {
         if((HistogramBuffer[i]>HistogramBuffer[i-1]) && (MACDlineBuffer[i]>MACDlineBuffer[i-1])) HistogramColors[i]=0;
         else
           {
            if((HistogramBuffer[i]<HistogramBuffer[i-1]) && (MACDlineBuffer[i]<MACDlineBuffer[i-1])) HistogramColors[i]=1;
            else HistogramColors[i]=2;
           
}
        
}
     
}
   else 
     {
      ObjectSetString(0,"Impulse",OBJPROP_TEXT,"Elder's");
      for(int i=1;i<rates_total;i++)
        {
         if((HistogramBuffer[i]>HistogramBuffer[i-1]) && (EldersiEMA[i]>EldersiEMA[i-1])) HistogramColors[i]=0;
         else
           {
            if((HistogramBuffer[i]<HistogramBuffer[i-1]) && (EldersiEMA[i]<EldersiEMA[i-1])) HistogramColors[i]=1;
            else HistogramColors[i]=2;
           
}
        
}
     
}
  
}

现在,我们编写条件以防止不必要的按钮闪烁:

if (ObjectGetInteger(0,"2color",OBJPROP_STATE)) ObjectSetString (0,"2color",OBJPROP_TEXT,"2ColorMACD");
else ObjectSetString(0,"2color",OBJPROP_TEXT,"MultiColor");
if (ObjectGetInteger(0,"Impulse",OBJPROP_STATE)) ObjectSetString (0,"Impulse",OBJPROP_TEXT,"Impulse");
else ObjectSetString(0,"Impulse",OBJPROP_TEXT,"Elder's")

我们删除改变按钮文本的代码。

将所有内容结合在一起:

//+------------------------------------------------------------------
//|                                            MACD_By_CoreWinTT.mq5 |
//|                        Copyright 2010, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------
#property copyright "2010, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"
#property indicator_separate_window
#property indicator_buffers 5
#property indicator_plots   3
//---- 绘制 MACD线
#property indicator_label1  "MACDline"
#property indicator_type1   DRAW_LINE
#property indicator_color1  Green
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//---- 绘制信号线
#property indicator_label2  "Signalline"
#property indicator_type2   DRAW_LINE
#property indicator_color2  Red
#property indicator_style2  STYLE_SOLID
#property indicator_width2  1
//---- 绘制直方图
#property indicator_label3  "Histogram"
#property indicator_type3   DRAW_COLOR_HISTOGRAM
#property indicator_color3  DeepSkyBlue,Red,Green
#property indicator_style3  STYLE_SOLID
#property indicator_width3  2

//--- 输入参数
input int      Fast=12;
input int      Slow=26;
input int      Signal=9;
input int      EldersEMA=13;
//--- 指标缓存
double         MACDlineBuffer[];
double         SignallineBuffer[];
double         HistogramBuffer[];
double         HistogramColors[];
double         EldersiEMA[];
//+------------------------------------------------------------------
//| 自定义指标初始化函数                                                         |
//+------------------------------------------------------------------
int OnInit()
  {
//--- 指标缓存映射
   SetIndexBuffer(0,MACDlineBuffer,INDICATOR_DATA);
   SetIndexBuffer(1,SignallineBuffer,INDICATOR_DATA);
   SetIndexBuffer(2,HistogramBuffer,INDICATOR_DATA);
   SetIndexBuffer(3,HistogramColors,INDICATOR_COLOR_INDEX);
   SetIndexBuffer(4,EldersiEMA,INDICATOR_CALCULATIONS);
//---
   return(0);
  
}
//+------------------------------------------------------------------
//| 自定义指标迭代函数                                                 |
//+------------------------------------------------------------------
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
   ArraySetAsSeries(HistogramBuffer,false);
   ArraySetAsSeries(HistogramColors,false);

   int MACDhadling=iMACD(NULL,0,Fast,Slow,Signal,PRICE_CLOSE);
   CopyBuffer(MACDhadling,0,0,rates_total,MACDlineBuffer);
   CopyBuffer(MACDhadling,1,0,rates_total,SignallineBuffer);

   for(int i=0;i<rates_total;i++) { HistogramBuffer[i]=MACDlineBuffer[i]-SignallineBuffer[i];HistogramColors[i]=1; }

   ObjectCreate(0,"ShowMACD",OBJ_BUTTON,ChartWindowFind(),100,100);
   ObjectSetInteger(0,"ShowMACD",OBJPROP_XDISTANCE,75);
   ObjectSetInteger(0,"ShowMACD",OBJPROP_YDISTANCE,5);
   ObjectSetInteger(0,"ShowMACD",OBJPROP_CORNER,CORNER_RIGHT_UPPER);
   ObjectSetString(0,"ShowMACD",OBJPROP_TEXT,"ShowMACD");
   ObjectSetInteger(0,"ShowMACD",OBJPROP_FONTSIZE,8);
   ObjectSetInteger(0,"ShowMACD",OBJPROP_XSIZE,70);
   ObjectSetInteger(0,"ShowMACD",OBJPROP_YSIZE,20);
   ObjectSetInteger(0,"ShowMACD",OBJPROP_SELECTABLE,false);

   ObjectCreate(0,"ShowOsMA",OBJ_BUTTON,ChartWindowFind(),100,100);
   ObjectSetInteger(0,"ShowOsMA",OBJPROP_XDISTANCE,75);
   ObjectSetInteger(0,"ShowOsMA",OBJPROP_YDISTANCE,30);
   ObjectSetInteger(0,"ShowOsMA",OBJPROP_CORNER,CORNER_RIGHT_UPPER);
   ObjectSetString(0,"ShowOsMA",OBJPROP_TEXT,"Show OsMA");
   ObjectSetInteger(0,"ShowOsMA",OBJPROP_FONTSIZE,8);
   ObjectSetInteger(0,"ShowOsMA",OBJPROP_XSIZE,70);
   ObjectSetInteger(0,"ShowOsMA",OBJPROP_YSIZE,20);
   ObjectSetInteger(0,"ShowOsMA",OBJPROP_SELECTABLE,false);

   if(ObjectGetInteger(0,"ShowMACD",OBJPROP_STATE)!=1) 
     {
      PlotIndexSetInteger(0,PLOT_DRAW_TYPE,DRAW_NONE);
      PlotIndexSetInteger(1,PLOT_DRAW_TYPE,DRAW_NONE);
     
}
   else 
     {
      PlotIndexSetInteger(0,PLOT_DRAW_TYPE,DRAW_LINE);
      PlotIndexSetInteger(1,PLOT_DRAW_TYPE,DRAW_LINE);
     
}

   if(ObjectGetInteger(0,"ShowOsMA",OBJPROP_STATE)!=1) 
     {
      PlotIndexSetInteger(2,PLOT_DRAW_TYPE,DRAW_NONE);
     
}
   else 
     {
      PlotIndexSetInteger(2,PLOT_DRAW_TYPE,DRAW_COLOR_HISTOGRAM);
     
}

   ObjectCreate(0,"2color",OBJ_BUTTON,ChartWindowFind(),100,100);
   ObjectSetInteger(0,"2color",OBJPROP_XDISTANCE,75);
   ObjectSetInteger(0,"2color",OBJPROP_YDISTANCE,50);
   ObjectSetInteger(0,"2color",OBJPROP_CORNER,CORNER_RIGHT_LOWER);
   ObjectSetInteger(0,"2color",OBJPROP_FONTSIZE,8);
   ObjectSetInteger(0,"2color",OBJPROP_XSIZE,70);
   ObjectSetInteger(0,"2color",OBJPROP_YSIZE,20);
   ObjectSetInteger(0,"2color",OBJPROP_SELECTABLE,false);
   ObjectSetString(0,"2color",OBJPROP_TEXT,"MultiColor");

   ObjectCreate(0,"Impulse",OBJ_BUTTON,ChartWindowFind(),100,100);
   ObjectSetInteger(0,"Impulse",OBJPROP_XDISTANCE,75);
   ObjectSetInteger(0,"Impulse",OBJPROP_YDISTANCE,25);
   ObjectSetInteger(0,"Impulse",OBJPROP_CORNER,CORNER_RIGHT_LOWER);
   ObjectSetInteger(0,"Impulse",OBJPROP_FONTSIZE,8);
   ObjectSetInteger(0,"Impulse",OBJPROP_XSIZE,70);
   ObjectSetInteger(0,"Impulse",OBJPROP_YSIZE,20);
   ObjectSetInteger(0,"Impulse",OBJPROP_SELECTABLE,false);
   ObjectSetString(0,"Impulse",OBJPROP_TEXT,"Impulse");

   if(ObjectGetInteger(0,"2color",OBJPROP_STATE)) ObjectSetString(0,"2color",OBJPROP_TEXT,"2ColorMACD");
   else ObjectSetString(0,"2color",OBJPROP_TEXT,"MultiColor");
   if(ObjectGetInteger(0,"Impulse",OBJPROP_STATE)) ObjectSetString(0,"Impulse",OBJPROP_TEXT,"Impulse");
   else ObjectSetString(0,"Impulse",OBJPROP_TEXT,"Elder's");

   CopyBuffer(iMA(NULL,0,EldersEMA,0,MODE_EMA,PRICE_CLOSE),0,0,rates_total,EldersiEMA);

   if(ObjectGetInteger(0,"2color",OBJPROP_STATE))
     {
      for(int i=1;i<rates_total;i++)
        {
         if(HistogramBuffer[i] > HistogramBuffer[i-1]) HistogramColors[i]=0;
         if(HistogramBuffer[i] < HistogramBuffer[i-1]) HistogramColors[i]=1;
        
}
     
}
   else
     {
      if(ObjectGetInteger(0,"Impulse",OBJPROP_STATE))
        {
         for(int i=1;i<rates_total;i++)
           {
            if((HistogramBuffer[i]>HistogramBuffer[i-1]) && (MACDlineBuffer[i]>MACDlineBuffer[i-1])) HistogramColors[i]=0;
            else
              {
               if((HistogramBuffer[i]<HistogramBuffer[i-1]) && (MACDlineBuffer[i]<MACDlineBuffer[i-1])) HistogramColors[i]=1;
               else HistogramColors[i]=2;
              
}
           
}
        
}
      else 
        {
         for(int i=1;i<rates_total;i++)
           {
            if((HistogramBuffer[i]>HistogramBuffer[i-1]) && (EldersiEMA[i]>EldersiEMA[i-1])) HistogramColors[i]=0;
            else
              {
               if((HistogramBuffer[i]<HistogramBuffer[i-1]) && (EldersiEMA[i]<EldersiEMA[i-1])) HistogramColors[i]=1;
               else HistogramColors[i]=2;
              
}
           
}

        
}
     
}

//--- 返回prev_calculated的值用于下一次调用
   return(rates_total);
  
}
//+------------------------------------------------------------------

算法结构图如图 4 中所示:



图 4. 指标算法的结构图

结果在图 5-7 中显示。

5

6

7

总结

本文可作为指南,供那些开始使用计算机价格分析来研究市场和实施指标图形控件的简单方法的初学者使用。

我希望本文可提高读者创建图形控件系统的技术技能,并通过隐藏阻碍物帮助读者找到自己的“市场视野”。

本文译自 MetaQuotes Software Corp. 撰写的俄文原文
原文地址: https://www.mql5.com/ru/articles/42

附加的文件 |
最近评论 | 前往讨论 (1)
jiuhongzhi
jiuhongzhi | 25 6月 2014 在 14:41
无显示!
MQL5 中的事件处理:快速更改 MA 周期 MQL5 中的事件处理:快速更改 MA 周期

假设有周期为 13 的简单 MA(移动平均线)指标应用至图表。而我们希望将周期更改为 20,但我们不想转到指标属性对话框去把将数字 13 更改为 20:我们就是对这些使用鼠标和键盘执行的乏味操作感到厌倦。尤其是,我们不希望打开指标代码进行修改。我们只想按一下按钮 - 与数字小键盘相邻的“向上箭头”- 就完成这一切。在本文中,我将给出实现方法。

交易报告及短信通知的创建和发布 交易报告及短信通知的创建和发布

交易者往往不能、也不想接连多少个小时被拴在交易终端那里。如果交易系统再或多或少地正规化、而且可以自动识别一些市场状态的时候,就更是如此。本文会讲述如何生成一份 HTML 文件格式的交易结果报告(利用“EA 交易”、指标或脚本),并通过 FTP 将其上传到 WWW 服务器。我们还会考虑以短信形式向手机发送交易事件通知。

MetaTrader 5 和 MATLAB 交互 MetaTrader 5 和 MATLAB 交互

本文将详细介绍 MetaTrader 5 和 MatLab 数学包之间的交互。文中说明了数据转换机制,以及开发通用库以与 MatLab 交互的过程。文章还介绍了对 MatLab 环境生成的 DLL 的使用。本文面向掌握了 C++ 和 MQL5 的经验丰富的读者。

面向初学者的创建具有多个指标缓冲区的指标 面向初学者的创建具有多个指标缓冲区的指标

复杂代码由一组简单代码组成。如果您熟悉简单代码,复杂代码看上去就不那么复杂了。在本文中,我们将讨论如何创建具有多个指标缓冲区的指标。我们将 Aroon 指标作为示例进行详细分析,并给出两个不同的代码版本。