← Zurück

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

Записал Гидрой данные из источника 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(BitArrayReader reader, BinaryMetaInfo1 info) at StockSharp.Algo.Storages.TradeSerializer.MoveNext(MarketDataEnumerator enumerator) at StockSharp.Algo.Storages.BinaryMarketDataSerializer2.MarketDataEnumerator.MoveNext() at StockSharp.Algo.Storages.StorageHelper.RangeEnumerable1.RangeEnumerator.System.Collections.IEnumerator.MoveNext() at System.Linq.Enumerable.WhereEnumerableIterator1.MoveNext() at StockSharp.Algo.Export.TextExporter.Do[TValue](IEnumerable1 values, String templateName) at Ecng.Common.Converter.<>c__DisplayClassf.<DoInCulture>b__e() at Ecng.Common.Converter.DoInCulture(CultureInfo cultureInfo, Func1 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'". Насоздавал ей директорий вручную под каждую дату - всё завелось, она их даже удалила сама после использования.

War dieses Thema hilfreich?

Thema teilen

Kommentare (23)

Anmelden oder Konto erstellen, Melden Sie sich an oder registrieren Sie sich, um einen Kommentar zu hinterlassen

asuilin
asuilin Autor

В дополнение, если сохранять не в 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.CsvMarketDataSerializer1.ParseTime(String str, DateTime date) at StockSharp.Algo.Storages.CsvMarketDataSerializer1.CsvMetaInfo.<>c__DisplayClass15.<Read>b__14() at Ecng.Common.Converter.<>c__DisplayClassf.<DoInCulture>b__e() at Ecng.Common.Converter.DoInCulture(CultureInfo cultureInfo, Func1 func) at StockSharp.Algo.Storages.MarketDataStorage2.GetInfo(Stream stream, DateTime date) at StockSharp.Algo.Storages.MarketDataStorage2.Save(IEnumerable1 data) at StockSharp.Hydra.Core.BaseHydraTask.SafeSave(Security security, Type messageType, Object arg, IEnumerable1 values, Func2 getTime, IEnumerable1 getErrors, Func4 getStorage) RTS-CSV 31.03.2015 8:47:26 +03:00 Info Для SVM1@FORTS загружено 4019 ExecutionMessage (Tick).

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

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

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

Mikhail Sukhov:

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

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

Mikhail Sukhov
Mikhail Sukhov

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

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

asuilin
asuilin Autor

Кеш дат это tradesDates.bin?

Mikhail Sukhov
Mikhail Sukhov

Да

asuilin
asuilin Autor

Михаил, а не могли бы вы публиковать отладочную информацию в NuGet? Хрен ведь поймешь, на какой конкретной дате оно спотыкается внутри итератора. См. http://www.arturdr.ru/net/publikatsiya-ishodnikov-vmeste-s-nuget-plyus-ishodniki-av-infrastructure-web/ и https://docs.nuget.org/create/creating-and-publishing-a-symbol-package

asuilin
asuilin Autor

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

Mikhail Sukhov
Mikhail Sukhov

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

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

asuilin
asuilin Autor

Mikhail Sukhov: Наверное не поняли. Надо удалить дату. Тоесть не перезаписывать файл, а новый создавать нужно. Да, конечно я так и делал. Под перезакачкой имелась в виду повторная заливка этой даты в Гидре.

asuilin
asuilin Autor

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

Mikhail Sukhov
Mikhail Sukhov

asuilin:

Mikhail Sukhov: Наверное не поняли. Надо удалить дату. Тоесть не перезаписывать файл, а новый создавать нужно. Да, конечно я так и делал. Под перезакачкой имелась в виду повторная заливка этой даты в Гидре.

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

asuilin
asuilin Autor

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

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

Mikhail Sukhov
Mikhail Sukhov

asuilin:

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

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

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

asuilin
asuilin Autor

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

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

Mikhail Sukhov
Mikhail Sukhov

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

asuilin
asuilin Autor

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

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

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

Mikhail Sukhov
Mikhail Sukhov

asuilin:

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

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

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

asuilin
asuilin Autor

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

Mikhail Sukhov
Mikhail Sukhov

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

asuilin
asuilin Autor

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

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

asuilin
asuilin Autor

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

Mikhail Sukhov
Mikhail Sukhov

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

Вас кто-то останавливает? http://stocksharp.com/forum/4893/Sovmiestnaia-rabota-v-GitHub/