Помощь с доработкой индикатора

 

Добрый день.
Пытаюсь сделать гибридный MACD. А именно, к базовому индикатору добавить раскраску гистограммы по логике HA свечей.
Бьюсь, не могу победить код. 
Гистограмма просто вся зеленая.. 
Проверка в журнале показывает что расчет\определение HA свечей верное. 
Но с цветом беда какая-то

Буду благодарен за помощь.

Код: 

 //+------------------------------------------------------------------+
//|                               MACD_HA_Color.mq5                  |
//|                  MACD-гистограмма с окраской Heiken Ashi         |
//+------------------------------------------------------------------+
#property indicator_separate_window
#property indicator_buffers 7
#property indicator_plots   2

#property indicator_type1   DRAW_HISTOGRAM
#property indicator_type2   DRAW_LINE

#property indicator_color1  clrLime, clrRed
#property indicator_color2  clrYellow

#property indicator_width1  2
#property indicator_width2  1

#property indicator_label1  "MACD"
#property indicator_label2  "Signal"

//--- input parameters
input int                InpFastEMA=12;
input int                InpSlowEMA=26;
input int                InpSignalSMA=9;
input ENUM_APPLIED_PRICE InpAppliedPrice=PRICE_CLOSE;

//--- indicator buffers
double MacdBuffer[];        // Основной буфер MACD
double SignalBuffer[];      // Линия сигнала
double FastMaBuffer[];      // Быстрая EMA
double SlowMaBuffer[];      // Медленная EMA
double HaOpenBuffer[];      // HA Open
double HaCloseBuffer[];     // HA Close
double ColorBuffer[];       // Буфер цвета

//--- handles
int FastEMAHandle;
int SlowEMAHandle;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
void OnInit()
{
   // Настройка буферов
   SetIndexBuffer(0, MacdBuffer, INDICATOR_DATA);
   SetIndexBuffer(1, SignalBuffer, INDICATOR_DATA);
   SetIndexBuffer(2, FastMaBuffer, INDICATOR_CALCULATIONS);
   SetIndexBuffer(3, SlowMaBuffer, INDICATOR_CALCULATIONS);
   SetIndexBuffer(4, HaOpenBuffer, INDICATOR_CALCULATIONS);
   SetIndexBuffer(5, HaCloseBuffer, INDICATOR_CALCULATIONS);
   SetIndexBuffer(6, ColorBuffer, INDICATOR_COLOR_INDEX);

   // Настройка гистограммы MACD
   PlotIndexSetInteger(0, PLOT_DRAW_TYPE, DRAW_HISTOGRAM);
   PlotIndexSetInteger(0, PLOT_COLOR_INDEXES, 2);
   PlotIndexSetInteger(0, PLOT_LINE_COLOR, 0, clrLime);  // Зеленый для восходящих
   PlotIndexSetInteger(0, PLOT_LINE_COLOR, 1, clrRed);    // Красный для нисходящих
   PlotIndexSetString(0, PLOT_LABEL, "MACD");

   // Настройка сигнальной линии
   PlotIndexSetInteger(1, PLOT_DRAW_TYPE, DRAW_LINE);
   PlotIndexSetInteger(1, PLOT_LINE_COLOR, clrYellow);
   PlotIndexSetString(1, PLOT_LABEL, "Signal");

   PlotIndexSetInteger(1, PLOT_DRAW_BEGIN, InpSignalSMA);
   IndicatorSetString(INDICATOR_SHORTNAME, "MACD_HA(" + string(InpFastEMA) + "," + string(InpSlowEMA) + "," + string(InpSignalSMA) + ")");

   FastEMAHandle = iMA(NULL, 0, InpFastEMA, 0, MODE_EMA, InpAppliedPrice);
   SlowEMAHandle = iMA(NULL, 0, InpSlowEMA, 0, MODE_EMA, InpAppliedPrice);
   
   // Установка начального значения для буфера цвета
   ArrayInitialize(ColorBuffer, 0);
}

//+------------------------------------------------------------------+
//| Simple SMA on array                                              |
//+------------------------------------------------------------------+
void SimpleMAonArray(double &inBuffer[], double &outBuffer[], int total, int period)
{
   for(int i=0; i<total; i++)
   {
      if(i<period-1)
      {
         outBuffer[i]=0;
         continue;
      }

      double sum=0;
      for(int j=0; j<period; j++)
         sum+=inBuffer[i-j];

      outBuffer[i]=sum/period;
   }
}

//+------------------------------------------------------------------+
//| Calculate Heiken Ashi                                            |
//+------------------------------------------------------------------+
void CalculateHeikenAshi(const double &open[], const double &high[], const double &low[], const double &close[], 
                         double &haOpen[], double &haClose[], int rates_total)
{
   for(int i=0; i<rates_total; i++)
   {
      if(i==0)
      {
         haOpen[i] = open[i];
         haClose[i] = (open[i]+high[i]+low[i]+close[i])/4.0;
      }
      else
      {
         haOpen[i] = (haOpen[i-1]+haClose[i-1])/2.0;
         haClose[i] = (open[i]+high[i]+low[i]+close[i])/4.0;
      }
   }
}

//+------------------------------------------------------------------+
//| OnCalculate                                                      |
//+------------------------------------------------------------------+
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[])
{
   if(rates_total<InpSignalSMA)
      return(0);

   int limit;
   if(prev_calculated==0)
   {
      limit=0;
      ArrayInitialize(MacdBuffer, 0);
      ArrayInitialize(SignalBuffer, 0);
      ArrayInitialize(ColorBuffer, 0);
   }
   else
      limit=prev_calculated-1;

   if(CopyBuffer(FastEMAHandle,0,0,rates_total,FastMaBuffer)<=0)
      return(0);

   if(CopyBuffer(SlowEMAHandle,0,0,rates_total,SlowMaBuffer)<=0)
      return(0);

   // Расчёт MACD
   for(int i=limit; i<rates_total; i++)
      MacdBuffer[i]=FastMaBuffer[i]-SlowMaBuffer[i];

   // Расчёт Heiken Ashi
   CalculateHeikenAshi(open, high, low, close, HaOpenBuffer, HaCloseBuffer, rates_total);

   // Окрашивание MACD гистограммы по логике HA
   for(int i=limit; i<rates_total; i++)
   {
      if(HaCloseBuffer[i] > HaOpenBuffer[i])
         ColorBuffer[i] = 0; // Зелёный цвет (восходящий тренд)
      else
         ColorBuffer[i] = 1; // Красный цвет (нисходящий тренд)
   }

   // Signal line (SMA по MACD)
   SimpleMAonArray(MacdBuffer, SignalBuffer, rates_total, InpSignalSMA);

   return(rates_total);
} 
Документация по MQL5: Основы языка / Препроцессор / Свойства программ (#property)
Документация по MQL5: Основы языка / Препроцессор / Свойства программ (#property)
  • www.mql5.com
У каждой mql5-программы можно указать дополнительные специфические параметры #property , которые помогают клиентскому терминалу правильно...
 

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

пожалуйста помогите мне нужно чтобы каждый новый бар открывалась сделка мне нужно чтобы если Предыдущий бар был верх то buy если вниз то sell

Sergey Golubev, 2020.03.23 16:08

Вставляйте правильно код -

----------------‌

MQL5.community - Памятка пользователя 

Кнопка  Исходный кодпредназначена для вставки исходного кода в текст сообщения. При нажатии появляется пустое окно, в которое необходимо вставить код и далее нажать кнопку Вставить. Для отмены вставки кода необходимо нажать кнопку Отмена.


 
Evgeny Fedorenko:
Бьюсь, не могу победить код. 

Две ошибки:

  1. Неверный тип индикаторного буфера указано DRAW_HISTOGRAM - надо DRAW_COLOR_HISTOGRAM 
  2. Логическая - в коде нет привязки буфера с цветами к буферу визуализации, и как я понял, кодом это не привязать, поэтому компилятор смотрит на последовательность инициализации буферов, и если визуальный буфер (INDICATOR_DATA) цветной, то ожидается следующим объявления буфером с цветами (INDICATOR_COLOR_INDEX). В справке не увидел, что написано об этом...


//+------------------------------------------------------------------+
//|                               MACD_HA_Color.mq5                  |
//|                  MACD-гистограмма с окраской Heiken Ashi         |
//+------------------------------------------------------------------+
#property indicator_separate_window
#property indicator_buffers 7
#property indicator_plots   2

//#property indicator_type1   DRAW_HISTOGRAM
#property indicator_type1   DRAW_COLOR_HISTOGRAM
#property indicator_type2   DRAW_LINE

#property indicator_color1  clrLime, clrRed
#property indicator_color2  clrYellow

#property indicator_width1  2
#property indicator_width2  1

#property indicator_label1  "MACD"
#property indicator_label2  "Signal"

//--- input parameters
input int                InpFastEMA=12;
input int                InpSlowEMA=26;
input int                InpSignalSMA=9;
input ENUM_APPLIED_PRICE InpAppliedPrice=PRICE_CLOSE;

//--- indicator buffers
double MacdBuffer[];        // Основной буфер MACD
double SignalBuffer[];      // Линия сигнала
double FastMaBuffer[];      // Быстрая EMA
double SlowMaBuffer[];      // Медленная EMA
double HaOpenBuffer[];      // HA Open
double HaCloseBuffer[];     // HA Close
double ColorBuffer[];       // Буфер цвета

//--- handles
int FastEMAHandle;
int SlowEMAHandle;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
void OnInit()
{
   // Настройка буферов
   SetIndexBuffer(0, MacdBuffer, INDICATOR_DATA);
   SetIndexBuffer(1, ColorBuffer, INDICATOR_COLOR_INDEX);
   SetIndexBuffer(2, FastMaBuffer, INDICATOR_CALCULATIONS);
   SetIndexBuffer(3, SlowMaBuffer, INDICATOR_CALCULATIONS);
   SetIndexBuffer(4, HaOpenBuffer, INDICATOR_CALCULATIONS);
   SetIndexBuffer(5, HaCloseBuffer, INDICATOR_CALCULATIONS);
   SetIndexBuffer(6, SignalBuffer, INDICATOR_DATA);

   // Настройка гистограммы MACD
   PlotIndexSetInteger(0, PLOT_DRAW_TYPE, DRAW_COLOR_HISTOGRAM);
   PlotIndexSetInteger(0, PLOT_COLOR_INDEXES, 2);
   PlotIndexSetInteger(0, PLOT_LINE_COLOR, 0, clrLime);  // Зеленый для восходящих
   PlotIndexSetInteger(0, PLOT_LINE_COLOR, 1, clrRed);    // Красный для нисходящих
   PlotIndexSetString(0, PLOT_LABEL, "MACD");

   // Настройка сигнальной линии
   PlotIndexSetInteger(6, PLOT_DRAW_TYPE, DRAW_LINE);
   PlotIndexSetInteger(6, PLOT_LINE_COLOR, clrYellow);
   PlotIndexSetString(6, PLOT_LABEL, "Signal");

   PlotIndexSetInteger(6, PLOT_DRAW_BEGIN, InpSignalSMA);
   IndicatorSetString(INDICATOR_SHORTNAME, "MACD_HA(" + string(InpFastEMA) + "," + string(InpSlowEMA) + "," + string(InpSignalSMA) + ")");

   FastEMAHandle = iMA(NULL, 0, InpFastEMA, 0, MODE_EMA, InpAppliedPrice);
   SlowEMAHandle = iMA(NULL, 0, InpSlowEMA, 0, MODE_EMA, InpAppliedPrice);

   // Установка начального значения для буфера цвета
   ArrayInitialize(ColorBuffer, 0);

}

//+------------------------------------------------------------------+
//| Simple SMA on array                                              |
//+------------------------------------------------------------------+
void SimpleMAonArray(double &inBuffer[], double &outBuffer[], int total, int period)
{
   for(int i=0; i<total; i++)
   {
      if(i<period-1)
      {
         outBuffer[i]=0;
         continue;
      }

      double sum=0;
      for(int j=0; j<period; j++)
         sum+=inBuffer[i-j];

      outBuffer[i]=sum/period;
   }
}

//+------------------------------------------------------------------+
//| Calculate Heiken Ashi                                            |
//+------------------------------------------------------------------+
void CalculateHeikenAshi(const double &open[], const double &high[], const double &low[], const double &close[],
                         double &haOpen[], double &haClose[], int rates_total)
{
   for(int i=0; i<rates_total; i++)
   {
      if(i==0)
      {
         haOpen[i] = open[i];
         haClose[i] = (open[i]+high[i]+low[i]+close[i])/4.0;
      }
      else
      {
         haOpen[i] = (haOpen[i-1]+haClose[i-1])/2.0;
         haClose[i] = (open[i]+high[i]+low[i]+close[i])/4.0;
      }
   }
}

//+------------------------------------------------------------------+
//| OnCalculate                                                      |
//+------------------------------------------------------------------+
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[])
{
   if(rates_total<InpSignalSMA)
      return(0);

   int limit;
   if(prev_calculated==0)
   {
      limit=0;
      ArrayInitialize(MacdBuffer, 0);
      ArrayInitialize(SignalBuffer, 0);
      ArrayInitialize(ColorBuffer, 0);
   }
   else
      limit=prev_calculated-1;

   if(CopyBuffer(FastEMAHandle,0,0,rates_total,FastMaBuffer)<=0)
      return(0);

   if(CopyBuffer(SlowEMAHandle,0,0,rates_total,SlowMaBuffer)<=0)
      return(0);

   // Расчёт MACD
   for(int i=limit; i<rates_total; i++)
      MacdBuffer[i]=FastMaBuffer[i]-SlowMaBuffer[i];

   // Расчёт Heiken Ashi
   CalculateHeikenAshi(open, high, low, close, HaOpenBuffer, HaCloseBuffer, rates_total);

   // Окрашивание MACD гистограммы по логике HA
   for(int i=limit; i<rates_total; i++)
   {
      if(HaCloseBuffer[i] > HaOpenBuffer[i])
         ColorBuffer[i] = 0; // Зелёный цвет (восходящий тренд)
      else
         ColorBuffer[i] = 1; // Красный цвет (нисходящий тренд)
   }

   // Signal line (SMA по MACD)
   SimpleMAonArray(MacdBuffer, SignalBuffer, rates_total, InpSignalSMA);

   return(rates_total);
} 
//+------------------------------------------------------------------+
 
Aleksey Vyazmikin #:

Две ошибки:

  1. Неверный тип индикаторного буфера указано DRAW_HISTOGRAM - надо DRAW_COLOR_HISTOGRAM 
  2. Логическая - в коде нет привязки буфера с цветами к буферу визуализации, и как я понял, кодом это не привязать, поэтому компилятор смотрит на последовательность инициализации буферов, и если визуальный буфер (INDICATOR_DATA) цветной, то ожидается следующим объявления буфером с цветами (INDICATOR_COLOR_INDEX). В справке не увидел, что написано об этом...


Алексей, добрый день. 
Благодарю за помощь.

С вашими правками скомпилировал, бары красятся как нужно, но пропала сигнальная линия.
Видимо проблема с  PlotIndex и SetIndexBuffer в их последовательности.
Немного поправил, теперь все работает как нужно.
Вам еще раз огромное спасибо.

На всякий случай исправленный код, вдруг и вам пригодится

//+------------------------------------------------------------------+
//|                      MACD_HA_Color.mq5                           |
//+------------------------------------------------------------------+
#property indicator_separate_window
#property indicator_buffers 7
#property indicator_plots   2

#property indicator_type1   DRAW_COLOR_HISTOGRAM
#property indicator_type2   DRAW_LINE

#property indicator_color1  clrLime, clrRed        // MACD цвета
#property indicator_color2  clrYellow              // Сигнальная линия

#property indicator_width1  2
#property indicator_width2  1

#property indicator_label1  "MACD"
#property indicator_label2  "Signal"

//--- input parameters
input int                InpFastEMA=12;
input int                InpSlowEMA=26;
input int                InpSignalSMA=9;
input ENUM_APPLIED_PRICE InpAppliedPrice=PRICE_CLOSE;

//--- indicator buffers
double MacdBuffer[];        // Индикаторные данные для гистограммы
double ColorBuffer[];       // Цвета для гистограммы
double SignalBuffer[];      // Линия сигнала
double FastMaBuffer[];      // Быстрая EMA
double SlowMaBuffer[];      // Медленная EMA
double HaOpenBuffer[];      // HA Open
double HaCloseBuffer[];     // HA Close

//--- handles
int FastEMAHandle;
int SlowEMAHandle;

//+------------------------------------------------------------------+
//| OnInit                                                           |
//+------------------------------------------------------------------+
void OnInit()
{
   // Обязательно: сначала индикаторные буферы
   SetIndexBuffer(0, MacdBuffer, INDICATOR_DATA);         // Plot 0: MACD
   SetIndexBuffer(1, ColorBuffer, INDICATOR_COLOR_INDEX); // Цвета для Plot 0
   SetIndexBuffer(2, SignalBuffer, INDICATOR_DATA);       // Plot 1: Signal line

   // Вспомогательные буферы
   SetIndexBuffer(3, FastMaBuffer, INDICATOR_CALCULATIONS);
   SetIndexBuffer(4, SlowMaBuffer, INDICATOR_CALCULATIONS);
   SetIndexBuffer(5, HaOpenBuffer, INDICATOR_CALCULATIONS);
   SetIndexBuffer(6, HaCloseBuffer, INDICATOR_CALCULATIONS);

   // Настройка Plot 0: гистограмма
   PlotIndexSetInteger(0, PLOT_DRAW_TYPE, DRAW_COLOR_HISTOGRAM);
   PlotIndexSetInteger(0, PLOT_COLOR_INDEXES, 2);
   PlotIndexSetInteger(0, PLOT_LINE_COLOR, 0, clrLime);
   PlotIndexSetInteger(0, PLOT_LINE_COLOR, 1, clrRed);
   PlotIndexSetString(0, PLOT_LABEL, "MACD");

   // Настройка Plot 1: сигнальная линия
   PlotIndexSetInteger(1, PLOT_DRAW_TYPE, DRAW_LINE);
   PlotIndexSetInteger(1, PLOT_LINE_COLOR, clrYellow);
   PlotIndexSetInteger(1, PLOT_DRAW_BEGIN, InpSignalSMA);
   PlotIndexSetString(1, PLOT_LABEL, "Signal");

   IndicatorSetString(INDICATOR_SHORTNAME, "MACD_HA(" + string(InpFastEMA) + "," + string(InpSlowEMA) + "," + string(InpSignalSMA) + ")");

   // EMA хендлы
   FastEMAHandle = iMA(NULL, 0, InpFastEMA, 0, MODE_EMA, InpAppliedPrice);
   SlowEMAHandle = iMA(NULL, 0, InpSlowEMA, 0, MODE_EMA, InpAppliedPrice);

   ArrayInitialize(ColorBuffer, 0);
}

//+------------------------------------------------------------------+
//| Простое SMA по массиву                                           |
//+------------------------------------------------------------------+
void SimpleMAonArray(double &inBuffer[], double &outBuffer[], int total, int period)
{
   for(int i=0; i<total; i++)
   {
      if(i < period - 1)
      {
         outBuffer[i] = 0;
         continue;
      }

      double sum = 0;
      for(int j = 0; j < period; j++)
         sum += inBuffer[i - j];

      outBuffer[i] = sum / period;
   }
}

//+------------------------------------------------------------------+
//| Расчёт Heiken Ashi                                               |
//+------------------------------------------------------------------+
void CalculateHeikenAshi(const double &open[], const double &high[], const double &low[], const double &close[],
                         double &haOpen[], double &haClose[], int rates_total)
{
   for(int i=0; i<rates_total; i++)
   {
      if(i==0)
      {
         haOpen[i]  = open[i];
         haClose[i] = (open[i] + high[i] + low[i] + close[i]) / 4.0;
      }
      else
      {
         haOpen[i]  = (haOpen[i-1] + haClose[i-1]) / 2.0;
         haClose[i] = (open[i] + high[i] + low[i] + close[i]) / 4.0;
      }
   }
}

//+------------------------------------------------------------------+
//| OnCalculate                                                      |
//+------------------------------------------------------------------+
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[])
{
   if(rates_total < InpSignalSMA)
      return(0);

   int limit = (prev_calculated == 0) ? 0 : prev_calculated - 1;

   if(CopyBuffer(FastEMAHandle, 0, 0, rates_total, FastMaBuffer) <= 0)
      return(0);
   if(CopyBuffer(SlowEMAHandle, 0, 0, rates_total, SlowMaBuffer) <= 0)
      return(0);

   // Расчёт MACD
   for(int i=limit; i<rates_total; i++)
      MacdBuffer[i] = FastMaBuffer[i] - SlowMaBuffer[i];

   // Расчёт HA
   CalculateHeikenAshi(open, high, low, close, HaOpenBuffer, HaCloseBuffer, rates_total);

   // Цвет гистограммы
   for(int i=limit; i<rates_total; i++)
      ColorBuffer[i] = (HaCloseBuffer[i] > HaOpenBuffer[i]) ? 0 : 1;

   // Сигнальная линия
   SimpleMAonArray(MacdBuffer, SignalBuffer, rates_total, InpSignalSMA);

   return(rates_total);
}
//+------------------------------------------------------------------+
 
Evgeny Fedorenko #:
Алексей, добрый день. 
Благодарю за помощь.

С вашими правками скомпилировал, бары красятся как нужно, но пропала сигнальная линия.
Видимо проблема с  PlotIndex и SetIndexBuffer в их последовательности.
Немного поправил, теперь все работает как нужно.
Вам еще раз огромное спасибо.

На всякий случай исправленный код, вдруг и вам пригодится

Добрый день.

Пока решал проблему со вторым цветом - визуально проигнорировал пропажу другого буфера индикатора - согласен, упущение. Главное, что Вы всё довели до ума!

Рад был помочь.