Select() пропустил позиции, а почему? Или: чего я не вижу?

 

Есть такой код:

void ClosePosSell()
{
   int i=1, err;
   
   for (int trade = OrdersTotal() - 1; trade >= 0; trade--)
   {
      if (OrderSelect(trade, SELECT_BY_POS, MODE_TRADES))
      if (OrderSymbol() == Symbol() && OrderType() == OP_SELL && OrderMagicNumber()==MagicNumb)
      {
         Profit+=OrderProfit() + OrderCommission() + OrderSwap();
         while (i<=5)
         {
            RefreshRates();
            if (OrderClose(OrderTicket(), OrderLots(), Ask, 3, Yellow)) break;
            else
            {
               i++;
               err = GetLastError();
               PrintErr(err);
               if (err==ERR_SERVER_BUSY   ||
                   err==ERR_NO_CONNECTION ||
                   err==ERR_MARKET_CLOSED ||
                   err==ERR_BROKER_BUSY   ||
                   err==ERR_REQUOTE       ||
                   err==ERR_TRADE_CONTEXT_BUSY)
               {
                   Sleep(i*1000);
                   Print("Попытка закрыть позиции sell - ", i);
                   continue;
               }
               break;
            }
         }
      }
   }
   
   return;
}

 В рынке имелось 5-ть позиций

фрагмент:

0 13:29:23.579 '140395': modify order #26620659 sell 0.24 EURUSD at 1.1200 sl: 0.0000 tp: 1.1199 -> sl: 0.0000 tp: 1.1182

0 13:29:23.938 '140395': order #26620659 sell 0.24 EURUSD at 1.1200 was modified -> sl: 0.0000 tp: 1.1182

0 13:29:23.985 '140395': modify order #26620268 sell 0.12 EURUSD at 1.1182 sl: 0.0000 tp: 1.1165 -> sl: 0.0000 tp: 1.1182

0 13:29:24.406 '140395': order #26620268 sell 0.12 EURUSD at 1.1182 was modified -> sl: 0.0000 tp: 1.1182

0 13:29:24.406 '140395': modify order #26620116 sell 0.06 EURUSD at 1.1157 sl: 0.0000 tp: 1.1165 -> sl: 0.0000 tp: 1.1182

0 13:29:24.625 '140395': order #26620116 sell 0.06 EURUSD at 1.1157 was modified -> sl: 0.0000 tp: 1.1182

0 13:29:24.625 '140395': modify order #26620041 sell 0.03 EURUSD at 1.1144 sl: 0.0000 tp: 1.1165 -> sl: 0.0000 tp: 1.1182

0 13:29:24.827 '140395': order #26620041 sell 0.03 EURUSD at 1.1144 was modified -> sl: 0.0000 tp: 1.1182

0 13:29:24.843 '140395': modify order #26619539 sell 0.01 EURUSD at 1.1126 sl: 0.0000 tp: 1.1165 -> sl: 0.0000 tp: 1.1182

0 13:29:25.748 '140395': order #26619539 sell 0.01 EURUSD at 1.1126 was modified -> sl: 0.0000 tp: 1.1182

0 15:41:33.671 '140395': close order #26620659 sell 0.24 EURUSD at 1.1200 sl: 0.0000 tp: 1.1182 at price 1.1236

0 15:41:34.217 '140395': order #26620659 sell 0.24 EURUSD at 1.1200 sl: 0.0000 tp: 1.1182 closed at price 1.1236

0 15:41:34.249 '140395': close order #26620268 sell 0.12 EURUSD at 1.1182 sl: 0.0000 tp: 1.1182 at price 1.1236

0 15:41:40.239 '140395': order #26620268 sell 0.12 EURUSD at 1.1182 sl: 0.0000 tp: 1.1182 closed at price 1.1236

Как видно по логу, эксперт успешно менял Тайк, но потом наступило событие - просадка превышает допустимые потери - и сработал аварийный выход, но при этом закрылись только две позиции (лоты 0.24 и 0.12).

Три позиции пропущены и никаких следов причин. 

Подскажите, где искать проблему? 


 
fromme2you:

Есть такой код:

 В рынке имелось 5-ть позиций

фрагмент:

0 13:29:23.579 '140395': modify order #26620659 sell 0.24 EURUSD at 1.1200 sl: 0.0000 tp: 1.1199 -> sl: 0.0000 tp: 1.1182

0 13:29:23.938 '140395': order #26620659 sell 0.24 EURUSD at 1.1200 was modified -> sl: 0.0000 tp: 1.1182

0 13:29:23.985 '140395': modify order #26620268 sell 0.12 EURUSD at 1.1182 sl: 0.0000 tp: 1.1165 -> sl: 0.0000 tp: 1.1182

0 13:29:24.406 '140395': order #26620268 sell 0.12 EURUSD at 1.1182 was modified -> sl: 0.0000 tp: 1.1182

0 13:29:24.406 '140395': modify order #26620116 sell 0.06 EURUSD at 1.1157 sl: 0.0000 tp: 1.1165 -> sl: 0.0000 tp: 1.1182

0 13:29:24.625 '140395': order #26620116 sell 0.06 EURUSD at 1.1157 was modified -> sl: 0.0000 tp: 1.1182

0 13:29:24.625 '140395': modify order #26620041 sell 0.03 EURUSD at 1.1144 sl: 0.0000 tp: 1.1165 -> sl: 0.0000 tp: 1.1182

0 13:29:24.827 '140395': order #26620041 sell 0.03 EURUSD at 1.1144 was modified -> sl: 0.0000 tp: 1.1182

0 13:29:24.843 '140395': modify order #26619539 sell 0.01 EURUSD at 1.1126 sl: 0.0000 tp: 1.1165 -> sl: 0.0000 tp: 1.1182

0 13:29:25.748 '140395': order #26619539 sell 0.01 EURUSD at 1.1126 was modified -> sl: 0.0000 tp: 1.1182

0 15:41:33.671 '140395': close order #26620659 sell 0.24 EURUSD at 1.1200 sl: 0.0000 tp: 1.1182 at price 1.1236

0 15:41:34.217 '140395': order #26620659 sell 0.24 EURUSD at 1.1200 sl: 0.0000 tp: 1.1182 closed at price 1.1236

0 15:41:34.249 '140395': close order #26620268 sell 0.12 EURUSD at 1.1182 sl: 0.0000 tp: 1.1182 at price 1.1236

0 15:41:40.239 '140395': order #26620268 sell 0.12 EURUSD at 1.1182 sl: 0.0000 tp: 1.1182 closed at price 1.1236

Как видно по логу, эксперт успешно менял Тайк, но потом наступило событие - просадка превышает допустимые потери - и сработал аварийный выход, но при этом закрылись только две позиции (лоты 0.24 и 0.12).

Три позиции пропущены и никаких следов причин. 

Подскажите, где искать проблему? 


Возможно, что сначала OrdersTotal() был равен 5 после закрытия одной позиции он стал меньше на 1. Поэтому и пропускает. Попробуйте сначала поместить тикет ордеров в динамический массив. Например так.

int GetOrder(int &array[])
{
   int count = 0;
   for(int i=OrdersTotal()-1; i>=0; i--)         
   {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) 
      {     
         count++;
         ArrayResize(array,count);
         array[count-1]=OrderTicket();
      }
   }
   return(count);
}

 

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

 

А где лог советника, в котором виден распечатанный error?

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

Только не надо делать дополнительных выходов из цикла, а их в коде минимум 2. 

 
Andrey Khatimlianskii:

А где лог советника, в котором виден распечатанный error?

А нет никакой ошибки в логах. из 5-ти позиций закрылись только две. Почему пропущены 3?

 Ума не приложу, потому и ищу ответа здесь.

Andrey Khatimlianskii: 

Только не надо делать дополнительных выходов из цикла, а их в коде минимум 2. 

Какие таки выходы из цикла? break - это же  выход из while, а не for!

 
fromme2you:
Какие таки выходы из цикла? break - это же  выход из while, а не for!

Да, проглядел, сорри.

Сделайте принт в каждой ветке условий и приложите лог. Чего мы будем гадать?

Более чем уверен, что посмотрев в этот лог необходимость писать сюда пропадет, вы сами найдете причину ) 

 
Andrey Khatimlianskii:

Да, проглядел, сорри.

Сделайте принт в каждой ветке условий и приложите лог. Чего мы будем гадать?

Более чем уверен, что посмотрев в этот лог необходимость писать сюда пропадет, вы сами найдете причину ) 

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

Не стоит по порядку закрывать. Функция работает (может) относительно продолжительное время.

За время работы функции ордера могут быть закрыты по стопу, по тейку, пользователем.

Могут быть закрыты другие ордера (на другом символе, мэджике) другим советником или пользователем.


зы хотя... не должно это повлиять.

Я думаю, надо после удаления ордера снова просматривать весь список до тех пор, пока свои не перестанут находиться.

 
fromme2you:
Да, я бы рад и сам видеть такой лог, да только беда случилась на реале у заказчика. Сам я "сову" в реале не гонял, только тестер и демо и то не продолжительно - меньше недели- никаких подобных проблем не было. Вот сижу у разбитого корыта и не могу понять, как такое возможно - пропустить позиции?

Тогда откуда информация, что ошибок нет? Заказчик показал лог советника?

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

 

Тут все просто, вы не все ошибки обрабатываете, и по остальным просто выходите из цикла, отсюда и пропуск (это причина раз)

Плюс вы забываете сбрасывать количество попыток при переходе к следующему ордеру, и когда количество попыток заканчивается, дальше закрытия уже не происходят (это причина два)

Таймауты отрабатываете не следуя рекомендациям Метаквотов, рост задержки после каждой попытки это так и задумано?

Также после столь больших таймаутов я бы сделал RefreshRates, одному богу известно, обновляется ли предопределенная переменная Ask внутри тика

Проверка потока (коннект, поток, рынок) надо делать перед торговыми операциями, поскольку ответ может быть не корректен (это тоже есть в рекомендациях)

Надо также проверять уровень заморозки (Freeze) и обрабатывать ошибку - "нет ошибки, но результат не известен" (случается у некоторых брокеров) 

В любом случае, на следующем тике, не мешает перепроверить исполнение команды, путем запроса ордеров в рынке 

Предпочтительнее другой подход выполнения и контроля операций растянутых во времени:

- делаем предварительную проверку исполнимости команды 

- даем все необходимые команды

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

- в конце тика отрабатываем таймаут

- на следующем тике проверяем реальное исполнение, при необходимости повторяем 

 
Aleksei Radchenko:

Тут все просто, вы не все ошибки обрабатываете, и по остальным просто выходите из цикла, отсюда и пропуск (это причина раз)


Вот так просто - я только про первую строчку догадывался, и то, посмотрел какие гиганты(по рейтингам, датам регистрации) пишут - даже не стал заикаться=)
 
Andrey Khatimlianskii:

Тогда откуда информация, что ошибок нет? Заказчик показал лог советника?

Я в первом посте привел фрагмент такого лога, показывая, что модификация позиций выполнялась успешно для всех 5-ти позиций, а затем закрылись только две позиции из 5-ти. Между закрытиями позиций 6 сек, что указывает на какие-то задержки, если сравнивать время между модификациями позиций.
Причина обращения: