Ошибка при чтении тиков из bin-хранилища, API 4.2.72
Atom Ответить
30.03.2015


Записал Гидрой данные из источника RTS (всё подряд за несколько лет). Пытаюсь прочитать (без разницы, через API 4.2.72 или самой Гидрой c библиотеками 4.2.71) - время от времени вылезает exception:

Error System.ArgumentException: Decimal byte array constructor requires an array of length four containing valid decimal bytes.
at System.Decimal.SetBits(Int32[] bits)
at StockSharp.Algo.Storages.MarketDataStorageHelper.ReadDecimal(BitArrayReader reader, Decimal prevPrice)
at StockSharp.Algo.Storages.MarketDataStorageHelper.ReadPriceEx[T](BitArrayReader reader, BinaryMetaInfo`1 info)
at StockSharp.Algo.Storages.TradeSerializer.MoveNext(MarketDataEnumerator enumerator)
at StockSharp.Algo.Storages.BinaryMarketDataSerializer`2.MarketDataEnumerator.MoveNext()
at StockSharp.Algo.Storages.StorageHelper.RangeEnumerable`1.RangeEnumerator.System.Collections.IEnumerator.MoveNext()
at System.Linq.Enumerable.WhereEnumerableIterator`1.MoveNext()
at StockSharp.Algo.Export.TextExporter.Do[TValue](IEnumerable`1 values, String templateName)
at Ecng.Common.Converter.<>c__DisplayClassf.<DoInCulture>b__e()
at Ecng.Common.Converter.DoInCulture[T](CultureInfo cultureInfo, Func`1 func)
at StockSharp.Algo.Export.BaseExporter.Export(Type dataType, IEnumerable values)
at StockSharp.Hydra.Controls.ExportProgress.<>c__DisplayClass6.<Start>b__4(Object s, DoWorkEventArgs e)
at System.ComponentModel.BackgroundWorker.WorkerThreadStart(Object argument)

На достаточно активных фьючах (RIZ4) такая ошибка появляется раз в несколько месяцев. В общем, прочитать полностью все сделки по конкретному фьючерсу удается редко.

Еще забавный баг в последней Гидре: почему-то разучилась создавать временные директории вида yyyy_MM_dd внутри \TemporaryFiles во время загрузки данных из RTS. Пишет ошибку "System.IO.DirectoryNotFoundException: Could not find a part of the path 'S:\Hydra\TemporaryFiles\2009_11_02\20091102.zip'". Насоздавал ей директорий вручную под каждую дату - всё завелось, она их даже удалила сама после использования.

Теги:


Спасибо:




23 Ответов
asuilin

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


В дополнение, если сохранять не в bin а в CSV, Гидра сыплет такими ошибками в процессе скачивания RTS:

RTS-CSV 31.03.2015 8:46:51 +03:00 Info Старт загрузки сделок за 24.05.2011.
RTS-CSV 31.03.2015 8:47:26 +03:00 Error System.InvalidCastException: Cannot convert with format HH:mm:ss.FFFFFF zzz to TimeSpan. ---> System.FormatException: String was not recognized as a valid DateTime.
at System.DateTimeOffset.ParseExact(String input, String format, IFormatProvider formatProvider, DateTimeStyles styles)
at Ecng.Common.TimeHelper.ToDateTimeOffset(String value, String format)
--- End of inner exception stack trace ---
at Ecng.Common.TimeHelper.ToDateTimeOffset(String value, String format)
at StockSharp.Algo.Storages.CsvMarketDataSerializer`1.ParseTime(String str, DateTime date)
at StockSharp.Algo.Storages.CsvMarketDataSerializer`1.CsvMetaInfo.<>c__DisplayClass15.<Read>b__14()
at Ecng.Common.Converter.<>c__DisplayClassf.<DoInCulture>b__e()
at Ecng.Common.Converter.DoInCulture[T](CultureInfo cultureInfo, Func`1 func)
at StockSharp.Algo.Storages.MarketDataStorage`2.GetInfo(Stream stream, DateTime date)
at StockSharp.Algo.Storages.MarketDataStorage`2.Save(IEnumerable`1 data)
at StockSharp.Hydra.Core.BaseHydraTask.SafeSave[T](Security security, Type messageType, Object arg, IEnumerable`1 values, Func`2 getTime, IEnumerable`1 getErrors, Func`4 getStorage)
RTS-CSV 31.03.2015 8:47:26 +03:00 Info Для SVM1@FORTS загружено 4019 ExecutionMessage (Tick).

Ошибок много, в среднем одна ошибка на 5 скачанных инструментов.

Следующим шагом попробую отказаться от Гидры и напрямую дергать за RtsHistorySource.LoadTrades, с собственными хранилищами. Открытый код в Algo.History облегчил бы задачу.
Автор топика
Спасибо:

Mikhail Sukhov

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


1. Какая версия Гидры.
2. Если битый файл удалить и повторно перезакачать, будет ли ошибка? Если да, то скажите дату и инструмент.
Спасибо:

asuilin

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


Mikhail Sukhov Перейти
1. Какая версия Гидры.
2. Если битый файл удалить и повторно перезакачать, будет ли ошибка? Если да, то скажите дату и инструмент.


1. 4.2.71
2. Ошибка возникает на любом инструменте с достаточно большим количеством трейдов. На RI/SI, например, мне редко удавалось прочитать без ошибки тиковую историю любого фьючерса за три месяца. С перезакачкой не очень понятно, Гидра же хранит где-то в недрах метаинформацию о том, что скачалось? Если просто удалить файлы и закачать заново, ничего не сломается?

Через RtsHistorySource вроде бы нормально заливается в память, т.е. проблема в хранилище.
Автор топика
Спасибо:

Mikhail Sukhov

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


asuilin Перейти
С перезакачкой не очень понятно, Гидра же хранит где-то в недрах метаинформацию о том, что скачалось? Если просто удалить файлы и закачать заново, ничего не сломается?


Можно просто удалить битые даты и сбросить кэш дат в Гидре. Или удалить этот файл вручную.
Спасибо:

asuilin

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


Кеш дат это tradesDates.bin?
Автор топика
Спасибо:

Mikhail Sukhov

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


Да
Спасибо:

asuilin

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


Михаил, а не могли бы вы публиковать отладочную информацию в NuGet? Хрен ведь поймешь, на какой конкретной дате оно спотыкается внутри итератора.
См. http://www.arturdr.ru/ne...i-av-infrastructure-web/ и https://docs.nuget.org/c...lishing-a-symbol-package
Автор топика
Спасибо:

asuilin

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


Перезакачка полечила одну битую дату, но не полечила другую. На RIZ4@FORTS для 2014_12_09 (9 декабря) данные остаются битыми после нескольких перезакачек. Файл приложу, если найду как это сделать.
Автор топика
Спасибо:

Mikhail Sukhov

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


asuilin Перейти
Перезакачка полечила одну битую дату, но не полечила другую. На RIZ4@FORTS для 2014_12_09 (9 декабря) данные остаются битыми после нескольких перезакачек. Файл приложу, если найду как это сделать.


Наверное не поняли. Надо удалить дату. Тоесть не перезаписывать файл, а новый создавать нужно.
Спасибо:

asuilin

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


Mikhail Sukhov Перейти

Наверное не поняли. Надо удалить дату. Тоесть не перезаписывать файл, а новый создавать нужно.

Да, конечно я так и делал. Под перезакачкой имелась в виду повторная заливка этой даты в Гидре.
Автор топика
Спасибо:

asuilin

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


Кажется, мне быстрее будет реализовать собственное хранилище, имплементирующее IMarketDataStorage. Проблема в том, что у него есть свойство IMarketDataDrive Drive, а у него, в свою очередь, есть IMarketDataStorageDrive GetStorageDrive(). А IMarketDataStorageDrive оперирует бинарыми данными и рассчитан на формат StockSharp.
Какой тогда смысл в этих интерфейсах, если ни с чем, кроме закрытого бинарного формата, они работать не могут? Или реализация GetStorageDrive() не обязательна и можно там сделать заглушку?

Автор топика
Спасибо:

Mikhail Sukhov

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


asuilin Перейти
Mikhail Sukhov Перейти

Наверное не поняли. Надо удалить дату. Тоесть не перезаписывать файл, а новый создавать нужно.

Да, конечно я так и делал. Под перезакачкой имелась в виду повторная заливка этой даты в Гидре.


Тоесть ошибка за 2014_12_09 по RIZ4 стабильно воспроизводится?
Спасибо:

asuilin

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


Mikhail Sukhov Перейти

Тоесть ошибка за 2014_12_09 по RIZ4 стабильно воспроизводится?


Да, у меня цикл удаляем - скачиваем - читаем - получаем ошибку воспроизвёлся раз пять. Вы бы посмотрели файлик то?
Автор топика
Спасибо:

Mikhail Sukhov

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


asuilin Перейти
Mikhail Sukhov Перейти

Тоесть ошибка за 2014_12_09 по RIZ4 стабильно воспроизводится?


Да, у меня цикл удаляем - скачиваем - читаем - получаем ошибку воспроизвёлся раз пять. Вы бы посмотрели файлик то?


Файл смотреть нет смысла. Есть смысл устранить проблему, если она есть. Попробовал Гидрой из Гита скачать за указанную дату. Скачалось и прочиталось. Все Гидрой. Попробуете последней с Гита? Я правильно понимаю, что вы выставили в настройках нужную дату, выбрали нужный инструмент и закачали 1 день? После этого попытались его прочитать.
Спасибо:

asuilin

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


Да, всё так и делал.
Написал тест, сгенерировал 1М трейдов, записал и прочитал - все отработало.
Сейчас пробую сделать всё без Гидры, напрямую через RtsHistorySource и запись трейдов в хранилище, вдруг заработает. Заодно это быстрее, чем Гидра, работающая в один поток. Вопрос - при записи/чтении трейды никак не переупорядочиваются по номеру тика? Т.е. если я запишу сначала вечерние трейды за день, а потом утренние, они и читаться будут в том же порядке?

Кстати, посмотрел, что Гидра записала в CSV формат - во всех трейдах пустые даты. Не зря она сыпала ошибками, сама с собой не где то смогла договориться о формате дат в строках.
Автор топика
Спасибо:

Mikhail Sukhov

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


Вы не поняли. Надо через гидру.
Спасибо:

asuilin

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


Mikhail Sukhov Перейти
Вы не поняли. Надо через гидру.


Мне не надо через Гидру, мне надо решить мою простейшую задачу - загрузить и прочитать данные RTS. Через код ее оказалось удобнее и быстрее решать, Гидра дергает за те же классы, какая разница.
Итак, более детальное тестирование показало, что сбой в конкретной дате зависит от того, загружались ли следующие даты. Пример - при загрузке 17 марта 2015 и 18 марта сбоит чтение фьючерса GDM5 за 17 марта. При загрузке только 17 марта все ОК. Возможно, в следующем дне догружаются какие-то хвосты от предыдущего и неудачно дописываются в конец файла.

Тестировалось на версии API 4.2.75, которая датируется в NuGet 1 апреля, т.е. свежак.
Код теста прилагаю, попробуйте запустить у себя. Сначала надо загрузить пакеты из NuGet (Manage Nuget Packages) и поправить в коде пути для загрузки.
StorageTest.zip 9 KB (1)
Автор топика
Спасибо:

Mikhail Sukhov

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


asuilin Перейти
Mikhail Sukhov Перейти
Вы не поняли. Надо через гидру.


Мне не надо через Гидру


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

asuilin

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


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

Mikhail Sukhov

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


Я попробовал ваши шаги. О результатах отписал выше.
Спасибо:

asuilin

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


Mikhail Sukhov Перейти
Я попробовал ваши шаги. О результатах отписал выше.

Именно поэтому я сделал тест, работающий в изолированных стерильных условиях, чтобы ошибка была более воспроизводимой. Ошибка ведь в хранилище, а не в Гидре, значит хранилище и надо тестировать, без десятка дополнительных слоёв кода вокруг.

Вообще, по всем правилам здравого смысла продукт уровня StockSharp, тем более работающий с крупными деньгами, должен быть покрыт функциональными и unit тестами вдоль и поперёк. Их абсолютное отсутствие на GitHub и стремление искать ошибки вручную через интерфейс Гидры порождает вопросы...
Автор топика
Спасибо:

asuilin

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


Моя версия с багом дозаписи в .bin файл подтвердилась.
RTSHistorySource возвращает сделки не только за заданный день, но и небольшой хвост от предыдущего дня - не разбирался почему, возможно так устроены данные FORTS. Этот хвост дописывается в хранилище предыдущего дня, в котором уже есть данные, и где-то в этом месте нарушается структура хранилища.
Если перед записью отфильтровать этот хвост, т.е. записывать за один раз данные строго одного дня, то все работает. Все фьючерсы RTS за месяц прекрасно записались и прочитались.
Михаил, все вводные данные у вас есть, можете исправлять баг, можете нет, дело ваше. Я буду делать свой сторадж на SQLite, так надёжнее и проще в поддержке.

Автор топика
Спасибо:

Mikhail Sukhov

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


asuilin Перейти
должен быть покрыт функциональными и unit тестами вдоль и поперёк. Их абсолютное отсутствие на GitHub и стремление искать ошибки вручную через интерфейс Гидры порождает вопросы...


Вас кто-то останавливает? https://stocksharp.ru/fo...estnaia-rabota-v-GitHub/
Спасибо:


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

loading
clippy