Библиотеки: CDouble & CDoubleVector - страница 2

 
Alain Verleyen:
Хороший улов. Однако с торговой точки зрения вам нужно либо 1,70060, либо 1,70061, они оба верны. Так что, возможно, вы захотите выбрать лучший вариант в соответствии с вашими торговыми операциями, а не полагаться на математическую схему округления.

В данном сценарии, если ваш размер шага == 0,00001, то в результате вы должны получить только 1,70061, а значение 1,70060 будет близким, но неверным.

 
nicholishen:

В этом сценарии, если размер шага == 0.00001, то в результате вы должны получить только 1.70061, а значение 1.70060 близко, но неверно.

Извините, но я не понимаю ваших рассуждений. Что такое "размер шага"?

 
Alain Verleyen:

Извините, но я не понимаю ваших рассуждений. Что такое "размер шага"?

step-size - это значение шага, до которого вы округляете. например, lot_step = 0.01 (2 цифры), или tick_size = 0.00005...


В данном примере мы работаем с 5-значным символом с тик-сайзом == 0.00001

 
nicholishen:

step-size - это значение шага, до которого вы округляете. например, lot_step = 0.01 (2 цифры), или tick_size = 0.00005...


В данном примере мы работаем с 5-значным символом с тик-сайзом == 0,00001.

Итак, размер шага равен размеру тика. Это все еще не говорит мне, почему с точки зрения торговли расчетная цена, такая как 1.700605, не может быть "округлена" (независимо от математического/кодировочного способа) до 1.70060?
[Удален]  
Alain Verleyen: Итак, размер шага равен размеру тика. Это все еще не говорит мне, почему с торговой точки зрения расчетная цена, такая как 1.700605, не может быть "округлена" (независимо от математического/кодировочного способа) до 1.70060?

Пожалуйста, поймите, что "торговая точка зрения" здесь не имеет значения. Это чисто математический вопрос, для которого @amrali предоставил решение.

Нет необходимости обсуждать "торговую точку зрения" здесь, так как это не по теме этой темы и в конечном итоге перерастет в еще один жаркий спор, который закончится тем, что кто-то снова будет забанен. Поэтому, пожалуйста, постарайтесь избежать этого!

 
Fernando Carreiro:

Пожалуйста, поймите, что "торговая точка зрения" здесь не уместна. Это чисто математический вопрос, для которого @amrali предоставил решение.

Нет необходимости обсуждать здесь "торговую точку зрения", так как это не относится к данной теме и в конечном итоге перерастет в еще одну жаркую дискуссию, в результате которой кто-то снова будет забанен. Поэтому, пожалуйста, постарайтесь избежать этого!

Я просто пытаюсь понять, что сказал @nicholishen. Нет никаких причин для жарких дебатов или чего-то еще. Это форум о торговле, не так ли?

Пожалуйста, объясните мне, почему из расчетной цены 1.700605, реальная цена 1.70060 является "неправильной"? Если я что-то упускаю, я хотел бы это понять.

 
Alain Verleyen:

Я просто пытаюсь понять, что сказал @nicholishen. Нет причин для жарких дебатов или чего-то еще. Это форум о торговле, не так ли?

Пожалуйста, объясните мне, почему из расчетной цены 1.700605, реальная цена 1.70060 является "неправильной"? Если я что-то упускаю, я хотел бы это понять.

Как сказал Фернандо, "это чисто математический вопрос", и в математическом смысле ожидаемый результат - округление 5 до ближайшей цифры вверх, а не вниз. Функция MathRound дает противоречивые результаты, и если вы хотите избежать несоответствия, я бы посоветовал использовать ND вместо нее, как мудро предложил @amrali. Чтобы вернуть нас всех к теме, библиотека CDouble больше не использует функцию MathRound в пользу более последовательных результатов.

 
Alain Verleyen:

Я просто пытаюсь понять, что сказал @nicholishen. Нет причин для жарких дебатов или чего-то еще. Это форум о торговле, не так ли?

Пожалуйста, объясните мне, почему из расчетной цены 1.700605, реальная цена 1.70060 является "неправильной"? Если я что-то упускаю, я хотел бы понять это.

