Нужна помощь в написании индикатора!!!

 

Навожу пример кода который работает:

   if(Time[0] == prevtime)   return(-1);
   prevtime = Time[0];
   int limit = Bars-IndicatorCounted();
   for(int i=0; i<limit-1;i++)
    {
         if(Close[i+1]>Open[i+1]
            &&Close[i+1]>=Close[i+2]&&Close[i+2]>Open[i+2]
            &&Close[i+2]>=Close[i+3]&&Close[i+3]>Open[i+3]
            &&Close[i+3]>=Close[i+4]&&Close[i+4]>Open[i+4]
            &&Close[i+5]<=Open[i+5])
            {
            Buffer1[i+1]=High[i+1]+Positions;
            if(Alerts == true && i<=12)
            Alert("4 Бай бара ", Symbol());
            }
он ставит отметку при обнаружении 4 последовательных бай баров, все чудненько работает!!!

А вот навожу пример кода который не работает:

   if(Time[0] == prevtime)   return(-1);
   prevtime = Time[0];
   int limit = Bars-IndicatorCounted();
   for(int i=0; i<limit-1;i++)
    {
         if(Close[i+1]<Open[i+1]
            &&Close[i+1]<=Close[i+2]&&Close[i+2]<Open[i+2]
            &&Close[i+2]<=Close[i+3]&&Close[i+3]<Open[i+3]
            &&Close[i+3]<=Close[i+4]&&Close[i+4]<Open[i+4]
            &&Close[i+5]>=Open[i+5])
            {
            Buffer5[i+1]=Low[i+1]-Positions;
            if(Alerts == true && i<=12)
            Alert("4 Селл бара ", Symbol());
           }

все, блин, в зеркальном отражении, но эта хрень не работает!!!! Пожалуйста помогите! Объясните что к чему!!!

 
Maksim Neimerik:

Навожу пример кода который работает:


все, блин, в зеркальном отражении, но эта хрень не работает!!!! Пожалуйста помогите! Объясните что к чему!!!


Ответы уже были. Не надо выходить за пределы массивов.

Выложите весь код.

 
Victor Nikolaev:


Ответы уже были. Не надо выходить за пределы массивов.

Выложите весь код.

Вот полностью код:

//+------------------------------------------------------------------+
//|                                              BarsStreet 1.02.mq4 |
//|                                                   MaksimNeimeryk |
//|                                              deilyplanet@ukr.net |
//+------------------------------------------------------------------+
#property copyright "MaksimNeimeryk"
#property link      "deilyplanet@ukr.net"
#property version   "1.02"
#property strict
#property indicator_chart_window
#property indicator_buffers 8
#property indicator_color1 Blue
#property indicator_color2 Blue
#property indicator_color3 Blue
#property indicator_color4 Blue
#property indicator_color5 Red
#property indicator_color6 Red
#property indicator_color7 Red
#property indicator_color8 Red

extern int Position = 3; //Позиция метки индикатора (в пунктах)
extern bool Alerts = true; //Алерт

static datetime prevtime = 0;

double Buffer1[];
double Buffer2[];
double Buffer3[];
double Buffer4[];
double Buffer5[];
double Buffer6[];
double Buffer7[];
double Buffer8[];
double Positions;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
   SetIndexBuffer(0, Buffer1);
   SetIndexStyle(0, DRAW_ARROW,0,4);
   SetIndexArrow(0,143);
  
   SetIndexBuffer(1, Buffer2);
   SetIndexStyle(1, DRAW_ARROW,0,4);
   SetIndexArrow(1,145);

   SetIndexBuffer(2, Buffer3);
   SetIndexStyle(2, DRAW_ARROW,0,4);
   SetIndexArrow(2,147);

   SetIndexBuffer(3, Buffer4);
   SetIndexStyle(3, DRAW_ARROW,0,4);
   SetIndexArrow(3,149);

   SetIndexBuffer(4, Buffer5);
   SetIndexStyle(4, DRAW_ARROW,0,4);
   SetIndexArrow(4,143);

   SetIndexBuffer(5, Buffer6);
   SetIndexStyle(5, DRAW_ARROW,0,4);
   SetIndexArrow(5,145);

   SetIndexBuffer(6, Buffer7);
   SetIndexStyle(6, DRAW_ARROW,0,4);
   SetIndexArrow(6,147);

   SetIndexBuffer(7, Buffer8);
   SetIndexStyle(7, DRAW_ARROW,0,4);
   SetIndexArrow(7,149);
  
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| 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[])
 
  {
   Positions=NormalizeDouble(Position*Point,Digits());  
   if(Time[0] == prevtime)   return(-1);
   prevtime = Time[0];
   int limit = Bars-IndicatorCounted();
   for(int i=0; i<limit-1;i++)
    {
         if(Close[i+1]>Open[i+1]
            &&Close[i+1]>=Close[i+2]&&Close[i+2]>Open[i+2]
            &&Close[i+2]>=Close[i+3]&&Close[i+3]>Open[i+3]
            &&Close[i+3]>=Close[i+4]&&Close[i+4]>Open[i+4]
            &&Close[i+5]<=Open[i+5])
            {
            Buffer1[i+1]=High[i+1]+Positions;
            if(Alerts == true && i<=12)
            Alert("4 Бай бара ", Symbol());
            }
         if(Close[i+1]>Open[i+1]
            &&Close[i+1]>=Close[i+2]&&Close[i+2]>Open[i+2]
            &&Close[i+2]>=Close[i+3]&&Close[i+3]>Open[i+3]
            &&Close[i+3]>=Close[i+4]&&Close[i+4]>Open[i+4]
            &&Close[i+4]>=Close[i+5]&&Close[i+5]>Open[i+5]
            &&Close[i+5]>=Close[i+6]&&Close[i+6]>Open[i+6]
            &&Close[i+7]<=Open[i+7])
            {
            Buffer2[i+1]=High[i+1]+Positions;
            if(Alerts == true && i<=12)
            Alert("6 Бай баров ", Symbol());
            }
         if(Close[i+1]>Open[i+1]
            &&Close[i+1]>=Close[i+2]&&Close[i+2]>Open[i+2]
            &&Close[i+2]>=Close[i+3]&&Close[i+3]>Open[i+3]
            &&Close[i+3]>=Close[i+4]&&Close[i+4]>Open[i+4]
            &&Close[i+4]>=Close[i+5]&&Close[i+5]>Open[i+5]
            &&Close[i+5]>=Close[i+6]&&Close[i+6]>Open[i+6]
            &&Close[i+6]>=Close[i+7]&&Close[i+7]>Open[i+7]
            &&Close[i+7]>=Close[i+8]&&Close[i+8]>Open[i+8]
            &&Close[i+9]<=Open[i+9])
            {
            Buffer3[i+1]=High[i+1]+Positions;
            if(Alerts == true && i<=12)
            Alert("8 Бай баров ", Symbol());
            }
         if(Close[i+1]>Open[i+1]
            &&Close[i+1]>=Close[i+2]&&Close[i+2]>Open[i+2]
            &&Close[i+2]>=Close[i+3]&&Close[i+3]>Open[i+3]
            &&Close[i+3]>=Close[i+4]&&Close[i+4]>Open[i+4]
            &&Close[i+4]>=Close[i+5]&&Close[i+5]>Open[i+5]
            &&Close[i+5]>=Close[i+6]&&Close[i+6]>Open[i+6]
            &&Close[i+6]>=Close[i+7]&&Close[i+7]>Open[i+7]
            &&Close[i+7]>=Close[i+8]&&Close[i+8]>Open[i+8]
            &&Close[i+8]>=Close[i+9]&&Close[i+9]>Open[i+9]
            &&Close[i+9]>=Close[i+10]&&Close[i+10]>Open[i+10]
            &&Close[i+11]<=Open[i+11])
            {
            Buffer4[i+1]=High[i+1]+Positions;
            if(Alerts == true && i<=12)
            Alert("10 Бай баров ", Symbol());
            }
         if(Close[i+1]<Open[i+1]
            &&Close[i+1]<=Close[i+2]&&Close[i+2]<Open[i+2]
            &&Close[i+2]<=Close[i+3]&&Close[i+3]<Open[i+3]
            &&Close[i+3]<=Close[i+4]&&Close[i+4]<Open[i+4]
            &&Close[i+5]>=Open[i+5])
            {
            Buffer5[i+1]=Low[i+1]-Positions;
            if(Alerts == true && i<=12)
            Alert("4 Селл бара ", Symbol());
            }
         if(Close[i+1]<Open[i+1]
            &&Close[i+1]<=Close[i+2]&&Close[i+2]<Open[i+2]
            &&Close[i+2]<=Close[i+3]&&Close[i+3]<Open[i+3]
            &&Close[i+3]<=Close[i+4]&&Close[i+4]<Open[i+4]
            &&Close[i+4]<=Close[i+5]&&Close[i+5]<Open[i+5]
            &&Close[i+5]<=Close[i+6]&&Close[i+6]<Open[i+6]
            &&Close[i+7]>=Open[i+7])
            {
            Buffer6[i+1]=Low[i+1]-Positions;
            if(Alerts == true && i<=12)
            Alert("6 Селл баров ", Symbol());
            }
         if(Close[i+1]<Open[i+1]
            &&Close[i+1]<=Close[i+2]&&Close[i+2]<Open[i+2]
            &&Close[i+2]<=Close[i+3]&&Close[i+3]<Open[i+3]
            &&Close[i+3]<=Close[i+4]&&Close[i+4]<Open[i+4]
            &&Close[i+4]<=Close[i+5]&&Close[i+5]<Open[i+5]
            &&Close[i+5]<=Close[i+6]&&Close[i+6]<Open[i+6]
            &&Close[i+6]<=Close[i+7]&&Close[i+7]<Open[i+7]
            &&Close[i+7]<=Close[i+8]&&Close[i+8]<Open[i+8]
            &&Close[i+9]>=Open[i+9])
            {
            Buffer7[i+1]=Low[i+1]-Positions;
            if(Alerts == true && i<=12)
            Alert("8 Селл баров ", Symbol());
            }
         if(Close[i+1]<Open[i+1]
            &&Close[i+1]<=Close[i+2]&&Close[i+2]<Open[i+2]
            &&Close[i+2]<=Close[i+3]&&Close[i+3]<Open[i+3]
            &&Close[i+3]<=Close[i+4]&&Close[i+4]<Open[i+4]
            &&Close[i+4]<=Close[i+5]&&Close[i+5]<Open[i+5]
            &&Close[i+5]<=Close[i+6]&&Close[i+6]<Open[i+6]
            &&Close[i+6]<=Close[i+7]&&Close[i+7]<Open[i+7]
            &&Close[i+7]<=Close[i+8]&&Close[i+8]<Open[i+8]
            &&Close[i+8]<=Close[i+9]&&Close[i+9]<Open[i+9]
            &&Close[i+9]<=Close[i+10]&&Close[i+10]<Open[i+10]
            &&Close[i+11]>=Open[i+11])
            {
            Buffer8[i+1]=Low[i+1]-Positions;
            if(Alerts == true && i<=12)
            Alert("10 Селл баров ", Symbol());
            }
     }
    return(rates_total);
  }
 
//+------------------------------------------------------------------+

 
Выход за пределы массива был из-за неверного limit
//+------------------------------------------------------------------+
//|                                              BarsStreet 1.02.mq4 |
//|                                                   MaksimNeimeryk |
//|                                              deilyplanet@ukr.net |
//+------------------------------------------------------------------+
#property copyright "MaksimNeimeryk"
#property link      "deilyplanet@ukr.net"
#property version   "1.02"
#property strict
#property indicator_chart_window
#property indicator_buffers 8
#property indicator_color1 Blue
#property indicator_color2 Blue
#property indicator_color3 Blue
#property indicator_color4 Blue
#property indicator_color5 Red
#property indicator_color6 Red
#property indicator_color7 Red
#property indicator_color8 Red

extern int Position = 3; //Позиция метки индикатора (в пунктах)
extern bool Alerts = true; //Алерт

static datetime prevtime = 0;

double Buffer1[];
double Buffer2[];
double Buffer3[];
double Buffer4[];
double Buffer5[];
double Buffer6[];
double Buffer7[];
double Buffer8[];
double Positions;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
   SetIndexBuffer(0, Buffer1);
   SetIndexStyle(0, DRAW_ARROW,0,4);
   SetIndexArrow(0,143);
   
   SetIndexBuffer(1, Buffer2);
   SetIndexStyle(1, DRAW_ARROW,0,4);
   SetIndexArrow(1,145);

   SetIndexBuffer(2, Buffer3);
   SetIndexStyle(2, DRAW_ARROW,0,4);
   SetIndexArrow(2,147);

   SetIndexBuffer(3, Buffer4);
   SetIndexStyle(3, DRAW_ARROW,0,4);
   SetIndexArrow(3,149);

   SetIndexBuffer(4, Buffer5);
   SetIndexStyle(4, DRAW_ARROW,0,4);
   SetIndexArrow(4,143);

   SetIndexBuffer(5, Buffer6);
   SetIndexStyle(5, DRAW_ARROW,0,4);
   SetIndexArrow(5,145);

   SetIndexBuffer(6, Buffer7);
   SetIndexStyle(6, DRAW_ARROW,0,4);
   SetIndexArrow(6,147);

   SetIndexBuffer(7, Buffer8);
   SetIndexStyle(7, DRAW_ARROW,0,4);
   SetIndexArrow(7,149);

   Positions=NormalizeDouble(Position*Point,Digits());   
   
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| 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 limit;
   bool test;
   if(Time[0] == prevtime)   return(-1);
   prevtime = Time[0];
   if ( Bars < 12 ) return(-1);
   else limit = MathMin( Bars - 12, Bars-IndicatorCounted() );

   for (int i=0; i<limit; i++ )
    {
         test = Close[i+1]>Open[i+1]&&Close[i+1]>=Close[i+2]
              &&Close[i+2]>Open[i+2]&&Close[i+2]>=Close[i+3]
              &&Close[i+3]>Open[i+3]&&Close[i+3]>=Close[i+4]
              &&Close[i+4]>Open[i+4];
         if ( test && Close[i+5]<=Open[i+5])
         {
            Buffer1[i+1]=High[i+1]+Positions;
            if(Alerts == true && i<=12)
            Alert(Symbol(), " 4 Бай бара i=", i);
         }
         if ( test ) test = test
            &&Close[i+4]>=Close[i+5]&&Close[i+5]>Open[i+5]
            &&Close[i+5]>=Close[i+6]&&Close[i+6]>Open[i+6];
         if ( test && Close[i+7]<=Open[i+7])
         {
            Buffer2[i+1]=High[i+1]+Positions;
            if(Alerts == true && i<=12)
            Alert(Symbol(), " 6 Бай баров i=", i);
         }
         if ( test ) test = test
            &&Close[i+6]>=Close[i+7]&&Close[i+7]>Open[i+7]
            &&Close[i+7]>=Close[i+8]&&Close[i+8]>Open[i+8];
         if ( test && Close[i+9]<=Open[i+9])
         {
            Buffer3[i+1]=High[i+1]+Positions;
            if(Alerts == true && i<=12)
            Alert(Symbol(), " 8 Бай баров i=", i);
         }
         if ( test ) test = test
            &&Close[i+8]>=Close[i+9]&&Close[i+9]>Open[i+9]
            &&Close[i+9]>=Close[i+10]&&Close[i+10]>Open[i+10];
         if ( test && Close[i+11]<=Open[i+11])
         {
            Buffer4[i+1]=High[i+1]+Positions;
            if(Alerts == true && i<=12)
            Alert(Symbol(), " 10 Бай баров i=", i);
         }

         test = Close[i+1]<Open[i+1]&&Close[i+1]<=Close[i+2]
              &&Close[i+2]<Open[i+2]&&Close[i+2]<=Close[i+3]
              &&Close[i+3]<Open[i+3]&&Close[i+3]<=Close[i+4]
              &&Close[i+4]<Open[i+4];
         if ( test && Close[i+5]>=Open[i+5])
         {
            Buffer5[i+1]=Low[i+1]-Positions;
            if(Alerts == true && i<=12)
            Alert(Symbol(), " 4 Селл бара i=", i);
         }
         if ( test ) test = test
            &&Close[i+4]<=Close[i+5]&&Close[i+5]<Open[i+5]
            &&Close[i+5]<=Close[i+6]&&Close[i+6]<Open[i+6];
         if ( test && Close[i+7]>=Open[i+7])
         {
            Buffer6[i+1]=Low[i+1]-Positions;
            if(Alerts == true && i<=12)
            Alert(Symbol(), " 6 Селл баров i=", i);
         }
         if ( test ) test = test
            &&Close[i+6]<=Close[i+7]&&Close[i+7]<Open[i+7]
            &&Close[i+7]<=Close[i+8]&&Close[i+8]<Open[i+8];
         if ( test && Close[i+9]>=Open[i+9])
         {
            Buffer7[i+1]=Low[i+1]-Positions;
            if(Alerts == true && i<=12)
            Alert(Symbol(), " 8 Селл баров i=", i);
         }
         if ( test ) test = test
            &&Close[i+8]<=Close[i+9]&&Close[i+9]<Open[i+9]
            &&Close[i+9]<=Close[i+10]&&Close[i+10]<Open[i+10];
         if ( test && Close[i+11]>=Open[i+11])
         {
            Buffer8[i+1]=Low[i+1]-Positions;
            if(Alerts == true && i<=12)
            Alert(Symbol(), " 10 Селл баров i=", i);
         }

     }
    return(rates_total);
  }
  
//+------------------------------------------------------------------+
 
Maksim Neimerik:

Вот полностью код:


Исходя из расчета начального бара, который здесь приведен, обращаться в теле цикла можно только к барам i и i + 1. Все остальные - выход за пределы массива. Нужно менять код расчета значения переменной limit так, чтобы при добавлении к ней 11 баров она не указывала на бары за левым краем графика, которых не существует. 

Для расчета значения limit использую такую функцию:

int GetRecalcIndex(int& total, const int ratesTotal, const int prevCalculated)
{
   total = ratesTotal - 1;                                                                         
                                                   
   if (i_indBarsCount > 0 && i_indBarsCount < total)
      total = MathMin(i_indBarsCount, total);                      
                                                   
   if (prevCalculated < ratesTotal - 1)                     
   {       
      InitializeBuffers();
      return (total);
   }
   
   return (MathMin(ratesTotal - prevCalculated, total));                            
}

Вызов InitializeBuffers() можно убрать. Здесь i_indBarsCount указывает максимальное кол-во баров, на которых индикатор должен производить отображение своих данных. Можно установить его равным 0 и тогда индикатор будет отображаться на всех возможных барах. Для Ваших целей в функции нужно изменить одну строку:

   total = ratesTotal - 1;                                                                         

на:

   total = ratesTotal - 11;                                                                         

