Любые вопросы от ПРОФИ к СУПЕРПРОФИ - 1. - страница 46

 

Здравствуйте, уважаемые знатоки...

У меня есть робот на MT5, который работает сессиями с пачками рыночных позиций.
В очередном апдейте я хочу его научить, чтобы он учитывал историю закрытых сделок не только непосредственно закрытых им самим (по Magic_ID), но и закрытых вручную (при условии, что робот их открывал).
Общая блок схема:
1. При изменении истории сделок робот собирает первичную информацию по сделкам закрытия (DEAL_ENTRY_OUT) с начала своей сессии.
2. С помощью DEAL_POSITION_ID получаем тикет открывающей сделки.
3. С помощью DEAL_MAGIC получаем Magic_ID открывающей сделки
4. Если Magic_ID открывающей позиции равен заданному в настройках, то считаем закрывающую сделку нашей и фиксируем сведения о ней.
5. Отрисовываем метки открытия и закрытия позиции и линию жизни позиции. (Это удобно, когда на одной паре стоит несколько роботов, чтобы графически видеть нужную часть истории). 

По этой блок-схеме я сделал инклюд. На тестере работает как задумано. В журнал пишет:
Журнал на тестете

Но на реале как надо не работает. Путем последовательно исключения выяснил, что DEAL_MAGIC не считывает у сделки открытия.
И условие if(deal_id_in != id_Orders){continue;}   // если ID входящей сделки не наш, выбираем следующий ордер  //  (строка 94) дальше не пускает
Журнал на реале.

Прошу вас указать в чем причина и как её победить? 
Код инклюда прилагаю.

//+------------------------------------------------------------------+
//|                                                  DataHistory.mqh |
//|                                                            Ваш % |
//|                                                vashprocent@bk.ru |
//+------------------------------------------------------------------+
#property strict

  int      HistoryCountOrders;     //последнее известное количество ордеров в истории 
  double   BalanceHistory,         //баланс В $ по закрытым ордерам  
           LotsHistory;            //объем лота по всем закрытым ордерам с начала сессии

//=================================================================================================
struct HistoryOrders        // структура массива с данными по истории ордеров
{
   int               Deal_type_out[];              // тип сделки закрытия 
   datetime          Close_time[];                 // время закрытия позиции 
   double            Close_price[];                // цена закрытия позиции
   double            Close_lot[];                  // лот закрытия
   ulong             Deal_ticket_out[];            // тикет сделки закрытия
   long              ID_deal_out[];                // ID сделки закрытия (если 0 - значит вручную)
   
   int               Deal_type_in[];               // тип сделки открытия 
   datetime          Open_time[];                  // время открытия позиции
   double            Open_price[];                 // цена открытия
   double            Open_lot[];                   // лот открытия
   ulong             Deal_ticket_in[];             // тикет сделки открытия
   long              ID_deal_in[];                 // ID сделки открытия
 
}; HistoryOrders ActualHistoryOrders;
// ActualHistoryOrders.Deal_type_out[1]=

//+------------------------------------------------------------------+
//| Обработка ордеров в истории сессии                               |
//+------------------------------------------------------------------+
void DataHistory(datetime startTimeSessin, int id_Orders)
{
   int   totalPos;                           // кол-во закрытыхпозиций за время сессии
   
      if(!HistorySelect(startTimeSessin, TimeCurrent())){    // запрашиваем историю сделок с начала сессии до настоящего момента
         Print("HistorySelect() failed. Error ", GetLastError());
         return;
      }
      totalPos=HistoryDealsTotal();                                           // запоминаем текущее количество ордеров в истории
      Print("DataHistory: Кол-во сделок в истории сессии ",totalPos);
      
      BalanceHistory=0;                                                       // обнуляем баланс по закрытым позициям
      LotsHistory=0;                                                          // обнуляем сумму лотов по всем закрытым позициям с начала сессии
      HistoryCountOrders=0;                                                   // кол-во закрытых позиций за это время  
      ArrayResize(ActualHistoryOrders.Deal_type_out,  totalPos, 1);           // задаем изначальные размеры массивов истории сделок
      ArrayResize(ActualHistoryOrders.Close_time,     totalPos, 1);
      ArrayResize(ActualHistoryOrders.Close_price,    totalPos, 1);
      ArrayResize(ActualHistoryOrders.Close_lot,      totalPos, 1);                 
      ArrayResize(ActualHistoryOrders.Deal_ticket_out,totalPos, 1);
      ArrayResize(ActualHistoryOrders.ID_deal_out,    totalPos, 1);      
      ArrayResize(ActualHistoryOrders.Deal_type_in,   totalPos, 1);
      ArrayResize(ActualHistoryOrders.Open_time,      totalPos, 1);
      ArrayResize(ActualHistoryOrders.Open_price,     totalPos, 1);
      ArrayResize(ActualHistoryOrders.Open_lot,       totalPos, 1);      
      ArrayResize(ActualHistoryOrders.Deal_ticket_in, totalPos, 1);
      ArrayResize(ActualHistoryOrders.ID_deal_in,     totalPos, 1);
                                    
      ArrayInitialize(ActualHistoryOrders.Deal_type_out, -1);                 // обнуляем данные по типам сделок закрытия
      ArrayInitialize(ActualHistoryOrders.Close_time,    -1);
      ArrayInitialize(ActualHistoryOrders.Close_price,   -1);
      ArrayInitialize(ActualHistoryOrders.Close_lot,     -1);
      ArrayInitialize(ActualHistoryOrders.Deal_ticket_out,-1);
      ArrayInitialize(ActualHistoryOrders.ID_deal_out,   -1);
      ArrayInitialize(ActualHistoryOrders.Deal_type_in,  -1);
      ArrayInitialize(ActualHistoryOrders.Open_time,     -1);
      ArrayInitialize(ActualHistoryOrders.Open_price,    -1);
      ArrayInitialize(ActualHistoryOrders.Open_lot,      -1);
      ArrayInitialize(ActualHistoryOrders.Deal_ticket_in,-1);
      ArrayInitialize(ActualHistoryOrders.ID_deal_in,    -1);      
       

    //--- СКАНИРУЕМ ИСТОРИЮ СДЕЛОК ---       
      for(int i=0; i<totalPos; i++){                                                      // перебираем все закрытые позиции
         ulong deal_ticket = HistoryDealGetTicket(i);                                     // фиксируем тикет сделки
         //Print("DataHistory: deal_ticket=",deal_ticket);
         if(deal_ticket==0) continue;                                                     // если тикет нулевой, то пропускаем этот ордер
         if(HistoryDealGetString(deal_ticket,DEAL_SYMBOL) !=_Symbol){continue;}           // если символ не наш, выбираем следующий ордер       
         //Print("DataHistory: _Symbol=",_Symbol);         
         long deal_type = HistoryDealGetInteger(deal_ticket, DEAL_TYPE);                  // считываем тип сделки          
         if(!(deal_type==DEAL_TYPE_BUY || deal_type==DEAL_TYPE_SELL)){continue;}          // если сделка была НЕ рыночный BUY или SELL, то пропускаем этот ордер
         //Print("DataHistory: deal_type=",deal_type);           
         //Print("DataHistory: deal_entry=",HistoryDealGetInteger(deal_ticket,DEAL_ENTRY)); 
         if(HistoryDealGetInteger(deal_ticket,DEAL_ENTRY)==DEAL_ENTRY_OUT)                // если направление сделки - это выход из рынка
         {  
            //Print("DataHistory: deal_entry=",HistoryDealGetInteger(deal_ticket,DEAL_ENTRY)); 
            ulong deal_ticket_in = HistoryDealGetInteger(deal_ticket, DEAL_POSITION_ID);    // получаем тикет cделки открытия    
            int deal_id_in = (int)HistoryDealGetInteger(deal_ticket_in,DEAL_MAGIC);             // получаем ID cделки открытия 
            Print("DataHistory: deal_ticket_out=",(string)deal_ticket," deal_type_out=",(string)deal_type," deal_ticket_in=",(string)deal_ticket_in," deal_id_in=",(string)deal_id_in);            

            if(deal_id_in != id_Orders){continue;}                                          // если ID входящей сделки не наш, выбираем следующий ордер            
            long deal_id_out = HistoryDealGetInteger(deal_ticket_in, DEAL_MAGIC);                    // получаем ID cделки закрытия               
            //Print("DataHistory: deal_ticket=",(string)deal_ticket," deal_type=",(string)deal_type," deal_ticket_in=",deal_ticket_in," deal_id_in=",deal_id_in," deal_id_out=",deal_id_out);
            {
               HistoryCountOrders++;                                                      // число наших закрытых позиций
               
             //--- собираем сведения о каждой закрытой сделке ---
               ActualHistoryOrders.Deal_ticket_out [HistoryCountOrders-1]=(ulong)deal_ticket;                                                               // фиксируем тикет сделки закрытия
               ActualHistoryOrders.Deal_type_out   [HistoryCountOrders-1]=(int)deal_type;                                                                   // тип сделки закрытия 
               ActualHistoryOrders.Close_time      [HistoryCountOrders-1]=(datetime)HistoryDealGetInteger(deal_ticket,DEAL_TIME);                           // время сделки закрытия 
               ActualHistoryOrders.Close_price     [HistoryCountOrders-1]=(double)NormalizeDouble(HistoryDealGetDouble(deal_ticket,DEAL_PRICE),_Digits);    // цена сделки закрытия 
               ActualHistoryOrders.Close_lot       [HistoryCountOrders-1]=(double)NormalizeDouble(HistoryDealGetDouble(deal_ticket,DEAL_VOLUME),2);         // лот сделки закрытия
               ActualHistoryOrders.ID_deal_out     [HistoryCountOrders-1]=(int)deal_id_out;                                                                 // id сделки закрытия               
               
               ActualHistoryOrders.Deal_ticket_in  [HistoryCountOrders-1]=(ulong)deal_ticket_in;                                                            // тикет сделки открытия  
               ActualHistoryOrders.Deal_type_in    [HistoryCountOrders-1]=(int)(deal_type==DEAL_TYPE_SELL? 0 : 1);                                          // тип сделки открытия 
               ActualHistoryOrders.Open_time       [HistoryCountOrders-1]=(datetime)HistoryDealGetInteger(deal_ticket_in,DEAL_TIME);                        // время открытия позиции
               ActualHistoryOrders.Open_price      [HistoryCountOrders-1]=(double)NormalizeDouble(HistoryDealGetDouble(deal_ticket_in,DEAL_PRICE),_Digits); // цена открытия
               ActualHistoryOrders.Open_lot        [HistoryCountOrders-1]=(double)NormalizeDouble(HistoryDealGetDouble(deal_ticket_in,DEAL_VOLUME),2);      // лот открытия
               ActualHistoryOrders.ID_deal_in      [HistoryCountOrders-1]=(int)deal_id_in;                                                                  // id сделки открытия
            }
         }  // конец условия if(HistoryDealGetInteger(deal_ticket,DEAL_ENTRY)==DEAL_ENTRY_OUT)
      }     // конец цикла for(int hi=total; hi>=0; hi--){ //перебираем все закрытые ордера
    //----------        
      if(HistoryCountOrders>0){                                                            // если есть закрытые сделки в истории
         ArrayResize(ActualHistoryOrders.Deal_type_out,  HistoryCountOrders, 1);           // задаем новые размеры массивов истории сделок
         ArrayResize(ActualHistoryOrders.Close_time,     HistoryCountOrders, 1);
         ArrayResize(ActualHistoryOrders.Close_price,    HistoryCountOrders, 1);
         ArrayResize(ActualHistoryOrders.Close_lot,      HistoryCountOrders, 1);                 
         ArrayResize(ActualHistoryOrders.Deal_ticket_out,HistoryCountOrders, 1);
         ArrayResize(ActualHistoryOrders.ID_deal_out,    HistoryCountOrders, 1);        
         ArrayResize(ActualHistoryOrders.Deal_type_in,   HistoryCountOrders, 1);
         ArrayResize(ActualHistoryOrders.Open_time,      HistoryCountOrders, 1);
         ArrayResize(ActualHistoryOrders.Open_price,     HistoryCountOrders, 1);
         ArrayResize(ActualHistoryOrders.Open_lot,       HistoryCountOrders, 1);      
         ArrayResize(ActualHistoryOrders.Deal_ticket_in, HistoryCountOrders, 1);
         ArrayResize(ActualHistoryOrders.ID_deal_in,     HistoryCountOrders, 1);        
         
         for(int hi=0; hi<HistoryCountOrders; hi++){                                                              // перебираем все наши закрытые позиции
            LotsHistory+=NormalizeDouble(ActualHistoryOrders.Close_lot[hi],2);                                    // подсчитываем общий объем лота закрытых ордеров
            BalanceHistory+= HistoryDealGetDouble(ActualHistoryOrders.Deal_ticket_out[hi],DEAL_PROFIT)            // подсчет баланса по закрытым ордерам с начала сессии
                            +HistoryDealGetDouble(ActualHistoryOrders.Deal_ticket_out[hi],DEAL_COMMISSION)*2      // предполагается, что если брокер берет комиссию, 
                            +HistoryDealGetDouble(ActualHistoryOrders.Deal_ticket_out[hi],DEAL_SWAP);             // то он делит её пополам (за открытие и за закрытие сделки)              
          
            Print("DataHistory: Deal_ticket_out=",(string)ActualHistoryOrders.Deal_ticket_out[hi],", Deal_type_out=",(string)ActualHistoryOrders.Deal_type_out[hi],", ID_deal_out=",ActualHistoryOrders.ID_deal_out[hi],
                             ", Deal_ticket_in =",(string)ActualHistoryOrders.Deal_ticket_in[hi], ", Deal_type_in =",(string)ActualHistoryOrders.Deal_type_in[hi], ", ID_deal_in =",ActualHistoryOrders.ID_deal_in[hi] );
          
          //--- рисуем знак открытия, если его нет
          //ObjectOrderSend(deal_type_in,                         op_lot,                           op_price,                           deal_ticket_in);                             
 // закоментировал, потому что это в другом инклюде          ObjectOrderSend(ActualHistoryOrders.Deal_type_in[hi], ActualHistoryOrders.Open_lot[hi], ActualHistoryOrders.Open_price[hi], ActualHistoryOrders.Deal_ticket_in[hi]);   
          
          //--- рисуем знак закрытия и линию жизни позиции 
          //ObjectOrderDelete(int in_type,                          ulong in_ticket,                        double in_price,                    datetime in_time,                  double out_price,                    datetime out_time                 )         
 //  закоментировал, потому что это в другом инклюде          ObjectOrderDelete(ActualHistoryOrders.Deal_type_in[hi], ActualHistoryOrders.Deal_ticket_in[hi], ActualHistoryOrders.Open_price[hi], ActualHistoryOrders.Open_time[hi], ActualHistoryOrders.Close_price[hi], ActualHistoryOrders.Close_time[hi]);
                  
         }
     //----------
      //int index_open_time=ArrayMinimum(ActualHistoryOrders.Open_time,0);                                                 // смотрим индекс ячейки с самым ранним временем открытия позиции       
      //if(MathAbs((int)GlobalVariableGet(StartTimeSessin)-(int)ActualHistoryOrders.Open_time[index_open_time])>=1)        // если время в ГП StartTimeSessin отличается от времени из истории на 1сек и более
      //{  
      //   Print("DataHistory: Время начала сессии скорректировано по историческим данным с "+(string)((datetime)GlobalVariableGet(StartTimeSessin))+" на "+(string)(ActualHistoryOrders.Open_time[index_open_time]-1)); 
      //   GlobalVariableSet(StartTimeSessin, (double)(ActualHistoryOrders.Open_time[index_open_time]-1));                                     // корректируем время начала сессии по историческим данным      
      //}
      Print("DataHistory: Кол-во закрытых сделок в истории сессии HistoryCountOrders = ",HistoryCountOrders,". BalanceHistory = ",DoubleToString(BalanceHistory,2),". LotsHistory = ",DoubleToString(LotsHistory,2));
   }
}
//======================================================================== 
Файлы:
DataHistory.mqh  29 kb
 
Oleg Shangin #:

Здравствуйте, уважаемые знатоки...

У меня есть робот на MT5, который работает сессиями с пачками рыночных позиций.
В очередном апдейте я хочу его научить, чтобы он учитывал историю закрытых сделок не только непосредственно закрытых им самим (по Magic_ID), но и закрытых вручную (при условии, что робот их открывал).
Общая блок схема:
1. При изменении истории сделок робот собирает первичную информацию по сделкам закрытия (DEAL_ENTRY_OUT) с начала своей сессии.
2. С помощью DEAL_POSITION_ID получаем тикет открывающей сделки.
3. С помощью DEAL_MAGIC получаем Magic_ID открывающей сделки
4. Если Magic_ID открывающей позиции равен заданному в настройках, то считаем закрывающую сделку нашей и фиксируем сведения о ней.
5. Отрисовываем метки открытия и закрытия позиции и линию жизни позиции. (Это удобно, когда на одной паре стоит несколько роботов, чтобы графически видеть нужную часть истории). 

По этой блок-схеме я сделал инклюд. На тестере работает как задумано. В журнал пишет:

Но на реале как надо не работает. Путем последовательно исключения выяснил, что DEAL_MAGIC не считывает у сделки открытия.
И условие if(deal_id_in != id_Orders){continue;}   // если ID входящей сделки не наш, выбираем следующий ордер  //  (строка 94) дальше не пускает


Прошу вас указать в чем причина и как её победить? 
Код инклюда прилагаю.

На беглый взгляд, первый и второй логи выводятся _разными_ кодами.

И приведённому коду соответствует только первый лог, а второй выводится каким-то другим кодом.

 
JRandomTrader #:

На беглый взгляд, первый и второй логи выводятся _разными_ кодами.

И приведённому коду соответствует только первый лог, а второй выводится каким-то другим кодом.

Код тот же. 
Но поскольку на реале до конечного лога не добираемся, то я раскоментил строку 92, чтобы было видно докуда доходим.
  

 
Oleg Shangin #:

Здравствуйте, уважаемые знатоки...

У меня есть робот на MT5, который работает сессиями с пачками рыночных позиций.
В очередном апдейте я хочу его научить, чтобы он учитывал историю закрытых сделок не только непосредственно закрытых им самим (по Magic_ID), но и закрытых вручную (при условии, что робот их открывал).
Общая блок схема:
1. При изменении истории сделок робот собирает первичную информацию по сделкам закрытия (DEAL_ENTRY_OUT) с начала своей сессии.
2. С помощью DEAL_POSITION_ID получаем тикет открывающей сделки.
3. С помощью DEAL_MAGIC получаем Magic_ID открывающей сделки
4. Если Magic_ID открывающей позиции равен заданному в настройках, то считаем закрывающую сделку нашей и фиксируем сведения о ней.
5. Отрисовываем метки открытия и закрытия позиции и линию жизни позиции. (Это удобно, когда на одной паре стоит несколько роботов, чтобы графически видеть нужную часть истории). 