Здравствуйте, Ален Верлейен, вы правы в том, что касается вашей точки зрения. Для одного расчета это может не иметь большого значения. Однако по мере выполнения большего количества вычислений, включающих округление на каждом шаге, итоговая ошибка будет увеличиваться. Рассмотрим стратегию мартингейла, в которой каждый рассчитанный размер лота вытекает из предыдущего (который был отправлен на торговый сервер в виде округленного значения). Проблема, которую мы здесь рассматриваем, называется "Распространение ошибок". Поэтому, на мой взгляд, было бы безопаснее использовать NormalizeDouble(), чтобы промежуточные ошибки были как можно меньше.

Во-вторых, здесь есть и более технический момент. При использовании функции MathRound(number * power) / power с числами edge вы получите либо верхнее округленное значение, либо нижнее, в зависимости от входных данных. Эта несогласованность в округлении может не иметь значения с точки зрения торговли, как вы упомянули в своем комментарии, пока вы получаете окончательное округленное значение (либо вверх, либо вниз), поэтому торговый сервер не будет жаловаться. Однако, как отметил Марк Уоткин, такая непоследовательность в округлении может внести труднообнаруживаемые ошибки в клиентский код, использующий библиотеку "CDouble".

Кстати, при использовании другого варианта вышеприведенной функции , например MathRound(number / point) * point с крайними числами, вы получаете округленное число (либо вверх, либо вниз), или, что еще интереснее, не получаете точного округленного числа! (результат отличается от ожидаемого значения на 1 эпсилон, но это нормально для торговых функций).

Следующий скрипт помогает продемонстрировать эти проблемы более наглядно:

#property strict

#define  PRINT(A) Print(#A + " = ", (A))

//+------------------------------------------------------------------+
//||
//+------------------------------------------------------------------+
// противоречивые результаты MathRound() с краевыми числами

void OnStart()
{
    // округляем цены наполовину до ближайших 5 десятичных цифр

    PRINT(MathRound(1.248825 * 100000) / 100000 == 1.24883);    // true, цена округляется в большую сторону (как и ожидалось)
    PRINT(MathRound(1.248835 * 100000) / 100000 == 1.24883);    // true, в этот раз цена округляется в меньшую сторону
    PRINT(MathRound(1.248845 * 100000) / 100000 == 1.24885);    // true, цена округляется в большую сторону.

    // второй вариант MathRound()

    PRINT(MathRound(1.248825 / 0.00001) * 0.00001 == 1.24883);   // true, цена округляется в большую сторону (как и ожидалось)
    PRINT(MathRound(1.248835 / 0.00001) * 0.00001 == 1.24883);   // true, на этот раз цена округляется в меньшую сторону
    PRINT(MathRound(1.248845 / 0.00001) * 0.00001 == 1.24885);   // false, то цена точно не округляется!!!
    PRINT(MathRound(1.248845 / 0.00001) * 0.00001 == 1.24884);   // false, та же цена не округляется в меньшую сторону!
    PRINT(MathRound(1.248845 / 0.00001) * 0.00001 == 1.2488400000000001);   // true, но это нормально для торговых функций. 
}

Поэтому лучше заменить MathRound(number) на NormalizeDouble(number, 0) , чтобы избежать противоречивых результатов при арифметическом округлении (округлении по средней точке).

Другая хорошая альтернатива для округления по средней точке: использовать MathRound() + применить коррекцию полуэпсилон.

(Это было реализовано в функцииMathRoundCorrect(), о чем уже писалось ранее).

double MathRoundCorrect(double num, int precision) {
        double c = 0.5 * DBL_EPSILON * num;
// double p = MathPow(10, precision); //slow
        double p = 1; while (precision--> 0) p *= 10;
        if (num < 0)
                p *= -1;
        return MathRound((num + c) * p) / p;
}

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

https://en.wikipedia.org/wiki/Rounding

Rounding - Wikipedia
Rounding - Wikipedia
  • en.wikipedia.org
Graphs of the result, y, of rounding x using different methods. For clarity, the graphs are shown displaced from integer y values. In the SVG file, hover over a method to highlight it and, in SMIL-enabled browsers, click to select or deselect it. Rounding a numerical value means replacing it by another value that is approximately equal but has...