Почему double, а не decimal?
Atom Ответить
31.10.2010


Заинтересовал вопрос, почему параметры в double а не decimal, у которого фиксированная точка?



Спасибо:




40 Ответов
1 2  >
Mikhail Sukhov

Фотография
Автор статей Программист Трейдер
Дата: 31.10.2010
Ответить


Андрей Ефимов
Заинтересовал вопрос, почему параметры в double а не decimal, у которого фиксированная точка?


Избежать лишней конвертации при интеграции с другими системами.
Спасибо:

Mikhail Sukhov

Фотография
Автор статей Программист Трейдер
Дата: 22.02.2011
Ответить


Андрей Ефимов Перейти
Заинтересовал вопрос, почему параметры в double а не decimal, у которого фиксированная точка?


В итоге, после 3-ем месяцев осмысления, я понял - переводу на decimal быть. Сейчас это сделано в отдельной ветке S#, и появиться скорее всего, в 3.1.
Спасибо:

anothar

Фотография
Дата: 25.02.2011
Ответить


Smile Замечательно-все будет очень точно)))
Автор топика
Спасибо:

Alexander

Фотография
Дата: 14.03.2011
Ответить


А ведь ни цены, ни объём не могут быть отрицательными.
Почему бы не использовать для цен тот же самый Decimal, а для объёмов ulong?
Спасибо:

Mikhail Sukhov

Фотография
Автор статей Программист Трейдер
Дата: 17.03.2011
Ответить


Alexander Перейти
А ведь ни цены, ни объём не могут быть отрицательными.
Почему бы не использовать для цен тот же самый Decimal, а для объёмов ulong?


Потому что не CLS compliant.
Спасибо:

Иванов Андрей

Фотография
Дата: 20.03.2011
Ответить


Alexander Перейти
А ведь ни цены, ни объём не могут быть отрицательными.
Почему бы не использовать для цен тот же самый Decimal, а для объёмов ulong?

А зачем ulong?! =) Я думаю, что даже у американцев не бывает таких сделок, чтобы они в int не поместились =) Аккумуляторы вы можете использовать такие, какие посчитаете нужным.

Mikhail Sukhov Перейти
Андрей Ефимов Перейти
Заинтересовал вопрос, почему параметры в double а не decimal, у которого фиксированная точка?


В итоге, после 3-ем месяцев осмысления, я понял - переводу на decimal быть. Сейчас это сделано в отдельной ветке S#, и появиться скорее всего, в 3.1.

Зачем?! =) О какой точности идёт речь?! Точность double 15 знаков, где можно использовать бОльшую точность? Пока вы складываете и умножаете, разницы между double и decimal не будет. Сбер в пятницу на ММВБ наторговался на 24 876 860 765, это 11 знаков. То есть, чтобы добраться до ошибки, вам надо будет суммировать данные за 2000 дней. Если вы при этом перейдёте на decimal, вы получите ещё один порядок. С точки зрения обывателя это много, относительно исследуемых цифр мало -- когда у вас уже использовано 14 порядков, лишний порядок ничего не даст.

Точность у decimal выше, а ёмкость целой части такая же =) Сказки про использование decimal как решение под точные расчёты для детского сада. Потому что если бездумно делить, ошибка будет огромная и с decimal. Использовать decimal обычно неразумно -- он медленнее, больше ест памяти и не даёт ничего, кроме дополнительного порядка или двух ёмкости. Дополнительная ёмкость имеет смысл для агрегирования, ну так и используйте decimal в агрегировании за безумные интервалы. Хотя я бы в этой ситуации всё равно использовал double под промежуточные расчёты с агрегированием в ulong (20 знаков).
Спасибо:

Mikhail Sukhov

Фотография
Автор статей Программист Трейдер
Дата: 20.03.2011
Ответить


Иванов Андрей Перейти

Зачем?! =) О какой точности идёт речь?! Точность double 15 знаков, где можно использовать бОльшую точность? Пока вы складываете и умножаете, разницы между double и decimal не будет. Сбер в пятницу на ММВБ наторговался на 24 876 860 765, это 11 знаков. То есть, чтобы добраться до ошибки, вам надо будет суммировать данные за 2000 дней. Если вы при этом перейдёте на decimal, вы получите ещё один порядок. С точки зрения обывателя это много, относительно исследуемых цифр мало -- когда у вас уже использовано 14 порядков, лишний порядок ничего не даст.


Мне нравиться вот этот пост http://www.rsdn.ru/forum/cpp/2640596.1.aspx Скажем, если бы я писал графическое приложение, где бы вычислял координаты - да тут точность не так важна. В случае с торговым приложение - очень важно чтобы цена были точной. Как минимум, чтобы не получить ошибку при регистрации заявок. Поэтому все всегда приходится вызывать ShrinkPrice чтобы гарантировать правильность подачи заявок.

С чем я сам столкнулся. 1 - когда я восстанавливаю стаканы из файла. Там я как раз умножаю на минимальный шаг + сдвиг от предыдущей котировкки. В итоге цена котировки 100.99999 вместо 101. 2 - когда я группирую стакан по ценовым уровня. Так же приходится округлять каждую строчку.

Иванов Андрей Перейти

Точность у decimal выше, а ёмкость целой части такая же =) Сказки про использование decimal как решение под точные расчёты для детского сада. Потому что если бездумно делить, ошибка будет огромная и с decimal. Использовать decimal обычно неразумно -- он медленнее, больше ест памяти и не даёт ничего, кроме дополнительного порядка или двух ёмкости.


Если цена вычисляется через математически формулы, то ей верить без округления нельзя. В итоге ShrinkPrice кушает как раз тот прирост, что дает double перед decimal. И еще чуть больше. Получается обратная ситуация - decimal быстрее перед double, потому что первый не нужно округлять.

И да, при современных-то компьютерам. У меня весь рынок можно уместить виртуально на персональный ПС. А вот заявки все равно скользят.
Спасибо: MaximMM

anothar

Фотография
Дата: 20.03.2011
Ответить


Иванов Андрей Перейти
Alexander Перейти
А ведь ни цены, ни объём не могут быть отрицательными.
Почему бы не использовать для цен тот же самый Decimal, а для объёмов ulong?

А зачем ulong?! =) Я думаю, что даже у американцев не бывает таких сделок, чтобы они в int не поместились =) Аккумуляторы вы можете использовать такие, какие посчитаете нужным.

Mikhail Sukhov Перейти
Андрей Ефимов Перейти
Заинтересовал вопрос, почему параметры в double а не decimal, у которого фиксированная точка?


В итоге, после 3-ем месяцев осмысления, я понял - переводу на decimal быть. Сейчас это сделано в отдельной ветке S#, и появиться скорее всего, в 3.1.

Зачем?! =) О какой точности идёт речь?! Точность double 15 знаков, где можно использовать бОльшую точность? Пока вы складываете и умножаете, разницы между double и decimal не будет. Сбер в пятницу на ММВБ наторговался на 24 876 860 765, это 11 знаков. То есть, чтобы добраться до ошибки, вам надо будет суммировать данные за 2000 дней. Если вы при этом перейдёте на decimal, вы получите ещё один порядок. С точки зрения обывателя это много, относительно исследуемых цифр мало -- когда у вас уже использовано 14 порядков, лишний порядок ничего не даст.

Точность у decimal выше, а ёмкость целой части такая же =) Сказки про использование decimal как решение под точные расчёты для детского сада. Потому что если бездумно делить, ошибка будет огромная и с decimal. Использовать decimal обычно неразумно -- он медленнее, больше ест памяти и не даёт ничего, кроме дополнительного порядка или двух ёмкости. Дополнительная ёмкость имеет смысл для агрегирования, ну так и используйте decimal в агрегировании за безумные интервалы. Хотя я бы в этой ситуации всё равно использовал double под промежуточные расчёты с агрегированием в ulong (20 знаков).

Если Вы не знали, то decimal создавался именно для финансовой математики. Он не нужен скажем для расчетов в играх (по хорошему там и float хватит) и дело тут в том, что у decimal и double разное представление. У decimal фиксированная целая и дробная часть. А вот с double проблема в том что фактически оно мало какие целые числа может представить( грубо говоря будет не целое число, а 0.999999) со всеми отсюда вытекающими последствиями.
Автор топика
Спасибо:

Иванов Андрей

Фотография
Дата: 21.03.2011
Ответить


Андрей Ефимов Перейти
Если Вы не знали, то decimal создавался именно для финансовой математики. Он не нужен скажем для расчетов в играх (по хорошему там и float хватит) и дело тут в том, что у decimal и double разное представление. У decimal фиксированная целая и дробная часть. А вот с double проблема в том что фактически оно мало какие целые числа может представить( грубо говоря будет не целое число, а 0.999999) со всеми отсюда вытекающими последствиями.

Если вы не знаете, как работает двоичное представление десятичных чисел на компьютере, советую поинтересоваться =) Пока точности double хватает, разницы с decimal нет. По ссылке Мхаила рассматриваются числа 1е-20 (разницы с 1е20 нет, к слову) и эти числа в decimal тоже не поместятся. Где на бирже такие числа? ;) Точность максимум 4-5 знаков у акций Эффективных Менеджеров ВТБ, а с учётом размера лота эти 4-5 знаков превращаются в обычные 1-2 знака.

decimal нужен там, где у вас большая целая часть и большая дробная. Попробуйте привести пример, где оно надо. Уверен, что decimal вам в этом случае не поможет.
Спасибо:

Иванов Андрей

Фотография
Дата: 21.03.2011
Ответить


Mikhail Sukhov Перейти
Иванов Андрей Перейти

Зачем?! =) О какой точности идёт речь?! Точность double 15 знаков, где можно использовать бОльшую точность? Пока вы складываете и умножаете, разницы между double и decimal не будет. Сбер в пятницу на ММВБ наторговался на 24 876 860 765, это 11 знаков. То есть, чтобы добраться до ошибки, вам надо будет суммировать данные за 2000 дней. Если вы при этом перейдёте на decimal, вы получите ещё один порядок. С точки зрения обывателя это много, относительно исследуемых цифр мало -- когда у вас уже использовано 14 порядков, лишний порядок ничего не даст.


Мне нравиться вот этот пост https://www.rsdn.ru/forum/cpp/2640596.1.aspx Скажем, если бы я писал графическое приложение, где бы вычислял координаты - да тут точность не так важна. В случае с торговым приложение - очень важно чтобы цена были точной. Как минимум, чтобы не получить ошибку при регистрации заявок. Поэтому все всегда приходится вызывать ShrinkPrice чтобы гарантировать правильность подачи заявок.

А что, с decimal что-то меняется? ;) Два лишних знака на 15 знаках не дают ничего =)
Про графическое приложение пример мимо цели ;) Я хоть и не писал графических приложений, но поверхностно в курсе про математику, там используемую. В MS Paint, без сомнений, хватит и short, а вот когда вам надо хранить освещённость точки от нуля до 50 знаков, decimal не поможет =)

Про пост на RSDN. Человек по вашей ссылке возмущается тому же, чему возмущаюсь я. Там кто-то написал, что double сравнивать нельзя, вы пишете, что decimal вам даст большую точность.

Цитата:

С чем я сам столкнулся. 1 - когда я восстанавливаю стаканы из файла. Там я как раз умножаю на минимальный шаг + сдвиг от предыдущей котировкки. В итоге цена котировки 100.99999 вместо 101. 2 - когда я группирую стакан по ценовым уровня. Так же приходится округлять каждую строчку.

