Ньюансы-тонкости при программировании на MQL4

 

Цель создания данной ветки:

общими силами описать в одном месте различные возникающие ньюансы-тонкости при программировании на MQL4.

 

Пример того, как применение функции NormalizeDouble при неправильном применении искажает результат.

Ниже различные реализации преобразования числа типа int в число типа double и обратно:

// Не правильно (NumInt != NumInt2) (Пример: int NumInt = 59)
  double NumDouble = NumInt * Point;
  int NumInt2 = NumDouble / Point;
// Еще хуже (больше вариантов NumInt != NumInt2) (Пример: int NumInt = 29)
  double NumDouble = NormalizeDouble(NumInt * Point, Digits);
  int NumInt2 = NumDouble / Point;
// Ошибки не замечены, т.е. NumInt == NumInt2
  double NumDouble = NumInt * Point;
  int NumInt2 = NormalizeDouble(NumDouble / Point, Digits);
 

Попробуйте вместо NormalizeDouble использовать например MathRound.

Честно говоря был безумно удивлен, когда узнал что функции MathRound, MathCeil и MathFloor возвращают целые числа тип double.

 

Просто не делайте винигрета из Int и Doible и проблем не будет

 
getch:

Пример того, как применение функции NormalizeDouble при неправильном применении искажает результат.

Ниже различные реализации преобразования числа типа int в число типа double и обратно:

// Еще хуже (больше вариантов NumInt != NumInt2) (Пример: int NumInt = 29)
  double NumDouble = NormalizeDouble(NumInt * Point, Digits);
  int NumInt2 = NumDouble / Point;
В верхнем примере все собственно понятно. Логика есть.
// Ошибки не замечены, т.е. NumInt == NumInt2
  double NumDouble = NumInt * Point;
  int NumInt2 = NormalizeDouble(NumDouble / Point, Digits);
А вот с тем вариантом где целое пытаешься нормализовать это помоему глупо. целое и есть целое.
 

Это частный пример.

В третьем варианте нормализация используется, как функция округление с заданной точностью на случай более общей задачи. Конкретно в данном случае логично, но не обязательно, использование MathRound.

Вышеприведенный второй вариант с нормализацией хуже первого варианта без нее. Это и показано в примере.

 

Нормализация округляет, и это например в случае с котировками типа: 1.4321555763 может привести к грубой ошибке в анализе. А такие котировки хоть и редко, но встречаются.

Решил:

- использовать нормализацию только при работе с ордерами

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

int doubleToInt(double do_doubleToInt){
   return(do_doubleToInt*MathPow(10,Digits));
}

- присваивать значения переменным типа double без нормализации, для меньшей потери информации

 

Интересная информация для любителей типо меня не являющихся профессионалами в программировании

Плавающая арифметика - вещь приблизительная..

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