Alert срабатывает один раз

 

Здравствуйте

Проблема: Мне надо чтобы алерт срабатывал всегда, пока он активирован (активирован именно кликом на звёздочку). Сейчас же окно алерта срабатывает один раз, если алерт активирован именно кликом на звёздочку, и при повторном заходе линии в зону больше не появляется.

1. нажимаю на звёздочку (становится красной)
2. активируется алерт
3. линия индикатора заходит/уже находится в зоне
4. срабатывает алерт
5. нажимаю на звёздочку (становится серой)
6. выключается алерт
7. нажимаю на звёздочку (становится красной)
8. активируется алерт
9. линия индикатора повторно заходит/уже находится в зоне
10. алерт не срабатывает

При этом, если все эти действия выполнить в окне настроек индикатора:

1. включаю алерт
2. линия индикатора заходит/уже находится в зоне
3. срабатывает алерт. И он срабатывает каждый раз когда линия выходит из зоны и возвращается снова.

#property copyright "Copyright © 2005, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net/"
//----
#property indicator_separate_window
#property indicator_minimum -100
#property indicator_maximum 0
#property indicator_buffers 1
#property indicator_color1 OrangeRed
#property indicator_width1  1
#property indicator_level1 -20
#property indicator_level2 -50
#property indicator_level3 -80
#property indicator_levelcolor DimGray
#property indicator_levelwidth 1
#property indicator_levelstyle 4

//---- input parameters
extern bool Сигнал_красная_верх = false;
extern bool Сигнал_красная_низ = false;

static int pos;
int n=0;

//---- buffers
double ExtWPRBuffer1[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
   string sShortName;
//---- indicator buffer mapping
   SetIndexBuffer(0, ExtWPRBuffer1);
//---- indicator line
   SetIndexStyle(0, DRAW_LINE);
   SetIndexLabel(0, NULL);
//---- name for DataWindow and indicator subwindow label
   sShortName="Сигнал для:" + 14;
   IndicatorShortName(sShortName);
   SetIndexLabel(0, sShortName);
//---- first values aren't drawn
   SetIndexDrawBegin(0, 14);
//----
   pos = 0;
   return(0);
  }
//+------------------------------------------------------------------+
//                                         
//+------------------------------------------------------------------+
int start()
  {
   ObjectCreate("Bg1",OBJ_LABEL,0,0,0,0,0);
   ObjectSet("Bg1",OBJPROP_CORNER, 3);
   ObjectSet("Bg1",OBJPROP_XDISTANCE,18);
   ObjectSet("Bg1",OBJPROP_YDISTANCE,35);
   ObjectSetText("Bg1","*",18,"Tahoma",C'70,70,70');

   ObjectCreate("Bg2",OBJ_LABEL,0,0,0,0,0);
   ObjectSet("Bg2",OBJPROP_CORNER, 3);
   ObjectSet("Bg2",OBJPROP_XDISTANCE,18);
   ObjectSet("Bg2",OBJPROP_YDISTANCE,5);
   ObjectSetText("Bg2","*",18,"Tahoma",C'70,70,70');

   int i, nCountedBars;
   double dMaxHigh, dMinLow;
//---- insufficient data
   if(Bars <= 14)
      return(0);
//---- bars count that does not changed after last indicator launch.
   nCountedBars = IndicatorCounted();

      i = Bars - 14 - 1;
      if(nCountedBars > 14)
         i = Bars - nCountedBars - 1;
      while(i >= 0)
        {
         dMaxHigh = High[Highest(NULL, 0, MODE_HIGH, 14, i)];
         dMinLow = Low[Lowest(NULL, 0, MODE_LOW, 14, i)];
         if(!CompareDouble((dMaxHigh - dMinLow), 0.0))
            ExtWPRBuffer1[i] = -100*(dMaxHigh - Close[i]) / (dMaxHigh - dMinLow);
         i--;
        }
//----
   Alerts();
   return(0);
  }
//+------------------------------------------------------------------+
//| Функция сранения двух вещественных чисел.                        |
//+------------------------------------------------------------------+
bool CompareDouble(double Number1, double Number2)
  {
   bool Compare = NormalizeDouble(Number1 - Number2, 8) == 0;
   return(Compare);
  }
