Скачать MetaTrader 5
Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
Подключи MQL5 Cloud Network. Миллионы трейдеров ждут этого!
Ilya Prozumentov
216
Ilya Prozumentov 2016.01.11 00:30 
Есть индикатор, он производит сравнение котировок между собой и на основании этого строит линию, по одной из подходящих цен. Изначально последовательность действий была такая:
//RT - rates total
//PC - prevev calculated
{
   RT = iBars(_Symbol, InTimeframe);
   Index = RT - PC - 1;
   if(Index == -1)
      Index = 0;
   
   for(Index = Index; Index > -1; Index--)
   {
      OHLCCorrector();
      LimitZone();
   }   
   PC = RT;
   return(rates_total)
}
и индикатор исправно работал.

Затем я научил его строить Фибоначчи, но для оптимизации рисования потребовалось определять появление нового бара и код стал таким:
{
   RT = iBars(_Symbol, InTimeframe);
   Index = RT - PC - 1;
   if(Index == -1)
      Index = 0;
   
   for(Index = Index; Index > -1; Index--)
   {
      OHLCCorrector();
      LimitZone();
      if((RT - PC) == 1)
         Fibonacci();
      PC = RT - Index;
   }
   return(rates_total);
}
этот код отказался исправно работать, основная линия индикатора обрывалась. При пошаговом изучении происходящего обнаружилось, что теперь ни одно из условий для записи определённого значения в индикаторный буфер не выполнялось. Причиной стала котировка несоответствующей точности. То есть вместо 0,8386  iClose выдавал 0,838599999999. Такие же длинные котировки проскакивают и при печати в журнал. Я попробовал применить нормализацию. Нормализация до 3-х знаков сработала, но до 4-х никак не помогла. Я попробовал преобразование Double - Str - Double с точностью 4, но и это не принесло результата. В архиве котировок, если туда вручную заглянуть, таких длинных котировок нет.
Ilyas
1182
Ilyas 2016.01.11 14:02  
http://www.softelectro.ru/ieee754.html -  хорошая статья, прочитайте про точность представления вещественных чисел
ksili
14
ksili 2016.01.11 16:56  

Тут только поможет нормализация. Переменные должны быть типа float. С типом double у меня тоже не всегда нормализовало. А вот с флоатом никаих проблем не возникало.

Ilyas
1182
Ilyas 2016.01.12 09:04  
Не используйте float!
Этот тип позволяет хранить только очень приблизительные значения.

Пример:
input double d=10.0;
input float  f=10.0f;

void OnStart()
  {
   Print(typename(d),": ",(7/d)*1000.0);
   Print(typename(f),": ",(7/f)*1000.0);
  }

Результат:
float:  699.9998688697815
double: 700.0
ksili
14
ksili 2016.01.12 11:24  

блин о чем я сказал? о том что нужно нормализовать флоат. если вы приведете нормализацию флоата то будет тоже 700

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

Ilyas
1182
Ilyas 2016.01.12 11:52  
ksili:

блин о чем я сказал? о том что нужно нормализовать флоат. если вы приведете нормализацию флоата то будет тоже 700

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

Числа нормализуются до нужного знака всегда!

Но вот не всегда вещественное число можно представить в виде конечной двоичной записи и погрешность для float выше, т.к. мантиса значительно меньше(23 бита), чем у double (52 бита).
Slawa
Модератор
6676
Slawa 2016.01.12 11:54  
ksili:

блин о чем я сказал? о том что нужно нормализовать флоат. если вы приведете нормализацию флоата то будет тоже 700

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

Вы сначала прочитайте статью, которую Вам порекомендовали.

Топикстартер же даже не подозревает, что 0,838599999999 является нормализованным значением и в дальнейшей нормализации не нуждается. Тоже не читал документацию https://docs.mql4.com/ru/basis/types/double, https://docs.mql4.com/ru/convert/normalizedouble, https://docs.mql4.com/ru/basis/operations/relation

Mislaid
553
Mislaid 2016.01.12 13:22  
ksili:

блин о чем я сказал? о том что нужно нормализовать флоат. если вы приведете нормализацию флоата то будет тоже 700

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

Если вас интересует равенство двух вещественных чисел, то знания о нормализации являются излишеством.

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

noloxe
458
noloxe 2016.01.13 15:56  
mql5:
http://www.softelectro.ru/ieee754.html -  хорошая статья, прочитайте про точность представления вещественных чисел

А почему бы вам не ввести (в MQL), автоматическую нормализацию всех расчетов?

Можно по указанию при инициализации: 

— по разрядности текущего инструмента, 

— по выбранной разрядности

— при явном указании (иначе по инструменту)

— без нормализцации (как сейчас) 

... 

 

кстати и округление можно было бы разное ввести, чтобы можно было нормализировать "отбрасыванием лишних разрядов" 

Vladimir
199
Vladimir 2016.01.21 08:08  
noloxe:

А почему бы вам не ввести (в MQL), автоматическую нормализацию всех расчетов?

Можно по указанию при инициализации: 

— по разрядности текущего инструмента, 

— по выбранной разрядности

— при явном указании (иначе по инструменту)

— без нормализцации (как сейчас) 

... 

 

кстати и округление можно было бы разное ввести, чтобы можно было нормализировать "отбрасыванием лишних разрядов


Здесь говорится, что сейчас расчеты идут без нормализации. Это не так. Вне всяких языков уровня MQL само аппаратное представление чисел с плавающей точкой на разных платформах (Стандарт IEEE 754-1985) уже включает такие понятия:

  • как представлять нормализованные положительные и отрицательные числа с плавающей точкой
  • как представлять денормализованные положительные и отрицательные числа с плавающей точкой
  • как представлять нулевые числа
  • как представлять специальную величину бесконечность (Infinity)
  • как представлять специальную величину "Не число" (NaN или NaNs)
  • четыре режима округления

  • Чуть выше mql5 дал ссылку http://www.softelectro.ru/ieee754.html, где это написано. намного подробнее

    Понятие "нормализации вещественных чисел" в MQL отвечает очень специальной задаче, сводится к десятичному округлению до 0-8 значащих цифр и, конечно же, противоречит общепринятому понятию нормализованности вещественных чисел в двоичном представлении. Его лучше не развивать, а назвать иначе. Зачем ему дали название из общеупотребительных, не знаю, но, по-моему, хорошо бы избавиться от возникающих неясностей. Простой путь - число типа "Цена" с теми же свойствами.

    P.S. В своих опусах я использую еще число типа "Объем". Указываю в начале программы единицы измерения объема (0.01 или 0.001 лота, это и минимальный объем, и шаг объемов) и остальные операции с объемами свожу к целым числам (в MT5 так не выходит).

    P.P.S. Думается, в https://docs.mql4.com/ru/basis/operations/relation фразу "Для корректного сравнения двух вещественных чисел необходимо сравнивать нормализованную разницу этих чисел с нулевым значением." необходимо поправить или убрать. Если править, то заменить "двух вещественных чисел" на "двух вещественных чисел ценовой природы (курс, уровень ордера...) "

    /
    Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий