Фильтрация сигналов алерта

 
Здравствуйте! В mql4 полный новичек, имеется готовый индикатор, решил добавить в него алерт. Когда условия выполняются, алерт начинает очень много "пиликать". Как от этого избавиться, чтобы он издавал сигналы всего раза три. Вот мой код. Код на алерт выделил.

int start(){
  int    counted_bars=IndicatorCounted();
  if(counted_bars<0) return(-1);
  // пересчитаем последний
  if(counted_bars>0) counted_bars--;
  int limit=Bars-counted_bars-1;
  SetIndexDrawBegin(5, Bars );  // буфер типов сигналов
  
  //limit = 500;
  CalcAO(limit);
  int numwindow = WindowFind(indicatorname); 
  if( numwindow == -1 )numwindow = 0;
  for( int i = limit; i>0; i -- ){
     
     string addname = "_ao_";
     if( mode == 1 )addname = "_aonorm_";
     if( mode == 2 )addname =  "_rsi_" ;
     string objname = LINEAO+addname+Time[i];
     ObjectDelete(objname  );
     string objnameprice = LINEPRICE+Time[i];
     ObjectDelete(objnameprice  );
     bool isfoundpik = findpik(i); 
     if(  isfoundpik  ){
     // если есть пик для этого то его отразить
       // нарисовать линию от и до
       //Print("есь пик, бар номер ", i );  
       ObjectCreate(objname, OBJ_TREND, numwindow, Time[foundpik], ExtBuffer0[foundpik], Time[i+1], ExtBuffer0[i+1]   );
       color linc = Blue;
       ObjectSet(objname   , OBJPROP_RAY, 0);
       ObjectSet(objname   , OBJPROP_WIDTH, 2);
       ObjectSet(objname   , OBJPROP_COLOR, linc);
         int kol = 0;
         while (kol<2){
         Alert(Symbol(),Period());
         kol = kol+1;
         }
       if( flagdivergence == 1 ){
         double drp2 = pikprice2*sign(pikprice2);
         double drp1 = pikprice1*sign(pikprice1);
         //Print("draw line on chart ", pikprice2, pikprice1 );
         ObjectCreate(objnameprice, OBJ_TREND, 0, Time[foundpikprice2], drp2, Time[foundpikprice1], drp1   );
         ObjectSet(objnameprice   , OBJPROP_RAY, 0);
         ObjectSet(objnameprice   , OBJPROP_WIDTH, 2);
         ObjectSet(objnameprice   , OBJPROP_COLOR, linc);
       
       }
 
       //риссуем линию
     }else{
       //Print("нету пика ");
     }
     ShowSignals(i, isfoundpik, iif( flagdivergence==1, true, false ) );
     //Print(ExtBuffer0[i],ExtBuffer1[i],ExtBuffer2[i],BuyBuffer );
  }
  
  return(0);
}
 
fase169:
Здравствуйте! В mql4 полный новичек, имеется готовый индикатор, решил добавить в него алерт. Когда условия выполняются, алерт начинает очень много "пиликать". Как от этого избавиться, чтобы он издавал сигналы всего раза три. Вот мой код. Код на алерт выделил.

С алертом все ок, очевидно, слишком часто находятся пики в этой части кода

bool isfoundpik = findpik(i); 
     if(  isfoundpik  ){

 Попробуйте перед алертом вставить Print, чтобы посмотреть, как часто находятся пики

 
Alexey Volchanskiy:

С алертом все ок, очевидно, слишком часто находятся пики в этой части кода

 Попробуйте перед алертом вставить Print, чтобы посмотреть, как часто находятся пики

 

Ну да всё дело в функции

 bool isfoundpik = findpik(i);


Т.е вот я например удаляю эту синюю линию с графика, через секунду он снова рисуется. Заканчивается алерт, когда закрывается 1 бар на индикаторе AO. Как тогда нормально всё сделать? 

 
fase169:

 

Ну да всё дело в функции

 bool isfoundpik = findpik(i);


Т.е вот я например удаляю эту синюю линию с графика, через секунду он снова рисуется. Заканчивается алерт, когда закрывается 1 бар на индикаторе AO. Как тогда нормально всё сделать? 

Код findpik(i) выложите, посмотрим, может, что и найдем вредного )
 
Alexey Volchanskiy:
Код findpik(i) выложите, посмотрим, может, что и найдем вредного )
Давайте сам файл скину вам сюда)
Файлы:
 
fase169:
Давайте сам файл скину вам сюда)
Сейчас посмотрю, что там не так
 

  АНАЛогичная ситуация. Срабатывает по несколько раз... Индикатор показывает стрелкой место и направление пересечения бара с МА:

int OnCalculate(const int rates_total,                         //Размер входных таймсерий

                const int prev_calculated,                     //Обработано баров на предыдущем вызове

                const datetime &time[],                        //Time

                const double &open[],                          //Open

                const double &high[],                          //High

                const double &low[],                           //Low

                const double &close[],                         //Close

                const long &tick_volume[],                     //Tick Volume

                const long &volume[],                          //Real Volume

                const int &spread[])                           //Spread

{

//---

if (Bars <= MA_Period) return (0);                             //Проверка количества баров на достаточность для расчёта

int ExtCountedBars = IndicatorCounted();                       //Получение уже посчитанных баров

if (ExtCountedBars < 0) return (-1);                           //Проверка на возможные ошибки

if (ExtCountedBars > 0) ExtCountedBars--;                      //Последний посчитанный бар должен быть пересчитан

if (Volume[1] > 1)

for (int index = Bars - ExtCountedBars-1;index>=0; index--)    //Оосновной цикл расчёта индиатора

   {

   double oMA = iMA(NULL,MA_TimeFrame,MA_Period,MA_Shift,MA_Method,PRICE_CLOSE, index);   //Получение значений индикатора в переменные

   double cMA = iMA(NULL,MA_TimeFrame,MA_Period,MA_Shift,MA_Method,PRICE_OPEN, index);

   if (Open[index] < oMA && Close[index] > cMA)

//   if (Open[index] < oMA && Close[index] > oMA && Open[index] < cMA && Close[index] > cMA)                  //Проверка условий восходящего движения

      {

      UPBuffer[index] = Low[index]-20*Point;                   //Отрисовка стрелки ВВЕРХ

      Alert(Symbol(), " ", Period(), "Signal:UP!");

      }

   if (Open[index] > oMA && Close[index] < cMA)

//   if (Open[index] > oMA && Close[index] < oMA && Open[index] > cMA && Close[index] < cMA)                  //Проверка условий нисходящего движения

      {

      DOWNBuffer[index] = High[index]+20*Point;                //Отрисовка стрелки ВНИЗ

      Alert(Symbol(), " ", Period(), "Signal:DOWN!");

      }

   }

//--- return value of prev_calculated for next call

return(rates_total);

}


Стрелку 1 раз рисует, а алертов куча.

Помогите: Укажите ошибку или напишите решения (комментария в кокоде приветствуются)

Спасибо! 

 
Alexey Volchanskiy:
Сейчас посмотрю, что там не так
Вставьте первой строчкой #property strict и исправьте все ошибки и варнинги, там какое-то месиво багов, нет желания разбираться.
 

Решаю проблему всегда так:

 В шапку индикатора или советника

sinput ENUM_TIMEFRAMES RefreshBar      = PERIOD_M1;  // THE_REFRESH_BAR

 

sinput bool            UseSound        = True;       // USE_A_SOUND

Функция

//+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
//| isNewBar(). Возвращает True, если появился новый бар по символу-периоду, иначе False.                                         |>ok
//+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
bool NewBar(int per) {
//---
  static datetime tm=0; // В стат. переменной будем помнить время открытия последнего бара
  datetime        tb=(datetime)SeriesInfoInteger(Symbol(), per, SERIES_LASTBAR_DATE); // Текущее время
  
  if (tm==0) {      // Если это первый вызов функции
    tm=tb;          // Установим время и выйдем
    return (False);
  }
  if (tm!=tb) {     // Если время отличается
    tm=tb;          // Запомним время и вернем True
    return (True);
  }
  return (False);   // Дошли до сюда - значит бар не новый, вернем False
}

 Использую

if (UseSound && NewBar(RefreshBar)) PlaySound("\\Sounds\\MELOCH.wav");

 То есть: если условия выполнены даем алерт 1 раз в минуту с появлением нового бара, так как переменная   RefreshBar = PERIOD_M1.

Есть варианты попроще, но меня этот вполне устраивает. 

Причина обращения: