Скачать MetaTrader 5
Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
Подключи MQL5 Cloud Network. Миллионы трейдеров ждут этого!
Aikis
17
Aikis 2015.03.08 10:16 

Пишем digits. Получаем "5".

Пишем Open[0],Close[0],High[0], Low[0]. Выводим эти значения через Alert (эта функц. может выводить до 8 знаков после точки).

И получаем котировки с 4 (!!!) значениями после запятой.

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

Бар 1.1234 является на самом деле баром 1.12345. А считается как 1.1234. Следовательно, получаем ошибку. У меня - это как одновременно бычий и медвежий бар.

Помогите пожалуста, я многое перерыл уже!!!


Как вариант - можно изначально присваивать некой переменной Open значение Open[0], потом выполнить функцию DoubleToString со значением 5.  

Рустам
3602
Рустам 2015.03.08 13:27  
всегда нормируйте
Алексей Тарабанов
7220
Алексей Тарабанов 2015.03.08 19:22  
FAQ:
всегда нормируйте
?
Алексей Тарабанов
7220
Алексей Тарабанов 2015.03.08 20:14  
Aikis:

Пишем digits. Получаем "5".

Пишем Open[0],Close[0],High[0], Low[0]. Выводим эти значения через Alert (эта функц. может выводить до 8 знаков после точки).

И получаем котировки с 4 (!!!) значениями после запятой.

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

Бар 1.1234 является на самом деле баром 1.12345. А считается как 1.1234. Следовательно, получаем ошибку. У меня - это как одновременно бычий и медвежий бар.

Помогите пожалуста, я многое перерыл уже!!!


Как вариант - можно изначально присваивать некой переменной Open значение Open[0], потом выполнить функцию DoubleToString со значением 5.  

Не переживайте, сколько бы знаков ни выводил Alert, значение переменной будет таким, каким рассчитали его Вы. 
Aikis
17
Aikis 2015.03.08 21:22  
extern int digits=8;
int init()
   {
   double a,b,c,d,e,f,g;
   a=0.1234876;//--- цифры после 4-го значения после запятой нужно подбирать так, что-б нагляднее было видно округление,выполняемое функц double
   Alert("a без обработки = ",a);//----Значение ОКРУГЛЯЕТСЯ!!!
   Alert("a через DoubleToStr,где Digits ",digits," = ",DoubleToStr(a,digits));
   b=0.9876122;//--- цифры после 4-го значения после запятой нужно подбирать так, что-б нагляднее было видно округление,выполняемое функц double
   Alert("b без обработки = ",b);
   Alert("b через DoubleToStr,где Digits ",digits," = ",DoubleToStr(b,digits));
   c=a+b;
   Alert("c без обработки = ",c);//----ОТВЕТ ОКРУГЛЯЕТСЯ!!!
   Alert("с через DoubleToStr,где Digits ",digits," = ",DoubleToStr(c,digits));//--- Полученое значение отличается=>губительно на низких ТФ и тиковой торговли?
   //-----ПРЕОБРАЗОВАНИЕ double в string
   string a_str,b_str,c_str,d_str,e_str;
   a_str=DoubleToStr(a,digits);
   Alert("a_str=",a_str);
   b_str=DoubleToStr(b,digits);
   Alert("b_str=",b_str);

   //----ОБРАТНОЕ ПРЕОБРАЗОВАНИЕ double в string
   double a_new,b_new,c_new,d_new,e_new;
   a_new=StrToDouble("0.1234876");//---Использован способ записи из справочника
   Alert("a_new = ",a_new);
   Alert("a_new через DoubleToStr,где Digits ",digits," = ",DoubleToStr(a_new,digits));
   b_new=StrToDouble(b_str);//---Значение из ПРЕОБРАЗОВАНИЯ double в string
   Alert("b_new = ",b_new);
   Alert("b_new через DoubleToStr,где Digits ",digits," = ",DoubleToStr(b_new,digits));
   c_new=a_new+b_new;
   Alert("c_new = ",c_new);
   Alert("с_new через DoubleToStr,где Digits ",digits," = ",DoubleToStr(c_new,digits));
   //----Выводы
   //----Можно в функции StrToDouble писать значение не в скобках, а в виде переменно, что приятно и облегчит написание))) (кэп очевидность...)
   //----Как узнать, содержится ли в памяти значение double с точностью до 7-го знака, или там уже округлённое значение? Попробуем сравнением:
   
   
   if(c==1.11109980)//----значение с последней цифрой 0 (как и при расчёте)
      {
      Alert("перменная c типа double равняется ", "1.11109980");
      }
   if(c==1.1110998)//---в конце ноль не указан
      {
      Alert("перменная c типа double равняется ", "1.1110998");
      }
   if(c==1.11109981)//---в конце дописано 1
      {
      Alert("перменная c типа double равняется ", "1.11109981");
      }
   //--- В памяти содержится значение переменной "с" типа double с нужной нам точностью. Если в конце стоит "0", то это не влияет на результат
   //--- Проверим ещё одно:
   
   d=c+1;
   if(d==2.11109980)//----значение с последней цифрой 0 (как и при расчёте)
      {
      Alert("перменная d типа double равняется ", "2.11109980");
      }
   if(d==2.1110998)//---в конце ноль не указан
      {
      Alert("перменная d типа double равняется ", "2.1110998");
      }
   if(d==2.11109981)//---в конце дописано 1
      {
      Alert("перменная d типа double равняется ", "2.11109981");
      }
      //--- И ещё немного задротства:
      
   e=d+0.00000001;
   if(e==2.11109980)//----значение с последней цифрой 0 (как и при расчёте)
      {
      Alert("перменная e типа double равняется ", "2.11109980");
      }
   if(e==2.1110998)//---в конце ноль не указан
      {
      Alert("перменная e типа double равняется ", "2.1110998");
      }
   if(e==2.11109981)//---в конце дописано 1
      {
      Alert("перменная e типа double равняется ", "2.11109981");
      }
   //---В итоге - мы убедились, что в памяти переменная типа double хранится с нужным нам значением.
   //---НО!!!
   //---К примеру у нас есть цена открытия бара. Она округляется. А мы к примеру имеем индикатор, который от этой цены делает расчёты (ну например если открытие
   //--- больше-меньше предыдущего. И эти расчёты тоже округляются=> мы можем получить,что новое открытие стоит на месте ( по цифрам) !!!
   //--- Опыт на минутной истории:
   //--- Бар 2015.03.09. 00.03 открылся по цене 1.08298 (для меня это был нулевой бар)
   Alert("Open[0] = ",Open[0]); //--- Полученное значение - 1.083
   if(Open[0]==1.083)
      {
      Alert("Open[0] равняется ", "1.0851");
      }
   if(Open[0]==1.08298)//--- выполняется эта функция, значит в памяти значение открытия не округлено
      {
      Alert("Open[0] равняется ", "1.08298");
      }
   f=1.08297;
   g=1.08299;
   if(Open[0]>f&&Open[0]<g)
      {
      Alert("Open[0] находится в интервале ", f, " и ", g);
      }
   //---- И это мы тоже проверили!!! И оказалось, что всё верно! В памяти действительно хранится точное значение
   //---- НАВЕРНОЕ тоже касается индикаторов - т.е. их значения так-же имеют 5 точек после запятой, а не 4, как мы видим 
   //---- при вызове функции Alert
   
   //---- Честно говоря, изначально меня это очень смутило - "Как, ведь округли оно в другую сторону, индикатор выдаст ошибочку!!!"
   //---- Но теперь понятно, что это округление чисто для глаз, а на деле все значения имеются.
   //---- Спасибо мне что ответил на свой вопрос!
   
   
   }
Файлы:
simple.mq4 6 kb
Aikis
17
Aikis 2015.03.08 21:24  
Я отключал инет для фиксации 0-го бара. Сначала не поверилось tara, что всё так просто...
Aikis
17
Aikis 2015.03.08 21:28  
Как тут теперь закрыть тему?
Aikis
17
Aikis 2015.03.08 21:34  
Лан, тогда ещё вопросик.
У меня советничек делается, он сбрысывается (тупо исчезает, даже deinit не выполняет) когда я просто проматываю бары назад во времени... Шо может быть не так? 
Алексей Тарабанов
7220
Алексей Тарабанов 2015.03.08 21:35  
Она уже в архиве. 
Рустам
3602
Рустам 2015.03.08 23:35  
tara:
Она уже в архиве. 
  ))))))))
/
Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий