Конвертация исторических файлов QScalp в формат StockSharp
Atom Ответить
26.09.2013


Привет всем алготрейдерам!

Хочу поделиться своим решение для тестирования скальперских и ХФТ стратегий. Долгое время я использую замечательный привод Морошкина (бесплатную версию Smile ). И недавно решил автоматизировать несколько стратегий на базе StockSharp.

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

Но недавно я узнал, что QScalp сам пишет историю и бесплатно ее выкладывает через брокера IT Invest.

В итоге, я написал конвертор данных QScalp в формат StockSharp!

qscalp.png


6ca46147f28faec3535dad2b10487513.png


Просто установите программу и скачайте исторические данные формата QSH для QScalp по одной из ссылок ниже

http://www.itinvest.ru/s...ware/spo/qscalp/history/

ftp://athistory.zerich.com/

Теперь осталось только указать в конвертере путь к скаченным файлам и к папке хранения исторических данных StockSharp, и нажать кнопку “Запустить”!

Вуаля, теперь у вас есть высококачественные исторические данные для тестирования своих стратегий!

PS Торопитесь пока бесплатно ;))

PPS Шутка))


Всем удачной торговли!

Присоединиться и редактировать код можно по https://github.com/stocksharp/Qsh2Bin

скомпилированную программу по https://github.com/StockSharp/Qsh2Bin/releases




63 Ответов
< 1 2 3 
Mikhail Sukhov

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


Поправил утилиту, чтобы поддерживала новый формат.

Утилитой кто-то пользуется? Или ОЛ уже интересен только единицам?
Спасибо: Дмитрий Антипов

Константин

Фотография
Курсы Благотворитель
Дата: 04.02.2019
Ответить


Я юзаю сею утиль
Спасибо:

torontoxx

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


Mikhail Sukhov Перейти
Поправил утилиту, чтобы поддерживала новый формат.

Утилитой кто-то пользуется? Или ОЛ уже интересен только единицам?



Здравствуйте. Я пользуюсь утилитой. Огромное за нее спасибо - очень полезная вещь. Но я обнаружил, что утилита неправильно собирает стакан.
Как я это обнаружил. Я добавил в утилиту функцию подсчета суммарного объема стакана по бидам и аскам (глубина стакана 50) и сохранения суммарного объема, а также лучшей цены в файл.
Т.е. я добавил после строки 509 метода ConvertFile файла MainWindow.xaml.cs следующий код (под спойлером):



Далее я протестировал утилиту на исторических данных фьючерса на индекс РТС (RTS-3.19), скаченных с сайта цериха и сравнил полученные объемы стакана с объемами, которые выводит QScalp на этих же исторических данных.
Результаты отличались: объемы, рассчитанные утилитой на порядок превышали объемы QScalp. Я пришел к выводу, что проблема в коде в строках 438 - 441 метода ConvertFile файла MainWindow.xaml.cs:

Код

else if (ol.Flags.Contains(OrdLogFlags.Moved))
{

    status |= 0x100000;
}


По совету пользователя vk37 от 26.01.2016 я установил OrderState = Done для заявок с флагом Moved:

Код

else if (ol.Flags.Contains(OrdLogFlags.Moved))
{

status |= 0x100000;
msg.OrderState = OrderStates.Done;
}


И утилита стала считать объемы стакана правильно. Скажите пожалуйста, насколько мое решение верно?
Пользователь vk37 в своем сообщении от 26.01.2016 вообще советует устанавливать OrderState = Done для всех заявок из ордерлога, кроме добавляемых заявок (с флагом Add). Скажите пожалуйста, насколько его совет правильный?

Но это еще не все. Когда я стал сравнивать лучшие цены и суммарные объемы стакана после вечернего клиринга с данными, выводимыми QScalp, то обнаружил, что они отличаются: объемы рассчитанные утилитой в разы превышали объемы QScalp.
Я пришел к выводу, что утилита при сборке стакана некорректно обрабатывает вечерний клиринг, фактически не очищая стакан. Вот пример результата работы утилиты в вечерний клиринг:

1) Перед вечерним клирингом (время 18:44:59.926) суммарный объем по бидам = 2186, по аскам = 1889.
2) При обработке всех последующих заявок из ордерлога в период вечернего клиринга получаем пустой стакан (список котировок по бидам и аскам, а также лучшие цены пустые).
3) Начало вечерней сессии (время 19:0:0.347). Поступила заявка, в результате которой получаем лучшую цену по аскам, а суммарный объем по аскам = 2612, что фактически составляет суммарный объем до клиринга плюс объем заявок, поступивших в период вечернего клиринга.
4) Аналогично с бидами: время 19:0:0.505, поступает заявка, в результате которой получаем лучшую цену по бидам, а суммарный объем по бидам = 2536, что фактически составляет суммарный объем до клиринга плюс объем заявок, поступивших в период вечернего клиринга.

Я решил очищать стакан в вечерний клиринг просто создавая новый экземпляр builder:

Код

builder = new PlazaOrderLogMarketDepthBuilder(securityId);


Теперь результаты утилиты и QScalp совпадают.

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




Спасибо: Mikhail Sukhov

torontoxx

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


Хотя нет, утилита все еще неудовлетворительно собирает стакан. Стал на истории сравнивать лучшие цены, рассчитанные утилитой с лучшими ценами, выводимыми QScalp и обнаружил, что разница между ними большая. Для фьючерса на индекс РТС за 25 февраля, например разница составляет 2-3 шага цены (20-30 пунктов)
Спасибо:

torontoxx

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


Все-таки интересно, почему лучшие цены в стакане, собранным утилитой (PlazaOrderLogMarketDepthBuilder) отличаются от лучших цен QScalp. Неужели один из двух дает неверный результат? Или я что-то не понимаю...
Спасибо:

