Ошибки, баги, вопросы - страница 1380

 

Извечная тема даблов =)

Прошу разработчиков добавить две стандартные функции.

Предлагаю следующую спецификацию:

====

Rp

Функция возвращает значение, которое будет выровнено на шаг цены по инструменту.

double  Rp(

   string    symbol_name,      // имя символа
   double  value                   // цена, которую надо выровнять
   );

Параметры

symbol_name

[in]  Символ.

value

[in]  Положительное число.

Возвращаемое значение

Ближайшее число, округлённое до шага цены торгового инструмента.

...

Пример:

Входные значения:

symbol_name = ES-...

value = 2000,55

на выходе = 2000,50

(шаг цены по инструменту ES = 0.25)


Входные значения:

symbol_name = SPX

value = 2000,55

на выходе = 2000,63

(на инструменте SPX шаг цены тоже 0,25, как и на ES, но при этом, существует базовое смещение и котировка может иметь только следующие дробные части -- 13,38,63,88).


Входные значения:

symbol_name = RTS

value = 82055,55

на выходе = 82060

(шаг цены по инструменту RTS = 10)

...Ну и так далее.


Вторая функция, которая меня интересует ещё больше:

====

Rv

Функция возвращает значение, которое будет выровнено на шаг объёма по инструменту и будет находиться в пределах от SYMBOL_VOLUME_MIN до SYMBOL_VOLUME_MAX.

double  Rv(

   string    symbol_name,      // имя символа
   double  value                   // лот, который надо выровнять
   );

Параметры

symbol_name

[in]  Символ.

value

[in]  Положительное число.

Возвращаемое значение

Ближайшее число, округлённое до шага объёма торгового инструмента. Число не будет больше SYMBOL_VOLUME_MAX и не будет меньше SYMBOL_VOLUME_MIN.

...

======


Главное свойство, которого я жду от этих функций - они должны быть валидны для ВСЕХ ТОРГОВЫХ ИНСТРУМЕНТОВ В МИРЕ и ДЛЯ ЛЮБЫХ ВХОДНЫХ ЗНАЧЕНИЙ.

Если у кого-то есть готовое решение, поделитесь пожалуйста, пока разработчики сделают.

Странно, что до сих пор нет таких =/

 

Решая задачу из своего камента ваше накатал тупейшую и топорную функцию, но даже она косячит для многих входных значений.

Код функции:

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 Возвращает кол-во значимых цифр после запятой
 вернёт 0 если число без значимой десятичной дробной части
 вернёт -1 в случае ошибки во время разбора строки на массив
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
int GetDigits(double n)
{
   ushort array[];
   string st=(string)n;                                        // явным образом формируем строку из числа
   int len=StringLen(st);
   if(len<3) return(0);                                        // число не может быть дробным если строка получилась меньше трёх символов
   if(StringToShortArray(st,array)!=len+1) return(-1);         // разбираем строку на массив символов
   for(int i=0;i<len;i++) if(array[i]=='.') return(len-i-1);   // ищем в строке точку и если она есть, возвращаем кол-во символов от точки до конца строки
   return(0);
}

Смысл в том, что я тупо переложил весь гемор определения значимой части дробного числа на тот метод, который подставляет компилятор вместо оператора =(string).

Но, оказывается, в таком виде код форматирует строку почти как g-тип из printf(), то есть для длинных дробей строку выводит в научном формате.

Как бы так добиться для любого n вывод в строку без экспоненциального формата и без лишних цифр справа и без гемороя =)?

И ещё вопрос: всегда десятичная дробь разделяется точкой или по дефолту из системных настроек может быть запятая или ещё что?

 
Fry:

Решая задачу из своего камента ваше накатал тупейшую и топорную функцию, но даже она косячит для многих входных значений.

Код функции:

Смысл в том, что я тупо переложил весь гемор определения значимой части дробного числа на тот метод, который подставляет компилятор вместо оператора =(string).

Но, оказывается, в таком виде код форматирует строку почти как g-тип из printf(), то есть для длинных дробей строку выводит в научном формате.

Как бы так добиться для любого n вывод в строку без экспоненциального формата и без лишних цифр справа и без гемороя =)?

И ещё вопрос: всегда десятичная дробь разделяется точкой или по дефолту из системных настроек может быть запятая или ещё что?

А чем Вас Point(), Digits  не устраивает ???
 
Vladimir Pastushak:
А чем Вас Point(), Digits  не устраивает ???

Пусть ещё будет хотя бы DigitsLot(), которая вернёт точность шага объёма.

Возможно, я не понял Ваш намёк. Есть какой-то разумный способ получить искомое через Point() или Digits()?


И всё-таки, очень нужны те две функции, которые я описал выше (валидные ровнялки для цены и для лота).

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

Инструментов всё больше. Уже не работают все поделки-самоделки, которые не допускают целым числом шаг лота. Кто сказал, что не буде минимального лота, допустим, в одну четверть? Да мало ли вариантов.