По этой блок-схеме я сделал инклюд. На тестере работает как задумано. В журнал пишет:

Но на реале как надо не работает. Путем последовательно исключения выяснил, что DEAL_MAGIC не считывает у сделки открытия.
И условие if(deal_id_in != id_Orders){continue;}   // если ID входящей сделки не наш, выбираем следующий ордер  //  (строка 94) дальше не пускает


Прошу вас указать в чем причина и как её победить? 
Код инклюда прилагаю. 

Так и думал, что никто ничего путёвого не подскажет. Видимо баг MQL5. Как иначе обьяснить, что на тестере (с визуалом и без) работает как надо, а на реале - нет.

 
Oleg Shangin #:

Так и думал, что никто ничего путёвого не подскажет. Видимо баг MQL5. Как иначе обьяснить, что на тестере (с визуалом и без) работает как надо, а на реале - нет.

Я пытался разобраться в вашем коде, но написано так, что мой мозг не воспринимает этого.

Вы зря не пользуетесь функцией OnTradeTransaction. Это избавило бы вас от перебора всех позиций. 

И вот это

Print("DataHistory: Deal_ticket_out=",(string)ActualHistoryOrders.Deal_ticket_out[hi],", Deal_type_out=",(string)ActualHistoryOrders.Deal_type_out[hi],", ID_deal_out=",ActualHistoryOrders.ID_deal_out[hi],
                 ", Deal_ticket_in =",(string)ActualHistoryOrders.Deal_ticket_in[hi], ", Deal_type_in =",(string)ActualHistoryOrders.Deal_type_in[hi], ", ID_deal_in =",ActualHistoryOrders.ID_deal_in[hi] );
          

почему на втором снимке написано подругому? Наверное печатает из другого места кода.

 
Alexey Viktorov #:

Я пытался разобраться в вашем коде, но написано так, что мой мозг не воспринимает этого.

Вы зря не пользуетесь функцией OnTradeTransaction. Это избавило бы вас от перебора всех позиций. 

И вот это

почему на втором снимке написано подругому? Наверное печатает из другого места кода.

Здравствуйте. ))) Спасибо за проявленный интерес.
Я уже писал выше, что поскольку на реале до конечного лога не добираемся, то я раскоментил строку 92, чтобы было видно докуда доходим и почему дальше не проходим: условие по DEAL_MAGIC не выполняется в строке 94.
И вопрос в том, почему это работает на тестере (в том числе с визуализацией), а на реале идет затык. Ведь такого не должно быть.
HistoryDealGetInteger(deal_ticket_in,DEAL_MAGIC);             // получаем ID cделки открытия 

Перефразирую вопрос. Как вы думаете, почему эта строка на визуальном тестере выдает Magic, а на реале выдает 0 ?
Вероятно "ларчик то просто открывается", и я упускаю какую-то мелочь. Ну или это всё-таки баг MQL5? Что думаете - СУПЕРПРОФИ ?

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

 
Oleg Shangin #:
Здравствуйте. ))) Спасибо за проявленный интерес.
Я уже писал выше, что поскольку на реале до конечного лога не добираемся, то я раскоментил строку 92, чтобы было видно докуда доходим и почему дальше не проходим: условие по DEAL_MAGIC не выполняется в строке 94.
И вопрос в том, почему это работает на тестере (в том числе с визуализацией), а на реале идет затык. Ведь такого не должно быть.

Перефразирую вопрос. Как вы думаете, почему эта строка на визуальном тестере выдает Magic, а на реале выдает 0 ?
Вероятно "ларчик то просто открывается", и я упускаю какую-то мелочь. Ну или это всё-таки баг MQL5? Что думаете - СУПЕРПРОФИ ?

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

В тестере всё совсем не так как в реале.

Вот эта строка

            ulong deal_ticket_in = HistoryDealGetInteger(deal_ticket, DEAL_POSITION_ID);    // получаем тикет cделки открытия  

почему вы решили, что это тикет сделки?

Внимательно прочтите что такое DEAL_POSITION_ID и как выбрать ордера и сделки относящиеся к одной позиции.

Oleg Shangin #:


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

Да, это будет другой код. И будет гораздо проще. Посмотрите структуры функции

void OnTradeTransaction(const MqlTradeTransaction& trans,
                        const MqlTradeRequest& request,
                        const MqlTradeResult& result)
struct MqlTradeTransaction 
  { 
   ulong                         deal;             // Тикет сделки 
   ulong                         order;            // Тикет ордера 
   string                        symbol;           // Имя торгового инструмента 
   ENUM_TRADE_TRANSACTION_TYPE   type;             // Тип торговой транзакции 
   ENUM_ORDER_TYPE               order_type;       // Тип ордера 
   ENUM_ORDER_STATE              order_state;      // Состояние ордера 
   ENUM_DEAL_TYPE                deal_type;        // Тип сделки 
   ENUM_ORDER_TYPE_TIME          time_type;        // Тип ордера по времени действия 
   datetime                      time_expiration;  // Срок истечения ордера 
   double                        price;            // Цена  
   double                        price_trigger;    // Цена срабатывания стоп-лимитного ордера 
   double                        price_sl;         // Уровень Stop Loss 
   double                        price_tp;         // Уровень Take Profit 
   double                        volume;           // Объем в лотах 
   ulong                         position;         // Тикет позиции 
   ulong                         position_by;      // Тикет встречной позиции 
  };

Вам не придётся на каждом тике проверять не изменилась ли история. Вы сразу получаете событие, проверяете что это и код выполняется в определённом направлении.

Но дело ваше, не нравится, не ешьте…😊

 
Alexey Viktorov #:
В тестере всё совсем не так как в реале.

Вы общими расхожими фразами выражаетесь вместо конкретики. Определенные различия между тестером и реалом в MQL5 конечно есть. Они описаны. Но в данном случае, в чем именно разница на реале и визуале в обработке этой строки?

ulong deal_ticket_in = HistoryDealGetInteger(deal_ticket, DEAL_POSITION_ID);    // получаем тикет cделки открытия  
Alexey Viktorov #:
почему вы решили, что это тикет сделки?

Потому что так написано в мануале.

DEAL_POSITION_ID

Идентификатор позиции, в открытии, изменении или закрытии которой участвовала эта сделка. Каждая позиция имеет уникальный идентификатор, который присваивается всем сделкам, совершенным на инструменте в течение всей жизни позиции. 

"Идентификатор позиции - это уникальное число, которое присваивается каждой вновь открытой позиции и не изменяется в течение всей ее жизни. Соответствует тикету ордера, которым была открыта позиция."
Значит тикет сделки открытия рыночной позиции это и будет для всех остальных ордеров идентификатором позиции (т.е. DEAL_POSITION_ID). Тестер с визуализацией это подтверждают. 

 

Alexey Viktorov #:
Вам не придётся на каждом тике проверять не изменилась ли история.

И тут тоже вы не угадали. Разве я не понимаю?))) Запрос истории у меня идет не на каждом тике. И даже не по времени вообще, а при изменении суммарного обьема лотов по инструменту.

 
Oleg Shangin #:


Потому что так написано в мануале.

DEAL_POSITION_ID

Идентификатор позиции, в открытии, изменении или закрытии которой участвовала эта сделка. Каждая позиция имеет уникальный идентификатор, который присваивается всем сделкам, совершенным на инструменте в течение всей жизни позиции. 

"Идентификатор позиции - это уникальное число, которое присваивается каждой вновь открытой позиции и не изменяется в течение всей ее жизни. Соответствует тикету ордера, которым была открыта позиция."

POSITION_TICKET

Тикет позиции. Уникальное число, которое присваивается каждой вновь открытой позиции. Как правило, соответствует тикету ордера, в результате которого она была открыта, за исключением случаев изменения тикета в результате служебных операций на сервере. Например, начисления свопов переоткрытием позиции. Для нахождения ордера, которым была открыта позиция, следует использовать свойство POSITION_IDENTIFIER.
 

Значение POSITION_TICKET соответствует MqlTradeRequest::position.

long

POSITION_IDENTIFIER

Идентификатор позиции - это уникальное число, которое присваивается каждой вновь открытой позиции и не изменяется в течение всей ее жизни. Соответствует тикету ордера, которым была открыта позиция.

 

Идентификатор позиции указывается в каждом ордере (ORDER_POSITION_ID) и сделке (DEAL_POSITION_ID), которая ее открыла, изменила или закрыла. Используйте это свойство для поиска ордеров и сделок, связанных с позицией.

 

При развороте позиции в режиме неттинга (единой сделкой in/out) идентификатор позиции POSITION_IDENTIFIER не изменяется. Однако при этом POSITION_TICKET изменяется на тикет ордера, в результате которого произошел разворот. В режиме хеджинга разворот позиции не предусмотрен.

long


Вот разница между тикетом позиции и идентификатором позиции.

Когда-то в этом описании была оговорка «…как правило соответствует тикету ордера…»

А в тестере это просто совпадение. Случайное попадание в цель…

Документация по MQL5: Константы, перечисления и структуры / Структуры данных / Структура торгового запроса
Документация по MQL5: Константы, перечисления и структуры / Структуры данных / Структура торгового запроса
  • www.mql5.com
Взаимодействие клиентского терминала и торгового сервера для проведения операций постановки ордеров производится посредством торговых запросов...
 
Посмотрите ещё этот раздел документации.
Документация по MQL5: Торговые функции / HistorySelectByPosition
Документация по MQL5: Торговые функции / HistorySelectByPosition
  • www.mql5.com
Запрашивает историю сделок и ордеров, имеющих указанный идентификатор позиции. Параметры position_id [in]  Идентификатор позиции, который...