//+------------------------------------------------------------------+
void Alerts()
  {
   if(Сигнал_красная_низ == true)
     {
      if(pos == 0 && ExtWPRBuffer1[1] < -100 + 20)
        {
         pos = -1;
         Alert("Сигнал на покупку на "+Symbol());
        }
      ObjectSetText("Bg2","*",18,"Tahoma",OrangeRed);
     }
   else
     {
      ObjectSetText("Bg2","*",18,"Tahoma",C'70,70,70');
     }

   if(Сигнал_красная_верх == true)
     {
      if(pos == 0 && ExtWPRBuffer1[1] > -20)
        {
         pos = 1;
         Alert("Сигнал на продажу на "+Symbol());
        }
      ObjectSetText("Bg1","*",18,"Tahoma",OrangeRed);
     }
   else
     {
      ObjectSetText("Bg1","*",18,"Tahoma",C'70,70,70');
     }
  }
//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
   if(id==CHARTEVENT_OBJECT_CLICK)
     {
      if(sparam=="Bg1")
        {
         if(n==1)
           {
            Сигнал_красная_верх = false;
            ObjectSetInteger(0,"Bg1",OBJPROP_COLOR,C'70,70,70');
            n=0;
            return;
           }
         if(n==0)
           {
            Сигнал_красная_верх = true;
            ObjectSetInteger(0,"Bg1",OBJPROP_COLOR,clrOrangeRed);
            n=1;
            return;
           }
        }

      if(sparam=="Bg2")
        {
         if(n==1)
           {
            Сигнал_красная_низ = false;
            ObjectSetInteger(0,"Bg2",OBJPROP_COLOR,C'70,70,70');
            n=0;
            return;
           }
         if(n==0)
           {
            Сигнал_красная_низ = true;
            ObjectSetInteger(0,"Bg2",OBJPROP_COLOR,clrOrangeRed);
            n=1;
            return;
           }
        }
     }
  }
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   ObjectDelete(0,"Bg1");
   ObjectDelete(0,"Bg2");
   Comment("");
  }
//+------------------------------------------------------------------+
 
Для начала опишите, что именно нужно. Пока просто описана работа индикатора. В чем проблема то?
 
Ihor Herasko #:
Для начала опишите, что именно нужно. Пока просто описана работа индикатора. В чем проблема то?

Проблема: Мне надо чтобы алерт срабатывал всегда, пока он активирован (активирован именно кликом на звёздочку). Сейчас же окно алерта срабатывает один раз, если алерт активирован именно кликом на звёздочку, и при повторном заходе линии в зону больше не появляется.

1. нажимаю на звёздочку (становится красной)
2. активируется алерт
3. линия индикатора заходит/уже находится в зоне
4. срабатывает алерт
5. нажимаю на звёздочку (становится серой)
6. выключается алерт
7. нажимаю на звёздочку (становится красной)
8. активируется алерт
9. линия индикатора повторно заходит/уже находится в зоне
10. алерт не срабатывает

При этом, если все эти действия выполнить в окне настроек индикатора:

1. включаю алерт
2. линия индикатора заходит/уже находится в зоне
3. срабатывает алерт. И он срабатывает каждый раз когда линия выходит из зоны и возвращается снова.

 
Или может есть функция перезагрузки индикатора? Если например сменить ТФ, и затем снова вернуться на прежний, алерт снова срабатывает, но один раз. Идея какая: при клике на звёздочку, индикатор как бы заново загружается. Но это всё мысли вслух нуба...
 
Влад #:
Или может есть функция перезагрузки индикатора? Если например сменить ТФ, и затем снова вернуться на прежний, алерт снова срабатывает, но один раз. Идея какая: при клике на звёздочку, индикатор как бы заново загружается. Но это всё мысли вслух нуба...

Это сложное решение проблемы ))

Гораздо проще исправить код. При включении соответствующего сигнала он будет появляться один раз на каждом баре, где есть сигнал. Так, пока линия находится в зоне перекупленности/перепроданности будет сигналить на каждом баре.

Файлы:
Test2.mq4  11 kb
 
Ihor Herasko #:

Это сложное решение проблемы ))

Гораздо проще исправить код. При включении соответствующего сигнала он будет появляться один раз на каждом баре, где есть сигнал. Так, пока линия находится в зоне перекупленности/перепроданности будет сигналить на каждом баре.

Спасибо Вам большое, это именно то, что надо.
 
Ihor Herasko #:

Это сложное решение проблемы ))

Гораздо проще исправить код. При включении соответствующего сигнала он будет появляться один раз на каждом баре, где есть сигнал. Так, пока линия находится в зоне перекупленности/перепроданности будет сигналить на каждом баре.

Игорь, а будет наглостью если попрошу прикрутить алерт на пересечение линии 50%? :D У меня беда с этими if-else. Просто пересечение, не важно снизу или сверху. По отдельности получилось сделать, но тогда на графике присутствуют две линии, и если например мне нужен алерт при пересечении линии сверху, то кликаю на одну линию, если снизу, то вторую. Вот такое рука-лицо.
 
Пересечение в моём исполнении и Вашим кодом:

//+------------------------------------------------------------------+
//|                                                      ProjectName |
//|                                      Copyright 2018, CompanyName |
//|                                       http://www.companyname.net |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2005, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net/"
//----
#property indicator_separate_window
#property indicator_minimum -100
#property indicator_maximum 0
#property indicator_buffers 1
#property indicator_color1 OrangeRed
#property indicator_width1  1
#property indicator_level1 -20
#property indicator_level2 -50
#property indicator_level3 -80
#property indicator_levelcolor DimGray
#property indicator_levelwidth 1
#property indicator_levelstyle 4

//---- input parameters
extern bool Сигнал_красная_верх = false;
extern bool Сигнал_красная_низ = false;
extern bool Сигнал_середина_верх = false;
extern bool Сигнал_середина_низ = false;

datetime g_dtLastAlert = 0;
int n=0;

//---- buffers
double ExtWPRBuffer1[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
   string sShortName;
//---- indicator buffer mapping
   SetIndexBuffer(0, ExtWPRBuffer1);
//---- indicator line
   SetIndexStyle(0, DRAW_LINE);
   SetIndexLabel(0, NULL);
//---- name for DataWindow and indicator subwindow label
   sShortName="Сигнал для:" + 14;
   IndicatorShortName(sShortName);
   SetIndexLabel(0, sShortName);
//---- first values aren't drawn
   SetIndexDrawBegin(0, 14);
//----
   return(0);
  }
//+------------------------------------------------------------------+
//
//+------------------------------------------------------------------+
int start()
  {
   ObjectCreate("Bg1",OBJ_LABEL,0,0,0,0,0);
   ObjectSet("Bg1",OBJPROP_CORNER, 3);
   ObjectSet("Bg1",OBJPROP_XDISTANCE,18);
   ObjectSet("Bg1",OBJPROP_YDISTANCE,95);
   ObjectSetText("Bg1","*",18,"Tahoma",C'70,70,70');

   ObjectCreate("Sep1",OBJ_LABEL,0,0,0,0,0);
   ObjectSet("Sep1",OBJPROP_CORNER, 3);
   ObjectSet("Sep1",OBJPROP_XDISTANCE,18);
   ObjectSet("Sep1",OBJPROP_YDISTANCE,70);
   ObjectSetText("Sep1","—",18,"Tahoma",C'70,70,70');

   ObjectCreate("Sep2",OBJ_LABEL,0,0,0,0,0);
   ObjectSet("Sep2",OBJPROP_CORNER, 3);
   ObjectSet("Sep2",OBJPROP_XDISTANCE,18);
   ObjectSet("Sep2",OBJPROP_YDISTANCE,40);
   ObjectSetText("Sep2","—",18,"Tahoma",C'70,70,70');

   ObjectCreate("Bg2",OBJ_LABEL,0,0,0,0,0);
   ObjectSet("Bg2",OBJPROP_CORNER, 3);
   ObjectSet("Bg2",OBJPROP_XDISTANCE,18);
   ObjectSet("Bg2",OBJPROP_YDISTANCE,5);
   ObjectSetText("Bg2","*",18,"Tahoma",C'70,70,70');

   int i, nCountedBars;
   double dMaxHigh, dMinLow;
//---- insufficient data
   if(Bars <= 14)
      return(0);
//---- bars count that does not changed after last indicator launch.
   nCountedBars = IndicatorCounted();

   i = Bars - 14 - 1;
   if(nCountedBars > 14)
      i = Bars - nCountedBars - 1;
   while(i >= 0)
     {
      dMaxHigh = High[Highest(NULL, 0, MODE_HIGH, 14, i)];
      dMinLow = Low[Lowest(NULL, 0, MODE_LOW, 14, i)];
      if(!CompareDouble((dMaxHigh - dMinLow), 0.0))
         ExtWPRBuffer1[i] = -100*(dMaxHigh - Close[i]) / (dMaxHigh - dMinLow);
      i--;
     }
//----
   Alerts();
   return(0);
  }
//+------------------------------------------------------------------+
//| Функция сранения двух вещественных чисел.                        |
//+------------------------------------------------------------------+
bool CompareDouble(double Number1, double Number2)
  {
   bool Compare = NormalizeDouble(Number1 - Number2, 8) == 0;
   return(Compare);
  }
