Почему цикл пропускает итерацию?

 

Задача закрывать первых два ордера в серии.

Ордера по очередности разно-направленные SELL-BUY-SELL-BUY-SELL-BUY и т.д.

Написал функцию, но в тестере в первый раз закрываются ордера через один 1 и 3 оба SELL

В следующий раз закрывается 2 и 5 BUY и SELL соответсвенно.

Подскажите пожалуйста, что не так с функцией:

//+------------------------------------------------------------------+
void CloseNOrders()
{
   int closed = 0, i = 0;
   
   while (closed < OrdersToClose)
   {
      if (OrderSelect(i,SELECT_BY_POS)) 
      {
         if (OrderMagicNumber() == Magic && OrderSymbol() == Symbol())
         {
            if (OrderType() == OP_BUY)
            {
               if(OrderClose(OrderTicket(), OrderLots(), Bid, slippage)) closed++;
               else     printf("Error Order BUY Close", GetLastError());
            }
            
            if (OrderType() == OP_SELL)
            {
               if(OrderClose(OrderTicket(), OrderLots(), Ask, slippage)) closed++;
               else printf("Error Order SELL Close", GetLastError());           
            }
         }
      }
   i++; 
   RefreshRates();   
   }
}
//+------------------------------------------------------------------+
 
Roman Meskhidze:

Задача закрывать первых два ордера в серии.

Ордера по очередности разно-направленные SELL-BUY-SELL-BUY-SELL-BUY и т.д.

Написал функцию, но в тестере в первый раз закрываются ордера через один 1 и 3 оба SELL

В следующий раз закрывается 2 и 5 BUY и SELL соответсвенно.

Подскажите пожалуйста, что не так с функцией:

Допустим есть ордера X, Y, Z

Когда вы закрываете первый ордер (X), то в терминале остаются ордера Y, Z

На следующем круге цикла вы закрываете второй ордер, это ордер Z. В терминале остается ордер Y.

На следующем круге вы пытаетесь выбрать ордер c индексом 2, но такого ордера нет.


Чтобы работало стабильно или делайте обход в обратном направлении, начав с i = OrdersToClose - 1

Или в одном цикле считайте тикеты ордеров в массив, а во втором цикле выбирайте и закрывайте ордера по тикетам из массива.

 
Ilya Baranov:

Допустим есть ордера X, Y, Z

Когда вы закрываете первый ордер (X), то в терминале остаются ордера Y, Z

На следующем круге цикла вы закрываете второй ордер, это ордер Z. В терминале остается ордер Y.

На следующем круге вы пытаетесь выбрать ордер c индексом 2, но такого ордера нет.

Точно, спасибо большое.

Как же решить задачу. Есть идеи?

 

Подумал находить первый ордер и дальше закрывать плюсуя к первому +1 +2 сколько надо закрыть ордеров.

Но подумал, что если в терминале не один советник то в мои ордера могу в серединку вписаться другие ордера (((

 
Roman Meskhidze:

Подумал находить первый ордер и дальше закрывать плюсуя к первому +1 +2 сколько надо закрыть ордеров.

Но подумал, что если в терминале не один советник то в мои ордера могу в серединку вписаться другие ордера (((

найти по тикету магику и символу эти два ордера и закрывать их оба за один проход по номеру тикета - на простом языке прогоняете выборку в цикле с фильтрами по магику и символу и какой-либо временной переменной присваивате первый же тикет если она равна нулю, далее на следующем проходе цикла сравниваете эту переменную со следующим тикетом, если он оказался меньше текущего то пересваиваете его в переменную итд, в конце за пределами цикла по найденным тикетам закрываете ордера с флагом SELECT_BY_TICKET

 
Roman Meskhidze:

Точно, спасибо большое.

Как же решить задачу. Есть идеи?

OrderSelect(0,SELECT_BY_POS)
 
Roman Meskhidze:

Точно, спасибо большое.

Как же решить задачу. Есть идеи?

Царь бурлит от затей(идей)

Ну, а Федька потей.

Вот ещё одно решение.

//+------------------------------------------------------------------+
void CloseNOrders()
{
   int closed = 0, i = 0;
   
   while (closed < OrdersToClose)
   {
      if (OrderSelect(i,SELECT_BY_POS)) 
      {
         if (OrderMagicNumber() == Magic && OrderSymbol() == Symbol())
         {
            if (OrderType() == OP_BUY)
            {
               if(OrderClose(OrderTicket(), OrderLots(), Bid, slippage))
                {
                 closed++;
                 i--;
                }
               else     printf("Error Order BUY Close", GetLastError());
            }
            
            if (OrderType() == OP_SELL)
            {
               if(OrderClose(OrderTicket(), OrderLots(), Ask, slippage))
                {
                 closed++;
                 i--;
                }
               else printf("Error Order SELL Close", GetLastError());           
            }
         }
      }
   i++; 
   RefreshRates();   
   }
}
//+------------------------------------------------------------------+
 

я вот так решил

//+------------------------------------------------------------------+
void CloseNOrders()
{
   int tickets[];
   
   ArrayResize(tickets, OrdersToClose);
   
   for (int i = 0; i <= OrdersTotal()-1; i++)
   {
      if (i == OrdersToClose) break;
      
      if (OrderSelect(i,SELECT_BY_POS)) 
      {
         if (OrderMagicNumber() == Magic && OrderSymbol() == Symbol())
         {
            tickets[i] = OrderTicket();
         }
      }
   }
         
   for (int i = 0; i <= OrdersToClose - 1; i++)
   {
      if (OrderSelect(tickets[i],SELECT_BY_TICKET))  
      {
         if (OrderType() == OP_BUY)
         {
            if(!OrderClose(OrderTicket(), OrderLots(), Bid, slippage)) 
            printf("Error Order BUY Close", GetLastError());
         }
               
         if (OrderType() == OP_SELL)
         {
            if(!OrderClose(OrderTicket(), OrderLots(), Ask, slippage)) 
            printf("Error Order SELL Close", GetLastError());           
         }
      }
   }   
}
//+------------------------------------------------------------------+
 

НУ вам же написали суть проблемы. Есть 3 ордера. Закрываем первый по списку, строка с ордером исчезает, остается 2, цикл переходит на 2-ю строчку с ордером а это уже -3 ий ордер. Чтоб этого не было Начинаем перебирать цикл с конца. 

for (int i = OrdersTotal()-1; i>=0;i--) 

{  Закрытие ордера } 

В такой конструкции начинается отсчет с последней строчки. Закрывается ордер, строчек становится на 1 меньше, происходит итерация цикла на строчку вверх и опять на тыкаемся на последний ордер в списке. И не надо запоминать тикеты и пр. танцы с бубном. 

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