Скачать MetaTrader 5

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

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
Нет времени изучать MQL5? Библиотека исходников для вас!
Sergey Belyaev
433
Sergey Belyaev 2014.09.30 19:02 

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

При достижении заданного значения происходит закрытие ордеров. 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);
          }
        }
      }
    }
  }
}

Artyom Trishkin
Модератор
75738
Artyom Trishkin 2014.09.30 19:15  
57-miracle:

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

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

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

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

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

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

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

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

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

это понятно что сработало условие IsStopped(), и торговый приказ советником не отдавался, но почему оно сработало в первые за 20 месяцев использования и вроде в коде есть повтор ? и именно в одном из дц только.
Artyom Trishkin
Модератор
75738
Artyom Trishkin 2014.09.30 19:29  
57-miracle:
это понятно что сработало условие IsStopped(), и торговый приказ советником не отдавался, но почему оно сработало в первые за 20 месяцев использования и вроде в коде есть повтор ? и именно в одном из дц только.
Смотрите внимательно логи. Не только экспертов, но и терминала.
Alexandr Bryzgalov
27540
Alexandr Bryzgalov 2014.09.30 19:34  

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

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

Sergey Belyaev
433
Sergey Belyaev 2014.09.30 19:35  
artmedia70:
Смотрите внимательно логи. Не только экспертов, но и терминала.

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

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

Artyom Trishkin
Модератор
75738
Artyom Trishkin 2014.09.30 19:39  
57-miracle:

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

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

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

Sergey Belyaev
433
Sergey Belyaev 2014.09.30 19:43  
artmedia70:

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


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

Artyom Trishkin
Модератор
75738
Artyom Trishkin 2014.09.30 19:47  
57-miracle:


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

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

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

Alexandr Bryzgalov
27540
Alexandr Bryzgalov 2014.09.30 19:49  
57-miracle:


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

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

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

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

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

Sergey Belyaev
433
Sergey Belyaev 2014.09.30 19:50  
artmedia70:

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

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

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