Это в отладчике так показывается? ;) Попробуйте вывести на консоль то, что в отладчике показывается в виде 100.99999.
Не хотите разбираться с представлением чисел на компьютере, просто попробуйте. У вас число в примере четыре знака, представляя его в виде double или decimal, результат не изменится. Такие числа можно хоть в float хранить, с семью знаками, ничего не изменится. Просто смысла нет -- рантайм может его запросто хранить в 64 битах, хоть он и 32 бита, и процессор его наверняка будет считать в 64 битах. Если я неправ, покажите код или псевдокод, который приводит к 100.99999 в double и не приводит к тому же в decimal.

Цитата:

Иванов Андрей Перейти

Точность у decimal выше, а ёмкость целой части такая же =) Сказки про использование decimal как решение под точные расчёты для детского сада. Потому что если бездумно делить, ошибка будет огромная и с decimal. Использовать decimal обычно неразумно -- он медленнее, больше ест памяти и не даёт ничего, кроме дополнительного порядка или двух ёмкости.


Если цена вычисляется через математически формулы, то ей верить без округления нельзя.

Не поверите -- с decimal то же самое будет =) Его точность нужна там, где большая целая часть и большая дробная. То есть, число представляется в виде 25 знаков суммарно, например. 14 на целую, 11 на дробную. Да, такое число в виде double не представить, но где у вас такие числа? Если заниматься бездумной арифметикой, decimal не спасёт.

Цитата:
В итоге ShrinkPrice кушает как раз тот прирост, что дает double перед decimal. И еще чуть больше. Получается обратная ситуация - decimal быстрее перед double, потому что первый не нужно округлять.

И да, при современных-то компьютерам. У меня весь рынок можно уместить виртуально на персональный ПС. А вот заявки все равно скользят.

Файлы тоже медленно работают, по сравнению с быстрым процессором =)
Я не люблю рассуждения про современные компьютеры. Это странная причина для того, чтобы делать плохо, когда можно сделать хорошо и без напряжения.
Спасибо:

Mikhail Sukhov

Фотография
Автор статей Программист Трейдер
Дата: 21.03.2011
Ответить


Иванов Андрей Перейти

Не хотите разбираться с представлением чисел на компьютере, просто попробуйте. У вас число в примере четыре знака, представляя его в виде double или decimal, результат не изменится. Такие числа можно хоть в float хранить, с семью знаками, ничего не изменится. Просто смысла нет -- рантайм может его запросто хранить в 64 битах, хоть он и 32 бита, и процессор его наверняка будет считать в 64 битах.


Дело то не в максимальной размерности и точности после запятой. А в точности результирующего значения. Ему верить нельзя.

Иванов Андрей Перейти

Если я неправ, покажите код или псевдокод, который приводит к 100.99999 в double и не приводит к тому же в decimal.


Да легко:

Код
var priceF = 109.1;

for (var i = 0; i < 9; i++)
{
    priceF += 0.1 * i;
}

priceF /= 0.1;

if (priceF != 1127)
    throw new Exception();


Код

var priceD = 109.1m;

for (var i = 0; i < 9; i++)
{
    priceD += 0.1m * i;
}

priceD /= 0.1m;

if (priceD != 1127)
    throw new Exception();
Спасибо:

Иванов Андрей

Фотография
Дата: 21.03.2011
Ответить


Поставьте не 0.1, а 0.01, посмотрите, что получится.
Угадаете, чему будет равно Math.Round(2.5)? А вы в ShrinkPrice используете Math.Round =) Причина проскальзывания скорее здесь, а не в использовании double.
Это особенности представления вещественных чисел на компьютере, плата за скорость.

Я не понимаю, чем именно вас спасёт представление 0.1 как 0.1, а не как 0.10000000000000001 -- получение среднего арифметического двух цен, например, приводит к ошибке округления, которая всё равно заставляет использовать вашу функцию при выставлении заявки. И не такая уж она тяжёлая, эта ShrinkPrice, потому что выставлять заявки надо очень редко по сравнению с тем, сколько надо считать до выставления заявки.
Спасибо:

anothar

Фотография
Дата: 22.03.2011
Ответить


Иванов Андрей Перейти
Поставьте не 0.1, а 0.01, посмотрите, что получится.
Угадаете, чему будет равно Math.Round(2.5)? А вы в ShrinkPrice используете Math.Round =) Причина проскальзывания скорее здесь, а не в использовании double.
Это особенности представления вещественных чисел на компьютере, плата за скорость.

Я не понимаю, чем именно вас спасёт представление 0.1 как 0.1, а не как 0.10000000000000001 -- получение среднего арифметического двух цен, например, приводит к ошибке округления, которая всё равно заставляет использовать вашу функцию при выставлении заявки. И не такая уж она тяжёлая, эта ShrinkPrice, потому что выставлять заявки надо очень редко по сравнению с тем, сколько надо считать до выставления заявки.

Вот неплохой пост:http://stackoverflow.com/questions/803225/when-should-i-use-double-instead-of-decimal. В целом он повторяет Ваши мысли и мысли Михаила. Смысл примерно такой что для финансовых вычислений скорее всего больше подходит именно decimal(кроме тех случаев когда у Вас очень большой расчет) по той причине, которую указал Михаил, а для всех остальных double(или float)-но это как я понял.
Автор топика
Спасибо:

Mikhail Sukhov

Фотография
Автор статей Программист Трейдер
Дата: 22.03.2011
Ответить


Иванов Андрей Перейти
Поставьте не 0.1, а 0.01, посмотрите, что получится.
Угадаете, чему будет равно Math.Round(2.5)? А вы в ShrinkPrice используете Math.Round =) Причина проскальзывания скорее здесь, а не в использовании double.
Это особенности представления вещественных чисел на компьютере, плата за скорость.


При торговле в реальном времени что double что decimal не несет никакой разницы в производительности. Но мне приходится каждый раз делать округление, так как я не могу гарантировать в коде, что double будет сформирован правильно. То, что при 0.01 мой пример работает, а при 0.1 не работает - это еще хуже, чем если бы не работало всегда. Я не могу однозначность сказать - все будет работать. Поэтому лишняя перестраховка в виде выравнивания цены.

Иванов Андрей Перейти

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


Если я вычисляю сред арифметическое, то я точно знаю, что нужно округлять. И я точно знаю, что код, подобный моему примеру, не требует округления. Главное для меня, точно знать как будет работать. Я уже довольно много натыкался на грабли, когда код не работал банально из-за неточности double. Часами выискивал проблему, которая может и вообще сегодня не проявиться. А такая бага самая худшая, когда то работает, то нет (ваш пример с ИИС).

Иванов Андрей Перейти

И не такая уж она тяжёлая, эта ShrinkPrice, потому что выставлять заявки надо очень редко по сравнению с тем, сколько надо считать до выставления заявки.


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

Иванов Андрей

Фотография
Дата: 22.03.2011
Ответить


Mikhail Sukhov Перейти
Иванов Андрей Перейти
Поставьте не 0.1, а 0.01, посмотрите, что получится.
Угадаете, чему будет равно Math.Round(2.5)? А вы в ShrinkPrice используете Math.Round =) Причина проскальзывания скорее здесь, а не в использовании double.
Это особенности представления вещественных чисел на компьютере, плата за скорость.


При торговле в реальном времени что double что decimal не несет никакой разницы в производительности. Но мне приходится каждый раз делать округление, так как я не могу гарантировать в коде, что double будет сформирован правильно. То, что при 0.01 мой пример работает, а при 0.1 не работает - это еще хуже, чем если бы не работало всегда. Я не могу однозначность сказать - все будет работать. Поэтому лишняя перестраховка в виде выравнивания цены.

В интернетах есть мнение, что стандарт IEEE 754 убьёт мир =)
http://www.yur.ru/science/computer/IEEE754.htm