Это решение должно быть от разработчиков или абсолютное (для всех значений) иначе ему доверять нельзя.


А про котировку. Когда отправляешь заявку сервер-то принимает даже не ровные значения цены, лишь бы нормализовать (обрезать по знакам), но есть ведь и другие задачи.

Согласитесь, что надо иметь возможность получать из любого числа реально возможную котировку на любом инструменте, а не фигню подрезанную.

 
Fry:

Решая задачу из своего камента ваше накатал тупейшую и топорную функцию, но даже она косячит для многих входных значений.

Код функции:

...
Исправляю сам себя. Эта вроде бы работает:
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
Возвращает кол-во значимых цифр после запятой для чисел с точностью до 8 знаков 
   Вернёт 0 если число целое (в пределах 8 знаков после запятой) 
   Вернёт -1 в случае ошибки во время разбора строки на массив
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
int GetDigits(double n)
{
   ushort array[];
   if(StringToShortArray(StringFormat("%.8f",n),array)<10) return(-1); // число в строку и разбираем строку на массив символов
   int r=ArraySize(array)-2;                                           // размер массива минус ноль-терминатор и минус нулевая база указателя 
   for(;r>0 && array[r]=='0';r--);                                     // ищем справа не ноль
   for(int l=0;l<=r;l++) if(array[l]=='.') return(r-l);                // ищем слева точку и если она есть, возвращаем кол-во символов от точки до не нуля справа
   return(0);
}

Не подумайте, что я совсем уж дурной, так упорно из числа делаю строку ради чисто математической задачи.

Сначала честно попробовал сделать через логарифм, но глючно вышло до безобразия =(

 
Fry:
Исправляю сам себя. Эта вроде бы работает:

Не подумайте, что я совсем уж дурной, так упорно из числа делаю строку ради чисто математической задачи.

Сначала честно попробовал сделать через логарифм, но глючно вышло до безобразия =(

Еще раз спрошу на всякий случай, чем Вас не устраивает  NormalizeDouble()  _Point  _Digits    ????????

Зачем Вы создаете велосипед ?

 
Vladimir Pastushak:

Еще раз спрошу на всякий случай, чем Вас не устраивает  NormalizeDouble()  _Point  _Digits    ????????

Зачем Вы создаете велосипед ?

Ещё раз отвечу на всякий случай. Объясните мне, пожалуйста, как узнать точность SYMBOL_VOLUME_STEP с помощью "NormalizeDouble()  _Point  _Digits"?

Или как получить из любого положительного числа значение кратное SYMBOL_VOLUME_STEP?

Как получить следующий результат:

2000.55 (символ ES) -----> 2000.50

2000.55 (cимвол SPX) -----> 2000.63

1055.5555 (символ RTS) ------> 1060

для любого символа в мире, который доступен в терминале MT5 сегодня (и желательно завтра)

"????????"

Разработчики могут добавить всего 2 функции и дорабатывать их по мере развития терминала, а я не знаю всех особенностей разных торговых инструментов. Где я могу узнать, какие котировки вообще бывают? А мне надо получить именно КОТИРОВКУ, а не результат NormalizeDouble().

Если этот велосипед уже есть - ткните в конкретную реализацию, буду признателен. То что нашёл сам уже сейчас не работает на некоторых символах.

 
Fry:

...

2000.55 (символ ES) -----> 2000.50

2000.55 (cимвол SPX) -----> 2000.63

1055.5555 (символ RTS) ------> 1060

...

Пожалуйста покажите SYMBOL_VOLUME_STEP для этих трёх символов.
 
Karputov Vladimir:
Пожалуйста покажите SYMBOL_VOLUME_STEP для этих трёх символов.

0.01 для ES

0.1 для SPX

1 для RTS

Ещё раз - у меня 2 разные задачи:

1-я задача - выравнивать объём для любого инструмента в мире.

2-я задача - из числа получить котировку для любого инструмента в мире.

Про первую задачу. Я не знаю где получить информацию о том, какие в принципе бывают значения у SYMBOL_VOLUME_STEP.

То что лично мне встретились 1 и 0.1 и 0.01 - это не аргумент, что всегда будет только так.  Кто сказал, что нет, допустим, 0.25 или 0.5?


Про вторую задачу. Не знаю как получить смещение. Мне только один раз встретился такой хитрый случай с котировкой с шагом цены 0.13, 0.38, 0.63, 0.88. Но где гарантия, что это единичное исключение?

Неужели, чтобы из числа получить точную котировку в терминале надо обязательно стать экспертом по всем инструментам в мире? Почему это должно быть моей проблемой?

 
Fry:

...

Про первую задачу. Я не знаю где получить информацию о том, какие в принципе бывают значения у SYMBOL_VOLUME_STEP.

...

Переберите все инструменты в обзоре рынка и получите для каждого SYMBOL_VOLUME_STEP. Потом проделайте такую операцию на другом торговом сервере. И так, пока не обойдёте весь мир. 

После этого Вы будете знать какие значения SYMBOL_VOLUME_STEP вообще существуют в мире.