Вызывать функцию нужно так:

   int total;   
   int limit = GetRecalcIndex(total, rates_total, prev_calculated);                                

 
большое всем спасибо!!! все понял
 

сделайте проще - заведите два индексных буфера в которых будете считать кол-во чёрных/белых свечей (длины последовательностей - вы же это считаете в условиях).
если текущая свеча белая - то счётчик белых увеличивается, а чёрных обнуляется. Ну и наоборот конечно :-)

и по показаниям этих счётчиков уже выставьте свои алерты. Код покороче будет и без массивных copy-paste и длинных повторений.

 
Maxim Kuznetsov:

сделайте проще - заведите два индексных буфера в которых будете считать кол-во чёрных/белых свечей (длины последовательностей - вы же это считаете в условиях).
если текущая свеча белая - то счётчик белых увеличивается, а чёрных обнуляется. Ну и наоборот конечно :-)

и по показаниям этих счётчиков уже выставьте свои алерты. Код покороче будет и без массивных copy-paste и длинных повторений.

Оно может быть и проще, но я только начинаю программировать и, честно говоря, не совсем представляю как это сделать)))
 
Скажите кто-нибудь а есть ли возможность всунуть в индикатор больше 8 буферов?
 
Maksim Neimerik:
Скажите кто-нибудь а есть ли возможность всунуть в индикатор больше 8 буферов?
512 хватит?
IndicatorBuffers - Пользовательские индикаторы - Справочник MQL4
IndicatorBuffers - Пользовательские индикаторы - Справочник MQL4
  • docs.mql4.com
IndicatorBuffers - Пользовательские индикаторы - Справочник MQL4
 
Alexey Viktorov:
512 хватит?
О, нормуль, спасибо)))
Причина обращения: