Выдавалось однократное сообщение?

 

Пишу эксперт, не знаю как написать код. Нужно чтобы по достижении ценой определенной точки или ниже нее, выдавалось однократное сообщение и в дальнейшем это условие больше не проверялось. Не нужно чтобы если цена ушла ниже этой точки то при каждом тике выдавалось сообщение. Мне нужно чтобы если цена опустилась ниже точки стоплосс ордера то выдавалось однократное сообщение. Просто сообщение я уже написал, загвоздка именно в том чтобы оно не повторялось. Стоп-лосс в самом ордере не задается, эта точка вычисляется по формуле в самом эксперте, ордер продолжает висеть в терминале как далеко цена бы не ушла и не закрывается по стоп-лоссу.

Желательно привести кусок кода, если вам не влом конечно :-)

 
Обнуляйте переменную, в которой хранится значение СЛ:
double SL = 1.2345;
if ( SL > 0.0 )
{
   if ( NormalizeDouble( SL - Bid, Digits ) >= 0.0 )
   {
      Alert( "SL!" );
      SL = -1.0;
   }
}

Или заведите флаг срабатывания алерта и проверяйте его состояние перед алертом.
 

Дело в том что я слежу за всеми ордерами сразу, и в моем случае данный вариант не подходит. Вот мой кусок кода, который получится в данном случае:

//+------------------------------------------------------------------+
int start()
{
if(OrdersTotal() < 1) //Если ордеров в терминале нет, то нифига не делаем
return(0);
if(OrdersTotal() > 0) //Если есть хоть один ордер в терминале
{
int total = OrdersTotal(); //Получаем количество открытых ордеров
for(int i = total - 1; i >= 0; i--)
{
OrderSelect(i, SELECT_BY_POS);
int type = OrderType(); //Получаем тип текущего ордера
double SL; // Цена на которой находится Стоп-лосс
switch(type)
{
case OP_BUY : SL = 2.3456;
if ( SL > 0.0 )
{
if ( NormalizeDouble( SL - Bid, Digits ) >= 0. 0 )
{
Alert( "SL!" );
SL = -1. 0;
}
}
break;
}
}
}
return (0);
}
//+------------------------------------------------------------------+

Алерты в данном случае будут идти постоянно при каждом тике. Нужно что-то другое.

 
<<Нужно что-то другое.>>
SL (скаляр) --> SL[] (вектор). См. в справке: "Массивы".
 
Тогда можно запоминать значение цены на предыдущем тике и давать алерт при "пересечении" ценой уровня СЛ.
int start()
  {
  if(OrdersTotal() < 1) //Если ордеров в терминале нет, то нифига не делаем
       return(0);

   static double preBid = Bid;
  
   if(OrdersTotal() > 0) //Если есть хоть один ордер в терминале
     {
       int total = OrdersTotal();  //Получаем количество открытых ордеров  
       for(int i = total - 1; i >= 0; i--)
         {
           OrderSelect(i, SELECT_BY_POS);
           int type = OrderType(); //Получаем тип текущего ордера
           double SL = OrderStopLoss();     // Цена на которой  находится Стоп-лосс
           switch(type)
             {
               case OP_BUY : 
                                  if ( NormalizeDouble( SL - Bid, Digits ) >= 0.0 && NormalizeDouble( preBid - SL, Digits ) > 0.0 )
                                     {
                                      Alert( "SL!" );
                                     }
                                 }                               
                                 break;
             }
         }
      }
   
   preBid = Bid;
   return (0);   
  }


Только это не полностью решает проблему - алерты будут при каждом пересечении ценой этого уровня.
Например, если она упадет до уровня СЛ, потом поднимется на пункт выше и упадет опять.

Для однозначного избавления от повторов надо записывать тикет ордера, по которому отработан сигнал, в глобальную переменную.
И сразу после выбора ордера проверять, нет ли гл. переменной с таким именем.
 
Не понял насчет глобальных переменных, хотя общую идею уловил. Имеются в виду глобальные переменные клиентского терминала или глобальные переменные объявленные на уровне программы? Можно пример как это должно выглядеть?
 
Если надо чтоб сигнал не повторялся вообще, то гл. переменные клиентского терминала.
А если один сигнал после каждого перезапуска терминала не критичен, то можно просто объявленные на гл. уровне.

Код примерно такой:
int start()
  {
  if(OrdersTotal() < 1) //Если ордеров в терминале нет, то нифига не делаем
       return(0);
 
       int total = OrdersTotal();  //Получаем количество открытых ордеров  
       for(int i = total - 1; i >= 0; i--)
         {
           if ( !OrderSelect(i, SELECT_BY_POS) ) continue;
           if ( GlobalVariableCheck( StringConcatenate( "signal_", OrderTicket() ) ) continue;
           int type = OrderType(); //Получаем тип текущего ордера
           double SL = OrderStopLoss();     // Цена на которой  находится Стоп-лосс
           switch(type)
             {
               case OP_BUY : 
                                  if ( NormalizeDouble( SL - Bid, Digits ) >= 0.0 )
                                     {
                                      Alert( "SL!" );
                                      GlobalVariableSet( StringConcatenate( "signal_", OrderTicket() ), 1 );
                                     }
                                 }                               
                                 break;
             }
         }
 
   return (0);   
  }
 

Спасибо за помощь, разобрался. :-)

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