//+------------------------------------------------------------------+
void Alerts()
  {
   datetime dtCurBar = iTime(NULL, PERIOD_CURRENT, 0);
   if(Сигнал_красная_низ == true)
     {
      if(g_dtLastAlert < dtCurBar && ExtWPRBuffer1[1] < -80)
        {
         g_dtLastAlert = dtCurBar;
         Alert("Сигнал на покупку на "+Symbol());
        }
      ObjectSetText("Bg2","*",18,"Tahoma",OrangeRed);
     }
   else
     {
      ObjectSetText("Bg2","*",18,"Tahoma",C'70,70,70');
     }

   if(Сигнал_красная_верх == true)
     {
      if(g_dtLastAlert < dtCurBar && ExtWPRBuffer1[1] > -20)
        {
         g_dtLastAlert = dtCurBar;
         Alert("Сигнал на продажу на "+Symbol());
        }
      ObjectSetText("Bg1","*",18,"Tahoma",OrangeRed);
     }
   else
     {
      ObjectSetText("Bg1","*",18,"Tahoma",C'70,70,70');
     }

   if(Сигнал_середина_верх == true)
     {
      if(g_dtLastAlert < dtCurBar && ExtWPRBuffer1[1] > -50)
        {
         g_dtLastAlert = dtCurBar;
         Alert("Середина на "+Symbol());
        }
      ObjectSetText("Sep1","—",18,"Tahoma",OrangeRed);
     }
   else
     {
      ObjectSetText("Sep1","—",18,"Tahoma",C'70,70,70');
     }

   if(Сигнал_середина_низ == true)
     {
      if(g_dtLastAlert < dtCurBar && ExtWPRBuffer1[1] < -50)
        {
         g_dtLastAlert = dtCurBar;
         Alert("Середина на "+Symbol());
        }
      ObjectSetText("Sep2","—",18,"Tahoma",OrangeRed);
     }
   else
     {
      ObjectSetText("Sep2","—",18,"Tahoma",C'70,70,70');
     }
  }
//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
   if(id==CHARTEVENT_OBJECT_CLICK)
     {
      if(sparam=="Bg1")
        {
         if(n==1)
           {
            Сигнал_красная_верх = false;
            ObjectSetInteger(0,"Bg1",OBJPROP_COLOR,C'70,70,70');
            n=0;
            return;
           }
         if(n==0)
           {
            Сигнал_красная_верх = true;
            ObjectSetInteger(0,"Bg1",OBJPROP_COLOR,clrOrangeRed);
            n=1;
            return;
           }
        }

      if(sparam=="Bg2")
        {
         if(n==1)
           {
            Сигнал_красная_низ = false;
            ObjectSetInteger(0,"Bg2",OBJPROP_COLOR,C'70,70,70');
            n=0;
            return;
           }
         if(n==0)
           {
            Сигнал_красная_низ = true;
            ObjectSetInteger(0,"Bg2",OBJPROP_COLOR,clrOrangeRed);
            n=1;
            return;
           }
        }

      if(sparam=="Sep2")
        {
         if(n==1)
           {
            Сигнал_середина_низ = false;
            ObjectSetInteger(0,"Sep2",OBJPROP_COLOR,C'70,70,70');
            n=0;
            return;
           }
         if(n==0)
           {
            Сигнал_середина_низ = true;
            ObjectSetInteger(0,"Sep2",OBJPROP_COLOR,clrOrangeRed);
            n=1;
            return;
           }
        }

      if(sparam=="Sep1")
        {
         if(n==1)
           {
            Сигнал_середина_верх = false;
            ObjectSetInteger(0,"Sep1",OBJPROP_COLOR,C'70,70,70');
            n=0;
            return;
           }
         if(n==0)
           {
            Сигнал_середина_верх = true;
            ObjectSetInteger(0,"Sep1",OBJPROP_COLOR,clrOrangeRed);
            n=1;
            return;
           }
        }
     }
  }
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   ObjectDelete(0,"Bg1");
   ObjectDelete(0,"Bg2");
   Comment("");
  }
//+------------------------------------------------------------------+
 
Влад #:
Игорь, а будет наглостью если попрошу прикрутить алерт на пересечение линии 50%? :D У меня беда с этими if-else. Просто пересечение, не важно снизу или сверху. По отдельности получилось сделать, но тогда на графике присутствуют две линии, и если например мне нужен алерт при пересечении линии сверху, то кликаю на одну линию, если снизу, то вторую. Вот такое рука-лицо.

Можно сделать. Только учитывайте, что это не будет продуманным решением. Приделано пятое колесо к телеге.

P. S. К модераторам: перенесите, пожалуйста, ветку в раздел для MQL4.

Файлы:
Test2.mq4  12 kb