Можно ли в MQL5 задать тип decimal - страница 2

 

Еще обратите внимание, что оптимизатор компилятора почти все выражения ваших примеров свернет еще на этапе компиляции, распознав константность.

То есть, пример из #10 запросто может превратиться в одну строку:

Print(-2.775557561562891e-17);
 
double x1 = 0.01;
   double x2 = 0.02;
   double x3 = 0.03;
   double x4 = 0.01;
   double x5 = 0.01;
   double x6 = 0.01;
   double x7 = 0.01;
   double x8 = 0.05;

   double x = NormalizeDouble(x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8,2);
   double y = 0.15;
   double z = NormalizeDouble(x - y,2);

   if(z!=0)
      Print(x-y);
 
Alexander Bereznyak:
double x1 = 0.01;
   double x2 = 0.02;
   double x3 = 0.03;
   double x4 = 0.01;
   double x5 = 0.01;
   double x6 = 0.01;
   double x7 = 0.01;
   double x8 = 0.05;

   double x = NormalizeDouble(x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8,2);
   double y = 0.15;
   double z = NormalizeDouble(x - y,2);

   if(z!=0)
      Print(x-y);
Вопрос был о том, как избавиться от NormalizeDouble, чтобы обрезание происходило в фоновом режиме, а так-то да, можно вызывать метод явно
 
Andy Sanders:
Как минимум в двух случаях я такое замечал, когда писал расчет виртуальных ордеров, дублирующих неттинг исполнение МТ5 и вот сейчас в советнике, пример ниже.
И если с ордерами расчетов было много и погрешность double была предсказуема + кривизна моих рук, то боюсь, что из-за подобных ошибок в советнике я мог пару годных стратегий спустить на мусорку, в частности тех, которые работают с пересчетом лотов на сделку.

Вот кусок банального, неприметного кода, MT5 hedging mode :
double buyAlignment = sizeSell - sizeBuy; // check if lot of Sell > lot of Buy
double sellAlignment = sizeBuy - sizeSell; // check if lot of Buy > lot of Sell

if (buyAlignment > 0) // if Sell > Buy, make positions equal by size
{
    Print("################## BUY : " + buyAlignment + " = " + sizeSell + " - " + sizeBuy);
    openSimplePosition(symbol, 1, buyAlignment);
}

if (sellAlignment > 0) // if Buy > Sell, make positions equal by size
{
    Print("################## SELL : " + sellAlignment + " = " + sizeBuy + " - " + sizeSell);
    openSimplePosition(symbol, -1, sellAlignment);
}
Результат выполнения этого кода в нормальном случае выглядит так :
2016.12.17 03:04:58.657    2016.01.06 16:00:00   ################## SELL : 0.01 = 0.02 - 0.01
Но потом случается чудо ...
2016.12.17 03:05:47.736    2016.01.06 18:00:00   ################## SELL : 0.009999999999999998 = 0.03 - 0.02  //  WTF ???
Ну ок, допустим, у МТ какие-то свои мысли по поводу того, как представлять число, но тогда логично предположить, что код везде сьедает double в меньшую сторону, НО ... тут проиходит второе чудо и МТ решает, что 0 это вовсе не 0, а 0.0000000000000000000036453265234832582365325, ну что ж логично, и в результате этого "логично" я получаю такое :)
2016.12.17 03:08:33.094    2016.01.06 19:54:01   ################## BUY : 2.775557561562891e-17 = 0.15 - 0.15
2016.12.17 03:08:33.094    2016.01.06 19:54:01   failed market buy 0.00 EURUSD.m [Invalid volume]
Сразу отвечу "умникам", которые попытаются указать на то, что я делаю неявную конвертацию double в строку при выводе сообщения ... я то делаю, но вот факт, что в самом коде проверка (0 > 0.15 - 0.15) проходит, меня пугает ...
Для воспроизведения ошибки, напишите советника, которые, на каждом баре открывает позицию, рандомно, а через каждые, допустим, 5 баров делает позиции равными, как в коде выше.

Конкретную задачу надо и решать конкретно. Выравнивание объемов позиций возможно только с погрешностью в минимальный размер лота (и минимальный шаг изменения лота). Читал, в Oanda он почти нулевой, но не пробовал - пишу для встречавшихся случаев, чаще всего 0.01 лота. С такой погрешностью и надо сравнивать объемы сделок, а не с нулевой. Сам я при подсчетах лотов использую целые числа, на которые нужно умножать их единицу измерения (0.01, например).

В случае неттинга еще интереснее. С какой погрешностью держать курс открытия позиции, получившейся в результате трех покупок одинаковым лотом по курсам K, K, K+0.0001. Делить надо на три. Не вводить же для этого троичные числа...

Помнится, планы ввести в процессорах возможность операций с десятичными числами в развитие стандарта IEEE 754-2008 были. Потребность, похоже, есть. Будут в компьютерах - будут и в большинстве языков, и до MQL доберутся.

IEEE Standard for Floating-Point Arithmetic - IEEE Xplore Document
  • ieeexplore.ieee.org
This standard specifies interchange and arithmetic formats and methods for binary and decimal floating-point arithmetic in computer programming environment