Лишняя перестраховка в виде выравнивания цены не хуже лишней перестраховки в виде decimal =)

Цитата:

Иванов Андрей Перейти

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


Если я вычисляю сред арифметическое, то я точно знаю, что нужно округлять. И я точно знаю, что код, подобный моему примеру, не требует округления. Главное для меня, точно знать как будет работать. Я уже довольно много натыкался на грабли, когда код не работал банально из-за неточности double. Часами выискивал проблему, которая может и вообще сегодня не проявиться. А такая бага самая худшая, когда то работает, то нет (ваш пример с ИИС).

В вашем примере надо тоже делать округление, потому что делите. Я думаю, что на всякий случай надо делать округление перед каждой заявкой, чтобы всё продолжало работать после внесения изменений в середину кода. Чтобы получалось слабое связывание.

Цитата:

Иванов Андрей Перейти

И не такая уж она тяжёлая, эта ShrinkPrice, потому что выставлять заявки надо очень редко по сравнению с тем, сколько надо считать до выставления заявки.


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

У меня половину времени занимает чтение лога сделок из файла. На истории [20 декабря, сейчас] по GMKN всё примерно 5.5 секунд, из них секунды 3 это чтение истории из файлов, мегабайтов 90 где-то. Для одного дня программа дольше запускается, чем работает. Вполне возможно, что я использую какие-то очень простые инструменты.

На decimal уже переделали или только планы? Любопытно было бы узнать, как они работают против double. То есть, прогнать одну и ту же стратегию с double и с decimal на месяце сделок. И скорость интересна, и прирост денег на торговле 1 млн без плеча. Если мой способ не подходит, то какой хотите использовать для оценки эффективности перехода? Вам же надо как-то оценивать вложенный труд.

Уверен, что decimal не принесёт денег, зато принесёт хлопоты.
Спасибо:

Mikhail Sukhov

Фотография
Автор статей Программист Трейдер
Дата: 22.03.2011
Ответить


Иванов Андрей Перейти
На decimal уже переделали или только планы? Любопытно было бы узнать, как они работают против double. То есть, прогнать одну и ту же стратегию с double и с decimal на месяце сделок. И скорость интересна, и прирост денег на торговле 1 млн без плеча. Если мой способ не подходит, то какой хотите использовать для оценки эффективности перехода? Вам же надо как-то оценивать вложенный труд.

Уверен, что decimal не принесёт денег, зато принесёт хлопоты.


Я уже переделал до 3.0 еще. Но это не выносил в публичную ветку. Получилось быстрее, потому что из своей стратегии я повыкидывал Shrink.
Спасибо:

Иванов Андрей

Фотография
Дата: 26.03.2011
Ответить


Андрей Ефимов Перейти
Иванов Андрей Перейти
Поставьте не 0.1, а 0.01, посмотрите, что получится.
Угадаете, чему будет равно Math.Round(2.5)? А вы в ShrinkPrice используете Math.Round =) Причина проскальзывания скорее здесь, а не в использовании double.
Это особенности представления вещественных чисел на компьютере, плата за скорость.

Я не понимаю, чем именно вас спасёт представление 0.1 как 0.1, а не как 0.10000000000000001 -- получение среднего арифметического двух цен, например, приводит к ошибке округления, которая всё равно заставляет использовать вашу функцию при выставлении заявки. И не такая уж она тяжёлая, эта ShrinkPrice, потому что выставлять заявки надо очень редко по сравнению с тем, сколько надо считать до выставления заявки.

Вот неплохой пост:https://stackoverflow.com/questions/803225/when-should-i-use-double-instead-of-decimal. В целом он повторяет Ваши мысли и мысли Михаила. Смысл примерно такой что для финансовых вычислений скорее всего больше подходит именно decimal(кроме тех случаев когда у Вас очень большой расчет) по той причине, которую указал Михаил, а для всех остальных double(или float)-но это как я понял.

Не совсем так. "Финансы" это слишком обще.

Когда вам надо суммировать операции по счетам клиентов, то выбора нет, только decimal. Потому что представить в double 0.1 (10 копеек), например, невозможно. Когда у вас есть арифметика (считаете проценты, например), то double обычно точнее и всегда значительно быстрее. В случае с роботами суммирование операций это вспомогательные вычисления, основные как раз разнообразная арифметика. Мне так кажется =)

По сути, это вопрос религии или требования к производительности -- сложив три раза 1/3 в decimal получишь 0.9999999999, а в double 1.0, но сложив 10 раз 0.1 для decimal будет 1.0 и 0.999999999 для double. То есть, округлять надо независимо от выбора представления и результат будет приемлемый в любом случае. А если бездумно делить, повторюсь в который раз, decimal не поможет.

Mikhail Sukhov Перейти
Иванов Андрей Перейти
На decimal уже переделали или только планы? Любопытно было бы узнать, как они работают против double. То есть, прогнать одну и ту же стратегию с double и с decimal на месяце сделок. И скорость интересна, и прирост денег на торговле 1 млн без плеча. Если мой способ не подходит, то какой хотите использовать для оценки эффективности перехода? Вам же надо как-то оценивать вложенный труд.

Уверен, что decimal не принесёт денег, зато принесёт хлопоты.


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

Хорошо. "Посмотрим, что скажет стая" =)
Интересно будет послушать про результаты -- стало быстрее и/или больше денег. Может быть выложить параллельно версию с decimal?
Спасибо:

Иванов Андрей

Фотография
Дата: 26.03.2011
Ответить


Исходя из описания и именования, я бы ShrinkPrice сделал вот таким.
Проверить мне его не на чем, но не вижу причин, почему бы ему не работать в несколько десятков раз быстрее.

Было
Код

public static double ShrinkPrice(this Security security, double price, ShrinkRules rule = ShrinkRules.Auto)
{
if (security == null)
throw new ArgumentNullException("security");
decimal num = (decimal) price;
decimal minStepSize = (decimal) security.MinStepSize;
if (minStepSize == 0M)
throw new ArgumentException("trololo");
return (double) num.Round(minStepSize, security.Decimals, ((rule == ShrinkRules.Auto) ? null : new MidpointRounding?((rule == ShrinkRules.Less) ? MidpointRounding.AwayFromZero : MidpointRounding.ToEven)));
}

Стало
Код

public static double ShrinkPrice(this Security security, double price, ShrinkRules rule = ShrinkRules.Auto)
{
    if (security == null)
        throw new ArgumentNullException("security");
    if (price <= 0.0)
        throw new ArgumentException("Получена цена меньше либо равная нулю.", "price");
    if (security.MinStepSize <= 0.0)
        throw new InvalidOperationException("Невозможно выровнять цену для инструмента без установленного минимального шага цены."); // security.MinStepSize не параметр метода
    price /= security.MinStepSize;
    if (rule == ShrinkRules.Auto)
        price = Math.Round(price, MidpointRounding.AwayFromZero);
    else if (rule == ShrinkRules.More)
        price = Math.Ceiling(price);
    else if (rule == ShrinkRules.Less)
        price = Math.Floor(price);
    else
        throw new ArgumentOutOfRangeException("rule", rule, "Получено неизвестное правило округления.");
    price *= security.MinStepSize;
    return price;
}

Спасибо:

anothar

Фотография
Дата: 26.03.2011
Ответить


Вот комментарий по производительности:Decimal perfomance
Если ему верить, то у decimal производительность не ахти. А что если внутри представлять все ввиде целого Int64? Ну а наружу-без разницы. ТО есть по сути будет такая структура: фиксированное число знаков после точки, которое зависит только от инструмента и значение ввиде Int64(например 0.0012-это четыре знака после точки и значение 12). Если Вы преимущественно складываете, делите и т.д в рамках одного инструмента то все ок, но насколько это извращенно? По сути это и есть идея того поста.
Автор топика
Спасибо:

Иванов Андрей

Фотография
Дата: 27.03.2011
Ответить


Это не будет быстрее double =) Зато будет больше места для ошибок. И голову надо под такое перестраивать, как под ассемблер.

Если вам не нужна точность за вашими знаками (среднее арифметическое между 0.0012 и 0.0015 при использовании long что даст?), double будет работать не хуже. Чтобы накопить в double ошибку в четвёртом знаке, надо несколько миллионов или десятков миллионов операций. Ошибка быстро накапливается, если используются значения из разных диапазонов -- цена какого-нибудь ИнтерРАО с лотом 100 тысяч и объём торгов за час. То есть, отличаться они должны на несколько порядков. Чем больше порядков различие, тем быстрее накапливается ошибка.
Спасибо:

Maxim

Фотография
Дата: 29.04.2011
Ответить


Поздно конечно пить боржомии...
Напишу основной минус, который вижу для себя.
Размер необходимой памяти для дабл в два раз больше.
И для хранения в SQL и для ОЗУ.

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

На текущий момент бэктестинг еле влезает в 8Гб ОЗУ.
Больше ОЗУ добавить низя. Нужен новый сервер.
Правда там же крутится SQL.

Крайне неохото разбивать процесс на этапы, что бы
оставаться на том же железе. Пока еще не перевел
все на decimal. Очень надеюсь, что все влезет.

Вначале пути тоже выбирал double или decimal.
Выбрал double исключительно из-за ОЗУ.

Это все так... Лирика.
Больше некому поплакаться, не поймут. RollEyes
Спасибо:

Mikhail Sukhov

Фотография
Автор статей Программист Трейдер
Дата: 29.04.2011
Ответить


Maxim Перейти
Поздно конечно пить боржомии...
Напишу основной минус, который вижу для себя.
Размер необходимой памяти для дабл в два раз больше.
И для хранения в SQL и для ОЗУ.


При тестировании на истории Sql не используется. Насчет занимаемой памяти я так и не понял, возросло с переходом на decimal или не возросло.
Спасибо:

Maxim

Фотография
Дата: 29.04.2011
Ответить


Данные для тестирования беру из SQL.
Результаты тестирования сохраняю в SQL.
SQL кушает порядка гигабайта.

Насчет того, насколько увеличилось потребление памяти
при переходе на decimal сейчас сказать не могу. Все еще
в процессе переделывания на новый лад. Как сделаю, напишу.
Перенос всей программы на decimal то еще увлекательное мероприятие :)

Но чисто теоретически, double занимает 8байт, decimal 16 байт.
71млн значений цены для сбера занимали ~500Мб, теперь должны занимать ~1000Мб.
Производных данных от цены меньше, но надо будет посмотреть сколько это все вместе
будет теперь занимать.

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

Пока все это писал, понял, что Вы скорей всего не поймете
моей ситуации, так как для этого надо более детально описывать
структуру моего торгового робота.

Проехали :)

Основная мысль, что переход на decimal для меня тот еще геморой.
А с другой стороны все устраивало на double.


Спасибо:

Alexander

Фотография
Дата: 29.04.2011
Ответить


Вот кстати сегодня тоже обнаружил что мой робот кушает 470мб оперативки.
Это работа с 4мя квиками (где берутся ленты и стаканы из каждого квика), и по 3 стратегии на каждом квике.

Не знаю много это или нет, т.к. не помню сколько было.
Спасибо: MaximMM

Maxim

Фотография
Дата: 30.04.2011
Ответить


Перевел на decimal.
Потребление ОЗУ увеличилось с 5.6Гб до 6.6Гб.
Пока что влажу в лимит.

Эх, все же придется задуматься об оптимизации алгоритмов.

Также замечу, что некоторые методы Math и DateTime не принимают Decimal.
Лишнее преобразование в Double :)

Спасибо:
1 2  >

Добавить файлы через драг-н-дроп, , или вставить из буфера обмена.

loading
clippy