外汇EA编写教程:创建具有图形控制选项的指标

简介

熟悉市场情绪的人都知道 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. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------
#property copyright "2010, MetaQuotes Software Corp."
#property link      "https://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

附加的文件 |

下载ZIP
macd_by_corewintt.mq5
(14.75 KB)

 

 


MyFxtop迈投-靠谱的外汇跟单社区,免费跟随高手做交易!

 

免责声明:本文系转载自网络,如有侵犯,请联系我们立即删除,另:本文仅代表作者个人观点,与迈投财经无关。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。

著作权归作者所有。
商业转载请联系作者获得授权,非商业转载请注明出处。

風險提示

MyFxtops邁投所列信息僅供參考,不構成投資建議,也不代表任何形式的推薦或者誘導行為。MyFxtops邁投非外匯經紀商,不接觸妳的任何資金。 MYFXTOPS不保證客戶盈利,不承擔任何責任。從事外彙和差價合約等金融產品的槓桿交易具有高風險,損失有可能超過本金,請量力而行,入市前需充分了解潛在的風險。過去的交易成績並不代表以後的交易成績。依據各地區法律法規,MyFxtops邁投不向中國大陸、美國、加拿大、朝鮮居民提供服務。

邁投公眾號

聯繫我們

客服QQ:981617007
Email: service@myfxtop.com

MyFxtops 邁投