Обработка ошибок.

 

В этой теме предлагаю делиться мыслями и кодами по обработке разных ошибок. Сейчас меня интересует как правильно обработать ошибку №128 ERR_TRADE_TIMEOUT (Истек срок ожидания совершения сделки).

Подскажите, кто знает.

 

Сами разработчики, на мой взгляд, дают вполне конкретные рекомендации. Цитирую:

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

Организовать минутную и более паузу - не вопрос! Немного посложнее с проверкой, а не открылась ли позиция, но тоже решаемо. Я уже тут где-то выкладывал свою функцию для открытия позиций с обработкой ошибок. Тема, вроде бы, касалась реквот. Поищите. Если не найдёте, выложу снова.

 
KimIV:

Сами разработчики, на мой взгляд, дают вполне конкретные рекомендации. Цитирую:

....

Организовать минутную и более паузу - не вопрос! Немного посложнее с проверкой, а не открылась ли позиция, но тоже решаемо. Я уже тут где-то выкладывал свою функцию для открытия позиций с обработкой ошибок. Тема, вроде бы, касалась реквот. Поищите. Если не найдёте, выложу снова.


Просто вот из этой темы 'Поясните, пожалуйста, про ERR_TRADE_TIMEOUT, код 128.'

Цитата Рената (по поводу не менее, чем через 1 минуту): "Вы можете попробовать совершить торговую операцию даже без задержек."

Т.е. я правильно понимаю, что получив ошибку, можно сразу пытаться ее обработать?

 
Вот что примерно получилось:
starttime = TimeCurrent();
if(OrderSend(......)==-1) {
   err = GetLastError();
   Print("Ошибка: ", err);
   Error(err, ...., starttime);
}
 
Error(err, ...., starttime) {
   int i, cnt;
......
   if(err == 128) { 
      cnt = OrdersTotal() - 1;
      for(i = cnt; i >=0; i--) {
         if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES))continue;
         if(starttime <= OrderOpenTime()) return("Ордер выставлен!");
      }
   }
...... Пробуем снова.
}
Такой вариант имеет право на жизнь?
 
KimIV:

Организовать минутную и более паузу - не вопрос! Немного посложнее с проверкой, а не открылась ли позиция, но тоже решаемо. Я уже тут где-то выкладывал свою функцию для открытия позиций с обработкой ошибок. Тема, вроде бы, касалась реквот. Поищите. Если не найдёте, выложу снова.

Здравствуйте, Игорь!
Пользуясь случаем хочу поблагодарить за функцию для открытия позиций с обработкой ошибок!(за многое другое то же). К сожалению, чтобы понять, что она хороша пришлось самому сделать несколько попыток в написании подобной функции и все равно каждый раз мой код после оптимизации в общем сводился к коду Вашей. Верю, что Вы его доводили до ума два года.

Хотел очень скромно предложить доработку одной из Вашей функции, которая занимается как раз проверкой: а не открылась ли позиция.:
//+----------------------------------------------------------------------------+
//|  Возвращает флаг существования позиций                                     |
//|  Параметры:                                                                |
//|    sy - наименование инструмента   (""   - любой символ,                   |
//|                                     NULL - текущий символ)                 |
//|    op - операция                   (-1   - любая позиция)                  |
//|    mn - MagicNumber                (-1   - любой магик)                    |
//+----------------------------------------------------------------------------+
bool ExistPositions(string sy="", int op=-1, int mn=-1, datetime ot=2111111111)//2111111111=2036.11.24 03:45:11; 
  {
  int i, k=OrdersTotal();
  
  if (sy=="0") sy=Symbol();
  for (i=0; i<k; i++){
    if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)){
      if (OrderSymbol()==sy || sy==""){
        if (OrderType()==OP_BUY || OrderType()==OP_SELL){
          if (op<0 || OrderType()==op){
            if (mn<0 || OrderMagicNumber()==mn){
              if (OrderOpenTime()>=ot){
               return(true);
               }
              }
            }
          }
        }
      }
    }
  return(false);
  }
Просто добавил проверку времени открытой позиции для случая если поз много. Что скажите?
Спасибо.
 
VBAG:
Хотел очень скромно предложить доработку одной из Вашей функции, которая занимается как раз проверкой: а не открылась ли позиция.:
...

Просто добавил проверку времени открытой позиции для случая если поз много. Что скажите?
Количество проходов по циклу не уменьшилось. Быстродействие не увеличилось. Какую Вы ставили цель при доработке?
 
KimIV:
VBAG:
Хотел очень скромно предложить доработку одной из Вашей функции, которая занимается как раз проверкой: а не открылась ли позиция.:
...

Просто добавил проверку времени открытой позиции для случая если поз много. Что скажите?
Количество проходов по циклу не уменьшилось. Быстродействие не увеличилось. Какую Вы ставили цель при доработке?
В функцию ExistPosition добавил входной параметр ot(open time)-время открытия(начала отсылки ордера).
Если у нас уже есть позы по этому инструменту и в этом же направлении, то добавленный параметр ot позволит отфильтровать другие ордера.
Т.е. перед тем как посылать OrderSend(....) запоминаем время и передаем его в функцию ExistPosition.
Может и перемудрил?
 
VBAG писал (а):
В функцию ExistPosition добавил входной параметр ot(open time)-время открытия(начала отсылки ордера).
Если у нас уже есть позы по этому инструменту и в этом же направлении, то добавленный параметр ot позволит отфильтровать другие ордера.
Это я понял из Вашего кода. Ещё раз спрошу, какова была цель Вашей доработки? Вы хотели повысить быстродействие? Вы хотели уменьшить количество перебираемых ордеров? Или может что-то другое?
 
KimIV:
VBAG писал (а):
В функцию ExistPosition добавил входной параметр ot(open time)-время открытия(начала отсылки ордера).
Если у нас уже есть позы по этому инструменту и в этом же направлении, то добавленный параметр ot позволит отфильтровать другие ордера.
Это я понял из Вашего кода. Ещё раз спрошу, какова была цель Вашей доработки? Вы хотели повысить быстродействие? Вы хотели уменьшить количество перебираемых ордеров? Или может что-то другое?
Если предположить, что у нас уже есть поза GBPUSD по OP_BUY и мгиком 0 и после отправки ордера на покупку еще одного контракта по GBPUSD по OP_BUY и мгиком 0 Вашим кодом:
    ticket=OrderSend(sy, op, ll, pp, Slippage, sl, tp, lsComm, mn, 0, clOpen);
    if (ticket>0) {
      if (UseSound) PlaySound(NameFileSound); break;
    } else {
      err=GetLastError();
      if (err==128 || err==142 || err==143) {
        Sleep(1000*75);
        if (ExistPositions(sy, op, mn)) {
          if (UseSound) PlaySound(NameFileSound); break;
        }
      }
мы получаем одну из ошибок
err==128 || err==142 || err==143)
то уходим в функцию
bool ExistPositions(string sy="", int op=-1, int mn=-1) {
  int i, k=OrdersTotal();
 
  if (sy=="0") sy=Symbol();
  for (i=0; i<k; i++) {
    if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
      if (OrderSymbol()==sy || sy=="") {
        if (OrderType()==OP_BUY || OrderType()==OP_SELL) {
          if (op<0 || OrderType()==op) {
            if (mn<0 || OrderMagicNumber()==mn) return(True);
          }
        }
      }
    }
  }
  return(False);
}
чтобы убедиться что позиция открылась.
Мне сдается, что в этой ситуации функция ExistPosition увидит первую ранее открытую позу и вернет true раньше времени, не дождавшись результата от последней посылки.
Вот я и предложил подстраховаться проверкой времени открытия. Возможно я ошибаюсь в логике работы Вашего кода.
 
VBAG писал (а):
Мне сдается, что в этой ситуации функция ExistPosition увидит первую ранее открытую позу и вернет true раньше времени, не дождавшись результата от последней посылки.

Точно... так и есть... Вы правы... Функции ExistPosition() совершенно без разницы:
1. когда была открыта позиция
2. сколько было открыто позиций

И когда возникает ошибка 128 при уже существующей позиции, то это будет воспринято, как поза уже открылась и попытки открыться будут прекращены!

Благодарю Вас, Владимир! Вы нашли существенную недоработку моей функции. Я подумаю над Вашим вариантом доработки и поищу другие варианты.

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