Новая версия платформы MetaTrader 5 build 2980: Push-уведомления о торговых операциях - страница 39

 
mktr8591 #:

Теперь возникает вопрос - как сделать полное аварийное прерывание программы (ABORT)?

раньше это можно было сделать через if(1/MathAbs(0.0)==1) - а теперь?

Кроме ExpertRemove() какие есть варианты?

 
fxsaber #:

Язык становится все более низкоуровневым. Не знаю, плохо это или хорошо.


Сам наткнулся на эту ситуацию, когда стал вычислять маржинальные требования (фактически, торговые лоты) и случайно запустил на кастомном символе, получив странное значение.

Полез в код, увидел деление на ASK-цену. Но у кастомного символа такой цены не было (CustomTicksAdd не вызывал) - MarketWatch-поля пустые, т.е. нулевые. И вот происходит деление на ноль, а ошибок нет.


Стал разбираться, и оказалось, что отныне делить на ноль можно. И если раньше знал, что случись деление на ноль в боевом советнике, программа просто вылетит и даже сообщит, что и где произошло. То теперь несколько некомфортно, т.к. в случае деления на ноль программа не остановится, а начнет некорректные вычисления пихать в торговлю: огромные лоты, близкие стопы, спам торговыми приказами, бесконечные перевороты и т.д.


Т.е. можно очень круто слить на программной ошибке! В этом дискомфорт. Ситуации же, когда вдруг произошло деление на ноль, могут быть настолько редкими, что не подвластны идее с дебагом. Раз в год "палка" стрельнет и сольет торговый счет. Надо придумывать какие-то защиты. Какие - голову ломать, видимо, долго.

Терминал не пропустит ордера с Nan или Inf
Софтверная валидация вещественного делителя дороже чем для целых.

Но мы можем для MQL программ добавить новое свойство - "хардверная обработка исключений", по умолчанию всегда включена и может быть отключена через #property FP_EXCEPTIONS_DISABLED
Тогда, при некорретных значениях операндов в операциях над вещественными, исключения будут генерироваться процессором, подобно целочисленному делению.
Соответственно MQL программы будут останавливаться по критической ошибке.

 
mktr8591 #:

Кроме ExpertRemove() какие есть варианты?

Есть предложение добавить таки функцию Halt

void Halt(string message);

После вызова которой, MQL программа останавливается немедленно, выводя в лог сообщение message, которое подсвечено как ошиба


Но можно по старинке:

void Halt(string message)
  {
   static int s_zero=0;

   Print(message);
   s_zero = 1 / s_zero;
  }
 
Ilyas #:

Но можно по старинке:

В b3030 в откомпилированном по F7 скрипте ваш Halt(..) печатает сообщение и скрипт спокойно продолжает дальше.

Так что нужен системный Halt()!

и #property FP_EXCEPTIONS_DISABLED не помешает!

 
mktr8591 #:

Теперь возникает вопрос - как сделать полное аварийное прерывание программы (ABORT)?

EXPERT::Remove();
Expert
Expert
  • www.mql5.com
Библиотека чтения/записи параметров произвольных советников.
 
mktr8591 #:

у вас в b3030 ошибка zero divide выдается для скрипта, откомпилированного в дебаг или релиз режиме?

Проверялась версия откомпилированная по F7 и запущенная перетаскиванием из навигатора на график.

 
mktr8591 #:

Можно сделать функцию-обертку для операции деления наподобие Div(a,b,exit=true,default=0),

Если b(делитель) == 0 или это NaN, то  для exit=true делать аварийное завершение программы, а для false - возвращать default.

А в режиме отладки пусть считает простым делением.

И применять ее всегда!

Это костыль. Особенно, если используешь не свои библиотеки. В частности, если используешь EX5-библиотеки.

 
Ilyas #:

Терминал не пропустит ордера с Nan или Inf
Софтверная валидация вещественного делителя дороже чем для целых.

Но мы можем для MQL программ добавить новое свойство - "хардверная обработка исключений", по умолчанию всегда включена и может быть отключена через #property FP_EXCEPTIONS_DISABLED
Тогда, при некорретных значениях операндов в операциях над вещественными, исключения будут генерироваться процессором, подобно целочисленному делению.
Соответственно MQL программы будут останавливаться по критической ошибке.

С сообщением о причине и месте ошибки?

 
mktr8591 #:

Кроме ExpertRemove() какие есть варианты?

Это только взвод IsStopped-флага и постановка в очередь OnDeinit-события.

 
Ilyas #:

Терминал не пропустит ордера с Nan или Inf

Nan и Inf где-то в промежуточных вычислениях могут, например, увеличить риски в 10 раз. Все, что угодно.

Поэтому всегда лучше иметь защиту, когда что-то боевое крутится.


Наверное, мало кто не только при делении, но и в других ситуациях проверяет тот же Tick.ask на валидность... Нарваться на невалидное значение - большая "удача". Соответственно, какой-нибудь Маркет-продукт из-за не супер-высокой компетентности автора будет выдавать сюрпризы. Раньше же просто: вылетел у покупателя советник - покупатель прислал лог и автору сразу понятно, где накосячил.

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