Ошибка или баг функции ClosePosBySelect() ?

 

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

При достижении заданного значения происходит закрытие ордеров. 20 месяцев на различных типов счетов проблем никогда не было, сегодня случился первый баг на моей практике. Придя до экрана, обнаружил висящие ордера превышающие допустимое значение на одном из 5-ти счетов при двух дц и разных типов !

Удалось удачно разрулить ситуацию, так как цена вернулась на уровень стопа и прикрыть всё в ручную, + отыграть часть потери. Но дело могло обернутся в плачевную сторону и цена могла не вернуться, вплоть до полной потери депо.

Разбираясь в логах обнаружил :

в журнале в момент бага тишина и приказов на закрытие не последовало. В логе эксперта "имя советника": ClosePosBySelect(): Остановка работы функции и всё, сделки пошли дальше в минус, советник "остановился" ни потеря связи ни реквот не было. Терминал версии 670.

Где ошибка то в коде ? Я её вроде не обнаружил, должен быть повтор команды до закрытия...

void ClosePosBySelect(double ll=0) {
  bool   fc;
  color  clClose;
  double pa, pb, pp;
  int    dg=MarketInfo(OrderSymbol(), MODE_DIGITS), err, it;

  if (OrderType()==OP_BUY || OrderType()==OP_SELL) {
    for (it=1; it<=NumberOfTry; it++) {
      if (!IsTesting() && (!IsExpertEnabled() || IsStopped())) {
        Message("ClosePosBySelect(): Остановка работы функции");
        break;
      }
      while (!IsTradeAllowed()) Sleep(5000);
      RefreshRates();
      pa=MarketInfo(OrderSymbol(), MODE_ASK);
      pb=MarketInfo(OrderSymbol(), MODE_BID);
      if (OrderType()==OP_BUY) {
        pp=pb; clClose=clCloseBuy;
      } else {
        pp=pa; clClose=clCloseSell;
      }
      if (ll<=0) ll=OrderLots();
      pp=NormalizeDouble(pp, dg);
      fc=OrderClose(OrderTicket(), ll, pp, Slippage, clClose);
      if (fc) {
        if (UseSound) PlaySound(SoundSuccess); break;
      } else {
        err=GetLastError_v();
        if (UseSound) PlaySound(SoundError);
        if (err==146) while (IsTradeContextBusy()) Sleep(1000*11);
        Message("Error("+err+") Close "+GetNameOP(OrderType())+" "
               +ErrorDescription(err)+", try "+it+"\n"
               +OrderTicket()+"  Ask="+DoubleToStr(pa,dg)
               +"  Bid="+DoubleToStr(pb,dg)+"  pp="+DoubleToStr(pp,dg)+"\n"
               +"sy="+OrderSymbol()+"  ll="+DoubleToStr(ll,2)
               +"  sl="+DoubleToStr(OrderStopLoss(),dg)
               +"  tp="+DoubleToStr(OrderTakeProfit(),dg)+"  mn="+OrderMagicNumber());
        Sleep(1000*5);
      }
    }
  } else Message("Некорректная торговая операция. Close "+GetNameOP(OrderType()));
}
//+----------------------------------------------------------------------------+
void ClosePosFirstProfit(string sy="", int op=-1, int mn=-1) {
  int i, k=OrdersTotal();
  if (sy=="0") sy=Symbol();

  for (i=k-1; i>=0; i--) {
    if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
      if ((OrderSymbol()==sy || sy=="") && (op<0 || OrderType()==op)) {
        if (OrderType()==OP_BUY || OrderType()==OP_SELL) {
          if (mn<0 || OrderMagicNumber()==mn) {
            if (OrderProfit()+OrderCommission()+OrderSwap()>0) ClosePosBySelect();
          }
        }
      }
    }
  }
  k=OrdersTotal();
  for (i=k-1; i>=0; i--) {
    if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
      if ((OrderSymbol()==sy || sy=="") && (op<0 || OrderType()==op)) {
        if (OrderType()==OP_BUY || OrderType()==OP_SELL) {
          if (mn<0 || OrderMagicNumber()==mn) ClosePosBySelect();
        }
      }
    }
  }
}
//+----------------------------------------------------------------------------+
void ClosePositions(string sy="", int op=-1, int mn=-1, double ll=0) {
  int i, k=OrdersTotal();

  if (sy=="0") sy=Symbol();
  for (i=k-1; i>=0; i--) {
    if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
      if ((OrderSymbol()==sy || sy=="") && (op<0 || OrderType()==op)) {
        if (OrderType()==OP_BUY || OrderType()==OP_SELL) {
          if (mn<0 || OrderMagicNumber()==mn) {
            if (ll<=0) ll=OrderLots();
            if (ll>OrderLots()) {
              ClosePosBySelect(OrderLots());
              ll-=OrderLots();
            } else ClosePosBySelect(ll);
          }
        }
      }
    }
  }
}

 
57-miracle:

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

