Как отследить изменение Stop Loss?

 

Коллеги, приветствую.

Задачка есть, голову сломал. 

Мне нужно выдать окно уведомление, если пользователь изменил стоп лосс у позиции. 

Позиций может быть много и на разных символах. В окне уведомления должно отображаться тикет той позиции, у которой изменен стоп лосс и новое значение стоп лосса.

Куда копать? Какие решения?

 

TRADE_TRANSACTION_POSITION

Изменение позиции, не связанное с исполнением сделки. Данный тип транзакции свидетельствует именно о том, что позиция была изменена на стороне торгового сервера. У позиции может быть изменен объем, цена открытия, а также уровни Stop Loss и Take Profit. Информация об изменениях передается в структуре MqlTradeTransaction через обработчик OnTradeTransaction. Изменение позиции (добавление, изменение или ликвидация) в результате совершения сделки не влечет за собой появление транзакции TRADE_TRANSACTION_POSITION.

 
Alexey Viktorov:

TRADE_TRANSACTION_POSITION

Изменение позиции, не связанное с исполнением сделки. Данный тип транзакции свидетельствует именно о том, что позиция была изменена на стороне торгового сервера. У позиции может быть изменен объем, цена открытия, а также уровни Stop Loss и Take Profit. Информация об изменениях передается в структуре MqlTradeTransaction через обработчик OnTradeTransaction. Изменение позиции (добавление, изменение или ликвидация) в результате совершения сделки не влечет за собой появление транзакции TRADE_TRANSACTION_POSITION.

о, отличная тема, спасибо. Но для mql5.

Есть что-нибудь такое же для олдов, сидящих на mql4?

 
Nikita Chernyshov:

о, отличная тема, спасибо. Но для mql5.

Есть что-нибудь такое же для олдов, сидящих на mql4?

Есть. Но для моего понимания сложновато. Ум уже подсох чуток. Читайте статьи Артёма Тришкина.

 

можно насоздавать глобальных переменных в формате имя==тикет, значение=текущий стоплосс (не забывайте нормализовать!).

периодически мониторить на соответствие (и конечно же подправлять/очищать/добавлять), через SELECT_BY_TICKET легко должно быть.

 
Igor Zakharov:

можно насоздавать глобальных переменных в формате имя==тикет, значение=текущий стоплосс (не забывайте нормализовать!).

периодически мониторить на соответствие (и конечно же подправлять/очищать/добавлять), через SELECT_BY_TICKET легко должно быть.

Об этом я думал, конечно, но в таком случае можно и без глобальных в принципе обойтись. Просто позиций реально может быть много :))

переменные таки загадят терминал :)

 
Nikita Chernyshov:

Коллеги, приветствую.

Задачка есть, голову сломал. 

Мне нужно выдать окно уведомление, если пользователь изменил стоп лосс у позиции. 

Позиций может быть много и на разных символах. В окне уведомления должно отображаться тикет той позиции, у которой изменен стоп лосс и новое значение стоп лосса.

Куда копать? Какие решения?

2 цикла for(...) и 1 двухмерный массив

В первом цикле собираем в массив тикеты и SL, а во втором читаем тикеты и SL, если текущий SL не совпадает с сохранённым в массиве - Alert();

Циклы делать с очерёдностью: 1 - проверка, 2 - заполнение
 
Vitaly Muzichenko:

2 цикла for(...) и 1 двухмерный массив

В первом цикле собираем в массив тикеты и SL, а во втором читаем тикеты и SL, если текущий SL не совпадает с сохранённым в массиве - Alert();

Циклы делать с очерёдностью: 1 - проверка, 2 - заполнение

Спасибо! С двумерными массивами - как-то не получилось у меня, не хватает навыка. С одномерными провернул.

Может, кому понадобится.

// Глобальные переменные
int    mas[200];     // Массив для тикетов
double mas_2[200];   // Массив для стоп лоссов
bool flag  = true;   // Флаг для обновления массивов
int posa = 0;        // Переменная для хранения количества позиций

//------------------------------------------------------------------------------
int OnInit()
  {
   posa = OrderCount();                              // При первом запуске записать количество позиций
   
   return(INIT_SUCCEEDED);

  }
//------------------------------------------------------------------------------
void OnTick()
  {

   if(flag == true || OrderCount() != posa)          // Если был выдан Alert или изменилось количество позиций, 
     {                      
      for (int i = OrdersTotal() -1; i >=0; i--)     //  то собираем в массив новые данные о позициях и стоп лоссах
     {
       if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
       {
        mas[i]   = OrderTicket();                    // Несмотря на то, что тикеты и стоп лоссы записываются в разные массивы,
        mas_2[i] = OrderStopLoss();                  // элементы массивов соответствуют другу, а значит значение тикетов и стоп лоссов связаны номерами элементов
        posa = OrderCount();                         // Записываем текущее количество позиций в переменную posa
        flag = false;                                // Переключаем флаг, который запрещает сбор новых данных о позициях до появления Alert
       }                                             // или до изменения количества позиций
     }
    }
 
   if(flag == false)                                 // Если флаг переключен на запрет обновления данных, то переходим в цикл сравнения
    {
     for (int z = OrdersTotal() -1; z >=0; i--)
     {
       if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
       {
        if(OrderTicket() == mas[z])                 // Если тикет выбранной позиции равен тикету в массиве,
          {
           if(OrderStopLoss() != mas_2[z])          // то проверяем соответствие стоп лосса тому значению, что хранится в массиве
             {
              Alert("Изменен Stop Loss #",OrderTicket());        // Если стоп-лосс отличается, выдаем Alert
              flag = true;                                       // Включаем флаг для разрешения сбора новых данных о позициях
             }
          }
        
       }
     } 
   } 

   
  }
//+------------------------------------------------------------------+
// Счетчик позиций
//+------------------------------------------------------------------+
int OrderCount()
{
  int count = 0;
  for (int trade = OrdersTotal() -1; trade >=0; trade--)
  {
    if(OrderSelect(trade,SELECT_BY_POS,MODE_TRADES))
    {
      if(OrderType() == OP_BUY || OrderType() == OP_SELL)
      count++;
    }
  }
  return(count);
}