Ваши вопросы по языку MQL4

hoz

Активный участник
Нет, вполне нормальные. Проблема в погрешности при хранении и обработке double данных.

Хм. Очень интересно. Первый раз такое слышу. Мне доводилось слышать, что в терминал могут попадать котировки с разрядностью до множества цифр, куда дальше ежели 8... Интересно, как тогда так получается.
Я то понимаю, что проще потерять часть точности, т.е. уменьшить количество цифр после запятой, но, чтоб сама разрядность увеличилась..:facepalm: Для меня это нонсенс. Тут можно тока поверить Вам на слово, т.к. логически что-то не увязка получается.
 

ansol

Местный знаток
Хм. Очень интересно. Первый раз такое слышу. Мне доводилось слышать, что в терминал могут попадать котировки с разрядностью до множества цифр, куда дальше ежели 8... Интересно, как тогда так получается.
Я то понимаю, что проще потерять часть точности, т.е. уменьшить количество цифр после запятой, но, чтоб сама разрядность увеличилась..:facepalm: Для меня это нонсенс. Тут можно тока поверить Вам на слово, т.к. логически что-то не увязка получается.

У меня был очень неприятный случай с альпари. Счет был типа NDD с перерасчетом свопов overnight. Вообщем, ночью ордер закрывали и открывали снова по другой цене, но с учетом этого свопа. В результате, вместо нормальной 5-значной цены получалась 6-значная, т.е. за 1 день своп в пунктах был дробным по некоторым парам.
И перестал работать трейлингстоп :nda: А все просто - трейлингстоп прибавлял к цене Х пунктов и отправлял OrderModify с полученным новым стоплосс'ом, который без нормализации оставался 6-значным.
Может, это имелось в виду?
Во всех остальных случаях цена приходит психически нормальная :D
 

qqmber

Почетный гражданин
Добрый день, уважаемые форумчане!

Сделать пересечение двух МА – несложно.
А вот как написать код, в котором, например, MA5 пересекает снизу вверх последовательно три МА: МА31, МА21, MA11?

Прошу Вашей помощи.
Заранее благодарен.

Набросал скриптец, который рисует палки в местах выполнения твоего условия. Так надо?
Код:
Expand Collapse Copy
int tx(int i0, int j, int k, int k_price) {
double jma0,kma0,jma1,kma1;

   for(int i=i0; i>0; i--) {
      jma0=iMA(NULL,0,j,0,0,0,i);
      kma0=iMA(NULL,0,k,0,0,k_price,i);
      jma1=iMA(NULL,0,j,0,0,0,i+1);
      kma1=iMA(NULL,0,k,0,0,k_price,i+1);
      if(jma0-kma0 > 0 && jma1-kma1 <=0) return(i);
   }
   return(-1);     
}

int start() {
int t5x11,t5x21,t5x31;

   for(int start=WindowFirstVisibleBar(); start>0; start=t5x11-1) {
      t5x31=tx(start,5,31,PRICE_LOW); 
      t5x21=tx(t5x31,5,21,PRICE_CLOSE);
      t5x11=tx(t5x21,5,11,PRICE_HIGH);
      if(t5x11>0) ObjectCreate(""+t5x11,0,0,Time[t5x11],0,0,0);      
   }
}
 
Последнее редактирование:

Ugar

Гуру форума
Хм. Очень интересно. Первый раз такое слышу. Мне доводилось слышать, что в терминал могут попадать котировки с разрядностью до множества цифр, куда дальше ежели 8... Интересно, как тогда так получается.
Я то понимаю, что проще потерять часть точности, т.е. уменьшить количество цифр после запятой, но, чтоб сама разрядность увеличилась..:facepalm: Для меня это нонсенс. Тут можно тока поверить Вам на слово, т.к. логически что-то не увязка получается.
Статья
Особенности работы с числами типа double в MQL4 _http://articles.mql4.com/ru/762


http://articles.mql4.com/ru/762
 
Последнее редактирование:

qqmber

Почетный гражданин
Добавлю, не надейтесь, что результат Bid+i*Point с нормализованными бидом и пойнтом и целым i окажется автоматически нормализованным. Как повезет.
 

ansol

Местный знаток
Добавлю, не надейтесь, что результат Bid+i*Point с нормализованными бидом и пойнтом и целым i окажется автоматически нормализованным. Как повезет.

В тестере везет всегда :D А реале, как только не повезет - сменю ДЦ нафиг! Иначе у меня вся сова будет в "нормализах" увешана :nda:
 

qqmber

Почетный гражданин
В тестере везет всегда :D А реале, как только не повезет - сменю ДЦ нафиг! Иначе у меня вся сова будет в "нормализах" увешана :nda:
На самом деле торговые функции прощают небольшие ошибки с нормализацией. Тем не менее, скрипт
Код:
Expand Collapse Copy
int start() {
   for(int i=1;i<10;i++) 
      if(NormalizeDouble(Bid+i*Point,Digits) != Bid+i*Point) Print(i," is not Normal");
}
И результат
15:28:10 stst AUDUSD,Daily: 2 is not Normal
15:28:10 stst AUDUSD,Daily: 3 is not Normal
15:28:10 stst AUDUSD,Daily: 4 is not Normal
15:28:10 stst AUDUSD,Daily: 5 is not Normal
 

Ugar

Гуру форума
В тестере везет всегда :D А реале, как только не повезет - сменю ДЦ нафиг! Иначе у меня вся сова будет в "нормализах" увешана :nda:
Менять ДЦ бесполезно. Придётся поменять компьютер на миллиметровую бумагу с чертёжными принадлежностями + телефон для отправки приказов. :D
Если серьёзно. Не обязательно весь советник увешивать нормализами. Достаточно пересмотреть условия сравнения что бы остались только > и <.
 

ansol

Местный знаток
qqmber
Возможно, нужен просто "0" в следующем за Digits знаке?
Т.е. 1,2345601 проходит, а 1,234561 - нет?
Если double имеет точность 15 знаков, то "1" в 15 знаке, по идее, не влияет никак
Ugar
Да я понял! Я имею в виду не сравнение, а величину в OrderSend() - она должна проходить в случае Bid + i*Point и аналогичных.
А сравнение - да, на совести программера
 

Ugar

Гуру форума
qqmber
Возможно, нужен просто "0" в следующем за Digits знаке?
Т.е. 1,2345601 проходит, а 1,234561 - нет?
Если double имеет точность 15 знаков, то "1" в 15 знаке, по идее, не влияет никак
Ugar
Да я понял! Я имею в виду не сравнение, а величину в OrderSend() - она должна проходить в случае Bid + i*Point и аналогичных.
А сравнение - да, на совести программера
Думаю не сложно переписать строчки с OrderSend, OrderModify, OrderClose, засутув в них нормализе
 

Ugar

Гуру форума
Флаг в руки! В альпари не пойду! :D
А причём тут ДЦ? Это не особенность ДЦ, а особенность работы компьютера с дробными числами. Только в разных языках разная погрешность. Значит лажа может случиться в любом ДЦ. И как показывает практика, случается не редко.
2. Погрешности при работе с числами типа double


Специфика формата хранения чисел double в компьютере приводит к ограничению точности их хранения и возникновению погрешностей при работе с ними. Например, при использовании бесконечной точности вычислений, для любых действительных чисел A и B всегда будут справедливы тождества:
(A/B)*(B)=A,
A-(A/B)*B=0,
(A/B)*(B/A)=1 и т.п.
В компьютере точность хранения количества десятичных знаков чисел типа double определяется размерами мантиссы и ограничена 52 битами.
 
Последнее редактирование:

ansol

Местный знаток
Да, именно так.
Это не зависит от ДЦ, только от МТ.
Странно, что сервер отвергает запрос вместо того чтобы округлить.
Странно, что терминал не округляет при том, что "знает" что сервер такой запрос не пропустит :D
Хреновые они все-таки программисты.
Ugar

Есть два числа с 5 знаками после запятой. Их сложили. С чего ради у терминала получится 6 знаков? А вот если тебе вместо 5 знаков в цене подсунул ДЦ 6 злонамеренно, как я выше описал, а потом свою же цену и не принимает, то это виноват только ДЦ!
 
Последнее редактирование модератором:

qqmber

Почетный гражданин
Странно, что сервер отвергает запрос вместо того чтобы округлить.
Странно, что терминал не округляет при том, что "знает" что сервер такой запрос не пропустит :D
Хреновые они все-таки программисты.
Кривую цену отпинывает сам терминал. На сервер она не уходит. Хреновые программисты по обе стороны терминала.
 

ansol

Местный знаток
Кривую цену отпинывает сам терминал. На сервер она не уходит. Хреновые программисты по обе стороны терминала.

Кстати, интересно, если переменную один раз "нормализовать", то она потом, после других операций, может стать снова ненормализованной?
А то может их сразу "на входе" объявить какими надо, не? ;)
 

qqmber

Почетный гражданин
Кстати, интересно, если переменную один раз "нормализовать", то она потом, после других операций, может стать снова ненормализованной?
Разумеется.
А то может их сразу "на входе" объявить какими надо, не? ;)
Не поможет.
Надо было разрабам специальный тип данных для цен придумать, а не держать все в double.
 

Ugar

Гуру форума
Есть два числа с 5 знаками после запятой. Их сложили. С чего ради у терминала получится 6 знаков? А вот если тебе вместо 5 знаков в цене подсунул ДЦ 6 злонамеренно, как я выше описал, а потом свою же цену и не принимает, то это виноват только ДЦ!
Это был просто пример из статьи. Не о делении речь, а о погрешности представления дробных чисел. В терминале они 15 значные. В 15 знаке погрешность.
Число 1.33453 в темринале 15 значное 1.33453000000000. Так вот может на самом деле оказаться, с погрешностью 1.33453000000001.
При сложении двух чисел с погрешностью в 15 знаке, результат будет то же с погрешностью.
Если ДЦ подсовывает вместо 5 знаков 6 это конечно лажа. Но я такого не замечал может потому что оперирую везде значениями с учётом погрешностей.
 
Последнее редактирование модератором:
Верх