При достижении заданного значения происходит закрытие ордеров. 20 месяцев на различных типов счетов проблем никогда не было, сегодня случился первый баг на моей практике. Придя до экрана, обнаружил висящие ордера превышающие допустимое значение на одном из 5-ти счетов при двух дц и разных типов !

Удалось удачно разрулить ситуацию, так как цена вернулась на уровень стопа и прикрыть всё в ручную, + отыграть часть потери. Но дело могло обернутся в плачевную сторону и цена могла не вернуться, вплоть до полной потери депо.

Разбираясь в логах обнаружил :

в журнале в момент бага тишина и приказов на закрытие не последовало. В логе эксперта "имя советника": ClosePosBySelect(): Остановка работы функции и всё, сделки пошли дальше в минус, советник "остановился" ни потеря связи ни реквот не было. Терминал версии 670.

Где ошибка то в коде ? Я её вроде не обнаружил, должен быть повтор команды до закрытия...

Здесь смотрите:

if (!IsTesting() && (!IsExpertEnabled() || IsStopped())) {
        Message("ClosePosBySelect(): Остановка работы функции");
        break;
 
artmedia70:

Здесь смотрите:

это понятно что сработало условие IsStopped(), и торговый приказ советником не отдавался, но почему оно сработало в первые за 20 месяцев использования и вроде в коде есть повтор ? и именно в одном из дц только.
 
57-miracle:
это понятно что сработало условие IsStopped(), и торговый приказ советником не отдавался, но почему оно сработало в первые за 20 месяцев использования и вроде в коде есть повтор ? и именно в одном из дц только.
Смотрите внимательно логи. Не только экспертов, но и терминала.
 

мог сработать и запрет на торговлю советниками, может кто кнопку нажал?

нужно логи смотреть, что там было.

 
artmedia70:
Смотрите внимательно логи. Не только экспертов, но и терминала.

В том то и дело что в логах пусто в момент сбоя, только в логах эксперта, остановка и всё... Данная функция не является стандартной функцией mql и поэтому не дает в результате стандартной ошибки в логе для анализа, обратиться к разработчику за пояснениями о возможных причинах сбоя функции, это всё что они могли сказать ))) Дц вообще может быть замешан в такой ситуации ?

Кнопку отжать никто не мог. Это было бы видно в логе.

 
57-miracle:

В том то и дело что в логах пусто в момент сбоя, только в логах эксперта, остановка и всё... Данная функция не является стандартной функцией mql и поэтому не дает в результате стандартной ошибки в логе для анализа, обратиться к разработчику за пояснениями о возможных причинах сбоя функции, это всё что они могли сказать ))) Дц вообще может быть замешан в такой ситуации ?

Факт, что функция сработала на одно из условий: Если не тестовый режим и (Отжата кнопка Авто-торговля или Эксперт остановлен).

Раз реал, значит точно не тестовый режим --> значит одно из (Отжата кнопка Авто-торговля или Эксперт остановлен).

 
artmedia70:

Раз реал, значит точно не тестовый режим --> значит одно из (Отжата кнопка Авто-торговля или Эксперт остановлен).


Ситуация была в 13-07 по времени терминала, когда я обнаружил сие (минус больше положенного) то выключил сам советник и начал выкручиваться. Остановка авто торговли зафиксировано в журнале в 13-53 !

 
57-miracle:


Ситуация была в 13-07 по времени терминала, когда я обнаружил сие (минус больше положенного) то выключил сам советник и начал выкручиваться. Остановка авто торговли зафиксировано в журнале в 13-53 !

Значит, запись в журнале - реакция функции на ваши действия.

Тогда ищите в другом месте где советник не понял, что закрывать пора. Дело не в функции Игоря.

 
57-miracle:


Ситуация была в 13-07 по времени терминала, когда я обнаружил сие (минус больше положенного) то выключил сам советник и начал выкручиваться. Остановка авто торговли зафиксировано в журнале в 13-53 !

может до этого момента что-то произошло?(смена счёта, смена сервера при этом могут отключиться советники если в настройках задано отключаться)

и тут на этом условии вывалилось.

без лога долго можно гадать.

а лучше в сервисдеск, пусть там покурят )

 
artmedia70:

Значит, запись в журнале - реакция функции на ваши действия.

Тогда ищите в другом месте где советник не понял, что закрывать пора. Дело не в функции Игоря.

Да я на него не грешу. А в другом месте негде искать, ибо всё всегда работало правильно, это случилось просто вдруг. Даже паралельно на 2-х других терминалах, причём везде советник одинаковый. Хотелось просто разобраться как могло возникнуть данное условие остановки функции...
Причина обращения: