Нужна помощь (неправильно отрисовывает переднланный Palpite_MACD под мт5, ошибок нет).

 

Привет всем. Люди помогите поправить код в переделанном индикаторе под мт5. Переделал интересный индикатор Palpite_MACD под мт4.

Вот его исходный код

//+------------------------------------------------------------------+
//|                                                 Palpite_MACD.mq4 |
//|                                        Copyright © 2016, Palpite |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2005, Palpite"
#property link      ""

#property indicator_separate_window
#property indicator_height  150
#property indicator_buffers 4
#property indicator_color1  Red
#property indicator_color2  ForestGreen
#property indicator_color3  Yellow
#property indicator_color4  Cyan
#property indicator_width1 1
#property indicator_width2 1
#property indicator_width3 1
#property indicator_width4 1
//---- input parameters
extern int FastMAPeriod   = 12, 
           SlowMAPeriod   = 26,
           SignalMAPeriod = 9;
//---- buffers
double     MACDLineBuffer[],
           SignalLineBuffer[],
           HistogramBuffer[],
           HistogramBuffer1[],
           Signal,
           Signal_1;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
{
   IndicatorDigits(Digits + 1);
   //---- indicators
   SetIndexStyle (0, DRAW_HISTOGRAM);        SetIndexBuffer   (0, HistogramBuffer) ; SetIndexLabel(0, "Histo");SetLevelValue(0, 0);SetLevelStyle(STYLE_DOT,1,DimGray);
   SetIndexStyle (1, DRAW_HISTOGRAM);        SetIndexBuffer   (1, HistogramBuffer1); SetIndexLabel(1, "Histo1");
   SetIndexStyle (2, DRAW_LINE, STYLE_SOLID);SetIndexDrawBegin(2, SlowMAPeriod)     ;SetIndexBuffer(2, MACDLineBuffer);
   SetIndexBuffer(3, SignalLineBuffer)      ;SetIndexDrawBegin(3, SlowMAPeriod - SignalMAPeriod); SetIndexLabel(3, "Signal");
   IndicatorShortName("   Palpite_MACD   (" + FastMAPeriod+" , " + SlowMAPeriod + " , " + SignalMAPeriod + ")");
   //----
        Signal   = 1.5 / (SignalMAPeriod - 1.0);
        Signal_1 = 1.0 - Signal;
   //----
   return(Digits);
}
//+------------------------------------------------------------------+
//| Custor indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
   //----
   return(1);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
   int limit;
   int 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;
//----
   double value=0;
   for(int i = limit; i >= 0; i--)
     {
       MACDLineBuffer[i] = iMA(NULL, 0, FastMAPeriod, 0, MODE_EMA, PRICE_CLOSE, i) - iMA(NULL, 0, SlowMAPeriod, 0, MODE_EMA, PRICE_CLOSE, i);
       SignalLineBuffer[i]= Signal*MACDLineBuffer[i] + Signal_1*SignalLineBuffer[i+1];    
         HistogramBuffer[i] = MACDLineBuffer[i] - SignalLineBuffer[i]/100;
         HistogramBuffer1[i] = HistogramBuffer[i];
         if (value>SignalLineBuffer[i] - MACDLineBuffer[i]) HistogramBuffer[i]=value;
         if (value<SignalLineBuffer[i] - MACDLineBuffer[i]) HistogramBuffer1[i]=value;
     }
//----
   return(counted_bars);
  }

в мт4 он выглядит вот так


Вот переделанный мною код под мт5

//+------------------------------------------------------------------+
//|                                                 Palpite_MACD.mq4 |
//|                                        Copyright © 2016, Palpite |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2005, Palpite"
#property link      ""

#property indicator_separate_window
#property indicator_height  150
#property indicator_buffers  5
#property indicator_plots   3
#property indicator_type1   DRAW_HISTOGRAM
#property indicator_color1  Red
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
#property indicator_type2   DRAW_HISTOGRAM2
#property indicator_color2  ForestGreen
#property indicator_style2  STYLE_SOLID
#property indicator_width2  1

#property indicator_color2  ForestGreen
#property indicator_type2   DRAW_LINE
#property indicator_color3  Yellow
#property indicator_type3   DRAW_LINE
#property indicator_color4  Cyan

#property indicator_width3 1
#property indicator_width4 1
//---- input parameters
input int  FastMAPeriod   = 12,//InpPeriodFastMA 
           SlowMAPeriod   = 26,// InpPeriodSlowMA 
           SignalMAPeriod = 9;//InpPeriodSignal 
input ENUM_APPLIED_PRICE   InpAppliedPrice   =  PRICE_CLOSE;   // Applied price
           
//---- buffers
double     MACDLineBuffer[],//BufferMACD
           SignalLineBuffer[],//BufferSignal
           HistogramBuffer[],// BufferHistogram
           HistogramBuffer1[],
           Signal,
           Signal_1;
 
int            period_fma;
int            period_sma;
int            period_sig;
int            period_max;
int            handle_ma;
 
           
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
void OnInit()
  {
  
 //--- set global variables
   period_fma=int(FastMAPeriod<1 ? 1 : FastMAPeriod);
   period_sma=int(SlowMAPeriod==period_fma ? period_fma+1 : SlowMAPeriod<1 ? 1 : SlowMAPeriod);
   period_sig=int(SignalMAPeriod<1 ? 1 : SignalMAPeriod);
   period_max=fmax(period_sig,fmax(period_fma,period_sma)); 
  
  // IndicatorDigits(Digits + 1);
 IndicatorSetInteger(INDICATOR_DIGITS,_Digits+1);
//---- indicators
   //SetIndexStyle(0, DRAW_HISTOGRAM);
   SetIndexBuffer(0,HistogramBuffer,INDICATOR_DATA);
  // SetIndexLabel(0, "Histo");
   PlotIndexSetString(0,PLOT_LABEL,"Histo");
  // SetLevelValue(0, 0);
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE, 0.0);
   //SetLevelStyle(STYLE_DOT,1,DimGray);
   PlotIndexSetInteger(0,PLOT_LINE_STYLE,STYLE_DOT);//SetLevelStyle(STYLE_DOT,1,DimGray);
   PlotIndexSetInteger(0,PLOT_LINE_COLOR,DimGray);  //SetLevelStyle(STYLE_DOT,1,DimGray);
   PlotIndexSetInteger(0,PLOT_LINE_WIDTH,1);  //SetLevelStyle(STYLE_DOT,1,DimGray);
   //SetIndexStyle(1, DRAW_HISTOGRAM);
   SetIndexBuffer(1, HistogramBuffer1,INDICATOR_DATA);
   // SetIndexLabel(1, "Histo1");
   PlotIndexSetString(1,PLOT_LABEL,"Histo1");
      //SetIndexStyle(2, DRAW_LINE, STYLE_SOLID);
   //SetIndexDrawBegin(2, SlowMAPeriod);
     PlotIndexSetInteger(2,PLOT_DRAW_BEGIN,SlowMAPeriod);

   SetIndexBuffer(2, MACDLineBuffer);
   SetIndexBuffer(3, SignalLineBuffer);
  // SetIndexDrawBegin(3, SlowMAPeriod - SignalMAPeriod);
   PlotIndexSetInteger(3,PLOT_DRAW_BEGIN,SlowMAPeriod - SignalMAPeriod);
     // SetIndexLabel(3, "Signal");
         PlotIndexSetString(3,PLOT_LABEL,"Signal");
   IndicatorSetString(INDICATOR_SHORTNAME,"Palpite_MACD ("+string(FastMAPeriod)+","+string(SlowMAPeriod)+","+string(SignalMAPeriod)+")");

//----
  Signal   = 1.5 / (SignalMAPeriod - 1.0);
  Signal_1 = 1.0 - Signal;

//----
 
  }



//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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(tick_volume,true);
//--- Проверка и расчёт количества просчитываемых баров
   if(rates_total<period_max) return 0;
//--- Проверка и расчёт количества просчитываемых баров
   int limit=rates_total-prev_calculated;
   if(limit>1)
     {
      limit=rates_total-period_max-2;
      ArrayInitialize(MACDLineBuffer,0);
      ArrayInitialize(SignalLineBuffer,0);
      ArrayInitialize(HistogramBuffer,0);
      ArrayInitialize(HistogramBuffer1,0);
     }
//----
   double value=0;
   for(int i = limit; i >= 0; i--)
     {
      MACDLineBuffer[i] = iMA(NULL, 0, FastMAPeriod, 0, MODE_EMA,InpAppliedPrice) - iMA(NULL, 0, SlowMAPeriod, 0, MODE_EMA,InpAppliedPrice);
       SignalLineBuffer[i]= Signal*MACDLineBuffer[i] + Signal_1*SignalLineBuffer[i+1];    
         HistogramBuffer[i] = MACDLineBuffer[i] - SignalLineBuffer[i]/100;
         HistogramBuffer1[i] = HistogramBuffer[i];
         if (value>SignalLineBuffer[i] - MACDLineBuffer[i]) HistogramBuffer[i]=value;
         if (value<SignalLineBuffer[i] - MACDLineBuffer[i]) HistogramBuffer1[i]=value;
     }
//----
   return(rates_total);
  }
//+------------------------------------------------------------------+

Вот что данный код отрисовывает в мт5


 
А куда твой ima возвращает значение??? (..,i)
 
Aleksandr Morozov:
А куда твой ima возвращает значение??? (..,i)
Вопрос конечно интересный. Что то я не соображу.
 
Ну где у тебя имашки? Добавь в конце ,i.
 

MACDLineBuffer[i] = iMA(NULL. . .

на мт4 в конце ,i.

 
Игорь:
Вопрос конечно интересный. Что то я не соображу.

В корне не правильно

MACDLineBuffer[i] = iMA(NULL, 0, FastMAPeriod, 0, MODE_EMA,InpAppliedPrice) - iMA(NULL, 0, SlowMAPeriod, 0, MODE_EMA,InpAppliedPrice);

Это создаёт хендл, а вы с него берёте значения.

Значения нужно брать с CopyBuffer

Почитайте

Документация по MQL5: Доступ к таймсериям и индикаторам / CopyBuffer
Документация по MQL5: Доступ к таймсериям и индикаторам / CopyBuffer
  • www.mql5.com
CopyBuffer - Доступ к таймсериям и индикаторам - Справочник MQL5 - Справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
 
Vitaly Muzichenko:

В корне не правильно

Это создаёт хендл, а вы с него берёте значения.

Значения нужно брать с CopyBuffer

Почитайте

Спасибо за помощь. Сейчас попробую исправить.

 
Игорь:

Спасибо за помощь. Сейчас попробую исправить.

У меня вот что получилось.

....................
....................
 ma_handle=iMA(NULL, 0, FastMAPeriod, 0, MODE_EMA,InpAppliedPrice) - iMA(NULL, 0, SlowMAPeriod, 0, MODE_EMA,InpAppliedPrice);
   return(INIT_SUCCEEDED);
...................
.....................
 if(CopyBuffer(ma_handle,0,0,to_copy,MACDLineBuffer[i])<=0) return(0);

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

//+------------------------------------------------------------------+
//|                                                 Palpite_MACD.mq5 |
//|                        Copyright 2020, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2005, Palpite"
#property link      ""

#property indicator_separate_window
#property indicator_height  150
#property indicator_buffers  5
#property indicator_plots   3
#property indicator_type1   DRAW_HISTOGRAM
#property indicator_color1  Red
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
#property indicator_type2   DRAW_HISTOGRAM2
#property indicator_color2  ForestGreen
#property indicator_style2  STYLE_SOLID
#property indicator_width2  1

#property indicator_color2  ForestGreen
#property indicator_type2   DRAW_LINE
#property indicator_color3  Yellow
#property indicator_type3   DRAW_LINE
#property indicator_color4  Cyan

#property indicator_width3 1
#property indicator_width4 1
//---- input parameters
input int  FastMAPeriod   = 12,//InpPeriodFastMA 
           SlowMAPeriod   = 26,// InpPeriodSlowMA 
           SignalMAPeriod = 9;//InpPeriodSignal 
input ENUM_APPLIED_PRICE   InpAppliedPrice   =  PRICE_CLOSE;   // Applied price
           
//---- buffers
double     MACDLineBuffer[],//BufferMACD
           SignalLineBuffer[],//BufferSignal
           HistogramBuffer[],// BufferHistogram
           HistogramBuffer1[],
           Signal,
           Signal_1;
 
int            period_fma;
int            period_sma;
int            period_sig;
int            period_max;
int            handle_ma;
 
int                      ma_handle;     
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
void OnInit()
  {
   //--- set global variables
   period_fma=int(FastMAPeriod<1 ? 1 : FastMAPeriod);
   period_sma=int(SlowMAPeriod==period_fma ? period_fma+1 : SlowMAPeriod<1 ? 1 : SlowMAPeriod);
   period_sig=int(SignalMAPeriod<1 ? 1 : SignalMAPeriod);
   period_max=fmax(period_sig,fmax(period_fma,period_sma)); 
    // IndicatorDigits(Digits + 1);
 IndicatorSetInteger(INDICATOR_DIGITS,_Digits+1);
//---- indicators
   //SetIndexStyle(0, DRAW_HISTOGRAM);
   SetIndexBuffer(0,HistogramBuffer,INDICATOR_DATA);
  // SetIndexLabel(0, "Histo");
   PlotIndexSetString(0,PLOT_LABEL,"Histo");
  // SetLevelValue(0, 0);
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE, 0.0);
   //SetLevelStyle(STYLE_DOT,1,DimGray);
   PlotIndexSetInteger(0,PLOT_LINE_STYLE,STYLE_DOT);//SetLevelStyle(STYLE_DOT,1,DimGray);
   PlotIndexSetInteger(0,PLOT_LINE_COLOR,DimGray);  //SetLevelStyle(STYLE_DOT,1,DimGray);
   PlotIndexSetInteger(0,PLOT_LINE_WIDTH,1);  //SetLevelStyle(STYLE_DOT,1,DimGray);
   //SetIndexStyle(1, DRAW_HISTOGRAM);
   SetIndexBuffer(1, HistogramBuffer1,INDICATOR_DATA);
   // SetIndexLabel(1, "Histo1");
   PlotIndexSetString(1,PLOT_LABEL,"Histo1");
      //SetIndexStyle(2, DRAW_LINE, STYLE_SOLID);
   //SetIndexDrawBegin(2, SlowMAPeriod);
     PlotIndexSetInteger(2,PLOT_DRAW_BEGIN,SlowMAPeriod);
  SetIndexBuffer(2, MACDLineBuffer);
   SetIndexBuffer(3, SignalLineBuffer);
  // SetIndexDrawBegin(3, SlowMAPeriod - SignalMAPeriod);
   PlotIndexSetInteger(3,PLOT_DRAW_BEGIN,SlowMAPeriod - SignalMAPeriod);
     // SetIndexLabel(3, "Signal");
    PlotIndexSetString(3,PLOT_LABEL,"Signal");
   IndicatorSetString(INDICATOR_SHORTNAME,"Palpite_MACD ("+string(FastMAPeriod)+","+string(SlowMAPeriod)+","+string(SignalMAPeriod)+")");
//----
  Signal   = 1.5 / (SignalMAPeriod - 1.0);
  Signal_1 = 1.0 - Signal;

//----
 ma_handle=iMA(NULL, 0, FastMAPeriod, 0, MODE_EMA,InpAppliedPrice) - iMA(NULL, 0, SlowMAPeriod, 0, MODE_EMA,InpAppliedPrice);
  
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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[])
  {
   int to_copy;
 //--- Установка массивов буферов как таймсерий
   ArraySetAsSeries(tick_volume,true);
//--- Проверка и расчёт количества просчитываемых баров
   if(rates_total<period_max) return 0;
//--- Проверка и расчёт количества просчитываемых баров
   int limit=rates_total-prev_calculated;
   if(limit>1)
     {
      limit=rates_total-period_max-2;
      ArrayInitialize(MACDLineBuffer,0);
      ArrayInitialize(SignalLineBuffer,0);
      ArrayInitialize(HistogramBuffer,0);
      ArrayInitialize(HistogramBuffer1,0);
     }
//----
   double value=0;
   for(int i = limit; i >= 0; i--)
     { 
     if(CopyBuffer(ma_handle,0,0,to_copy,MACDLineBuffer[i])<=0) return(0);
//--- return value of prev_calculated for next call
  // return(rates_total);
     
       SignalLineBuffer[i]= Signal*MACDLineBuffer[i] + Signal_1*SignalLineBuffer[i+1];    
         HistogramBuffer[i] = MACDLineBuffer[i] - SignalLineBuffer[i]/100;
         HistogramBuffer1[i] = HistogramBuffer[i];
         if (value>SignalLineBuffer[i] - MACDLineBuffer[i]) HistogramBuffer[i]=value;
         if (value<SignalLineBuffer[i] - MACDLineBuffer[i]) HistogramBuffer1[i]=value;
     }
//----
   return(rates_total);
  }
//+------------------------------------------------------------------+

При компиляции выдаёт ошибки

possible use of uninitialized variable 'to_copy'        Palpite_MACD.mq5        130     34
'MACDLineBuffer' - array required       Palpite_MACD.mq5        130     42
 
Игорь:

У меня вот что получилось.

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

При компиляции выдаёт ошибки

  1. Инициализируйте переменную to_copy, иначе в ней мусор находится.
  2. Передайте в CopyBuffer ссылку на массив, а не на элемент массива.
 
Ihor Herasko:

  1. Инициализируйте переменную to_copy, иначе в ней мусор находится.
  2. Передайте в CopyBuffer ссылку на массив, а не на элемент массива.
Всё подправил
..............
int to_copy;
..............
if(CopyBuffer(ma_handle,0,0,to_copy,MACDLineBuffer)<=0) return(0);
................

Совсем ничего не рисует

 
Игорь:
Всё подправил

Совсем ничего не рисует

ma_handle=iMA(NULL, 0, FastMAPeriod, 0, MODE_EMA,InpAppliedPrice) - iMA(NULL, 0, SlowMAPeriod, 0, MODE_EMA,InpAppliedPrice);

У вас есть технически 2 разных индикатора, вот и нужно создавать 2 разных хендла и 2 CopyBuffer. Соответственно нужно по 2 разные переменные


Далее примерно так:

if(CopyBuffer(ma_handleFast,0,i,1,MACDLineBuffer_fast)<0) return(0);

Обращение по начальной позиции и количеству требуемых элементов

int  CopyBuffer(
   int       indicator_handle,   // handle индикатора
   int       buffer_num,           // номер буфера индикатора
   int       start_pos,              // откуда начнем 
   int       count,                   // сколько копируем
   double    buffer[]              // массив, куда будут скопированы данные
   );


В итоге, эта конструкция:

MACDLineBuffer[i] = iMA(NULL, 0, FastMAPeriod, 0, MODE_EMA,InpAppliedPrice) - iMA(NULL, 0, SlowMAPeriod, 0, MODE_EMA,InpAppliedPrice);

заменяется на такую:

double MAfast = MACDLineBuffer_fast[0];
double MASlow = MACDLineBuffer_Slow[0];
 MACDLineBuffer[i] = MAfast - MASlow;