Дмитрий Антипов

Фотография
Курсы Благотворитель
Дата: 04.03.2019
Ответить


Добрый день.

Подскажите пожалуйста.

Имею данные (c ftp://athistory.zerich.com/).
GAZP.2019-01-30.Deals.qsh
GAZP.2019-01-30.Quotes.qsh
LKOH.2019-01-30.Deals.qsh
LKOH.2019-01-30.Quotes.qsh

Снимок.PNG
Пробовал ставить и MICEX площадку и бинарные данные.

Стаканы грузятся корректно, но сделки не совсем.

Для Газпрома цену нужно разделить на 100 и тогда ок.
Снимок.PNG

Для Лукойла цену нужно разделить на 2 и тогда ок.
Снимок.PNG

Почему так получается?
Спасибо:

torontoxx

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


Дмитрий Антипов Перейти
Добрый день.

Подскажите пожалуйста.

Почему так получается?


Может надо цену умножать на шаг (priceStep) по аналогии с заявками из ордерлога?

Спасибо: Дмитрий Антипов

Дмитрий Антипов

Фотография
Курсы Благотворитель
Дата: 06.03.2019
Ответить


torontoxx Перейти
Дмитрий Антипов Перейти
Добрый день.

Подскажите пожалуйста.

Почему так получается?


Может надо цену умножать на шаг (priceStep) по аналогии с заявками из ордерлога?



Подскажите пожалуйста, на какой строке проекта находится данная "аналогия с заявками из ордерлога"?

Отследил чтение. Нужно в этом методе что-то менять?
Снимок.PNG
Снимок.PNG 34,1KB (60)
Спасибо:

torontoxx

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


Дмитрий Антипов Перейти
torontoxx Перейти
Дмитрий Антипов Перейти
Добрый день.

Подскажите пожалуйста.

Почему так получается?


Может надо цену умножать на шаг (priceStep) по аналогии с заявками из ордерлога?



Подскажите пожалуйста, на какой строке проекта находится данная "аналогия с заявками из ордерлога"?

Отследил чтение. Нужно в этом методе что-то менять?
Снимок.PNG


Попробуйте поменять строку №380 в файле MainWindow.xaml.cs:

Старая строка: TradePrice = deal.Price,
Исправленная срока: TradePrice = deal.Price * priceStep,
Спасибо: Дмитрий Антипов

Viacheslav

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


Коллеги, правильно ли я понимаю, что файлы сделок и стаканов на athistory.zerich.com и http://qsh.qscalp.ru/scalping.pro - это данные по Московской бирже?
Спасибо:

torontoxx

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


Viacheslav Перейти
Коллеги, правильно ли я понимаю, что файлы сделок и стаканов на athistory.zerich.com и https://qsh.qscalp.ru/scalping.pro - это данные по Московской бирже?


Надо полагать, да
Спасибо:

Sun_Storm

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


Добрый день.
Пробую сейчас сконвертировать данные через этот конвертер. Данные беру отсюда: http://erinrv.qscalp.ru, за апрель
Возникли следующие ошибки:
При загрузке данных стаканов по акциям Сбербанка возникала ошибка и данные не грузились.
Проблему я решил, порывшись в исходниках. там в исходном файле в начале торгов есть строки с ценой и объемом 0 и типом Unknown. Когда тип Unknown, программа сразу выдает исключение:
Код

switch (q.Type)
{
    case QuoteType.Unknown:
    case QuoteType.Free:
    case QuoteType.Spread:
        throw new ArgumentException(q.Type.ToString());

Написал пока так для себя, не знаю, как в С# принято такое обрабатывать, когда у нас только 2 значения side:
Код

switch (q.Type)
{
    case QuoteType.Free:
    case QuoteType.Spread:
        throw new ArgumentException(q.Type.ToString());
    case QuoteType.Unknown:
        \\throw new ArgumentException(q.Type.ToString());
        side = 0;
        break;


Второй ошибкой является то, что для всех стаканов (файл quotes) время проставляется одно и то же для каждой строчки на весь файл.
Эта ошибка проявляется и для акций и для фьючерсов.
Пока не могу её побороть. сохранение в файл делается средствами StockSharp.Algo.Storages, все исходники там, как я понимаю. По отладке не могу понять, какие параметры должны быть у pair, чтобы в строке registry.GetQuoteMessageStorage(pair.Key, format: format).Save(pair.Value.Item1); запись происходила как надо. Пробовал менять LocalTime и ServerTime для каждого набора, всё равно сохраняет неправильно (со временем 35517549, например)
Спасибо:

Sun_Storm

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


Опытным путем разобрался с проблемой времени!
Если у вас в папке, из которой вы конвертируете, лежат сразу 3 файла на день из архива http://erinrv.qscalp.ru (Deals, Quotes И AuxInfo), то конвертация будет некорректной!
Я скачивал сразу все 3 файла, и из одной папки конвертировал, поэтому была ошибка.
Если в папке лежат 2 файла на день - Deals, Quotes, то всё конвертируется нормально (если не считать ошибки по акциям, описанной мной выше)

UPD:
В общем это я поспешил, что разобрался, всё равно время некорректно ставится.
Ошибка плавающая... Я в потоках этих не разбираюсь...
Однако, если прописать вместо
ServerTime = currentDate.ApplyTimeZone(TimeHelper.Moscow),
ServerTime = qr.CurrentDateTime.ApplyTimeZone(TimeHelper.Moscow),
то вроде будет работать и время сменяться. Только в файлах начало дня при таком раскладе будет 4 часа.
Спасибо:
< 1 2 3 

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

loading
clippy