Блог им. AndreiSk

Обмен данных QUIK->Lua->C#

В продолжение темы
http://smart-lab.ru/blog/269715.php

Все таки переделал робота, частично разгрузил канал DDE (убрал стакан).
Теперь рабочая конфигурация выглядит так
QUIK->DDE->моя C# программа (NDDE сервер) (портфель, деньги)
QUIK->Lua скрипт->OnQuote()+PrintDbgStr(..)->моя C# программа (стакан)
моя C# программа->trans2quik.dll->QUIK (заявки и их статусы)

В общем, идея с PrintDbgStr вполне рабочая, два дня полет нормальный.
Робот заметно лучше шевелится и реагирует на стаканчик.
Скрипт на Lua передает изменения стаканов (метод OnQuote),
далее беру 5 лучших бидов и офферов, мне больше не надо.
А то понимаешь, по 20 значений для каждой стороны передавалось по DDE.
Конечно все тормозило. Счас уже незаметно торможение.

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

По прежнему жду компетентных товарищей использующих прямой доступ на биржу. Расскажите как у вас дела то…
  • Ключевые слова:
  • QUIK
★7
28 комментариев
что мешает самому прямой доступ взять и писать сразу под него?
avatar
Cristopher Robin, ничто не мешает, грабель боюсь, опыта нет в прямом соединении. А точнее не знаю, за что хвататься FIX/FAST/Plaza2… хочется послушать опытных людей
Счастливый Конец, берите Plaza2 на первое время для приобретения опыта и получения осязаемых результатов. С FIX/FAST много геморроя в плане тарифов (дороже, чем плаза), ну и сама эта связка немного сложнее плазы, в остальном по тестам биржи обмен данными по Plaza2 и FIX/FAST по скоростным характеристикам примерно одинаков.
Кстати, для разработчиков существует тестовый контур (и плаза, и фикс-фаст), и осваиваться с протоколами можно бесплатно.
avatar
вроде инструкция есть по поводу прямого подключения к бирже, на сайте их, не читали ее?
у вас хфт робот?
avatar
Ivor, инструкции пока не видел, жду логин-пароль от биржи для начала (заявку отправил). Да думаю разберусь без проблем, все же программист со стажем. Нет, не HFT робот, обычный, алгоритмический. Но и тормозить ему незачем, и главное можно попробовать отвязаться от торговых терминалов.
Счастливый Конец, тогда странно, что вы используете прямое подключение, плюс такую сложную конструкцию квик+луа+с#. У меня тоже обычные алгоритмические роботы, но всё в разы проще и дешевле, и тоже на с#.
Хотя, наверное, если делаете так ради опыта, то наверное оправданно.
avatar
Ivor, я не использую прямое подключение, пока только планирую разобраться в нем и может быть переделать нынешнего робота под прямое подключение. Сейчас робот у меня — надстройка над квиком, из которого экспортятся данные в C# через DDE+Lua скрипт и импортятся заявки из моей программы через trans2quik.dll. А у вас как устроено если на C#?
Счастливый Конец, комбайн для алготрейдера — ТСЛаб. И разрабатывает, и тестирует, и торгует. Сама разработка алгоритма ведется в visual studio, там же и дебагер, и подключается к тслабу через кубик.
Кстати, работа со стаканом там тоже есть.
avatar
Ivor, если честно, не хочу чтобы еще третьи программы сидели в комбайне. Мне хватает моей прожки и квика.
А как TSLab от квика получает данные?
Счастливый Конец, никак, на прямую от брокера берет.
avatar
Счастливый Конец, я тоже в свое время возился с луа, и dde, и в эксели загружал выгружал, мучился с кучами ошибок и падениями. Потом бросил все дело.
avatar
Ivor, с DDE все было проще. Квик он не только в эксель выводит, а в любой DDE сервер. Моя программа прикинулась экселем и получала данные. Все работает нереально стабильно. Я использовал NDDE библиотеку чтобы сделать на своей стороне DDE сервер, а в квике настроил передачу даннах (прописал имя сервера и topic — два верхних значения в окне свойств). Проблема была в том, что стаканы большие (40строк=20+20) и их передача забивала канал. А мне не надо так глубоко копаться в стакане, так что я стаканы перевел на другой канал, который и описал в предыдущем топике. Часть информации все равно передается по DDE, но там скорости не важны уже
Счастливый Конец, а как ваши дела с ram-диском? вы же вроде перешли на отдавание данных от квика через рам-диск? или до сих пор у вас работает dde?
avatar
Dmitriy, этот топик уже устарел :) PrintDbgStr был удален. Работал отлично, быстро. Но! Мешал отладке программы в окне Visual Studio. Использую RAM disk, полет отличный уже месяца три. От DDE до конца не отказался — все нет времени, но DDE осталось там, где нет потоков данных (позиции по бумагам, деньги).
Счастливый Конец, а я как раз вдохновился ранее вашим описанием метода экспорта через ram-disk, что вот тоже прямо сейчас пытаюсь его освоить, простота этого способа очень радует меня, новичка в с#)). Но в недавнем вашем комментарии «Под квиком использую QLua, Trans2quik.dll, NDDE» не увидел упоминания о рам-диске и подумал, может что-то изменилось и вы по какой-то причине отказались от него.
avatar
Dmitriy, так RAM диск всего лишь способ обмена между QLua и C#, формально QLua я упомянул, а больше QLua ни для чего не нужен.
Счастливый Конец, а какая задержка у вас получается на все эти операции записи-реагирования-чтения?
avatar
Dmitriy, сам процесс стал ощутимо чаще. Если раньше робот показывал приход данных стакана максимум 12 раз в секунду, то сейчас я видел число 90 раз в секунду. А что вас смущает в чтении-записи? Это же RAM диск (диск в памяти компьютера). Там обмен 7ГБайт/сек. Обычные SSD типа Plextor M6S дают около 0.5ГБайт/сек.
Счастливый Конец, а тики таблицы всех сделок не передаёте?
avatar
Dmitriy, нет. По моему опыту — в моменты движухи, оно сильно засоряет канал связи и из-за этого даже денег терял. Таблица всех сделок мне не нужна больше для стратегий. Вообще говоря там интересно только колонка «направление сделки», а так, агрегированные данные можно получить из таблицы котировок, что гораздо легче для клиентской части (нет нагрузки на канал связи).
Счастливый Конец, и ещё я пока сталкиваюсь с проблемой одновременности потоков. Реагирующее событие начинает реагировать на изменение файла раньше, чем строчка будет записана в файл. Как вы с этим боретесь?
avatar
Dmitriy, в событии FileSystemWatcher которое вызывается при создании файла в Lua, прежде чем читать, сделать Thread.Sleep(1); // ждать 1 мс — это не HFT в любом случае, так что задержка не сильно влияет.

Потом, в скрипте Lua не дописывайте файл, а просто создавайте новый, типа 1.txt, 2.txt, .., 99.txt, 1.txt и т.д. у меня в цикле 99 файлов создаются подряд. Да можно хоть 1000, но они просто место займут на RAM диске, 100 файлов достаточно, новые просто перезаписывают старые. Еще: в скрипте qlua пишете не строчку, а «S|ваши данные|E». И когда прочитали весь файл целиком, проверьте наличие S| и |E в начале и конце. Изредка, но бывает, что 1мс задержки недостаточно, тогда, если нет |E, ждем еще 1мс и читаем еще раз. У меня так и работает, щадержка 1-2 мс в данном случае — это ниочем, не мешает.
Счастливый Конец, к тому же событие FileSystemWatcher оно асинхронное (отдельный поток рождается), так что несколько инструментов не влияют на общую производительность. Но лучше конечно иметь быстрый процессор с несколькими ядрами. У меня i7 4790K, на данный момент — один из быстрых бытовых процессоров (см. http://www.anandtech.com/bench/CPU/38 ). Быстрее был бы еще i7 6700K, но это уже надо новый компьютер собирать. Главное быстрый процессор — видеокарта может быть и встроенная.
Счастливый Конец, насколько я понимаю Thread.Sleep(1) эквивалентно Thread.Sleep(16) и кучу других вариантов при разной загруженности процессора.
За советы спасибо! К сожалению не хватает рейтинга, чтобы спросить ещё некоторые вещи в лс))
avatar
Dmitriy, нет, Sleep(1) это 1мс. А 16мс это тик таймера (контрола такого). Он быстрее не может.
Счастливый Конец, точно! только что перепроверил — действительно так. Странно, видимо я не так воспринял то, что начитался про этот Sleep. Думал там как раз для определения длительности используется системный таймер… Ничего не пойму, но ладно, разберусь)
avatar
А почему нельзя поступать как тот же Chrome? Т.е. пока пишется файл на диск, то файл имеет расширение .txt.tmp, как Lua скрипт из QUIK закончил писать, то переименовать в .txt. Непонятно зачем городить слипы, а потом еще и пытаться под них подстроиться.
avatar
nskez, не помню уже что там да и как. Самое оптимальное теперь - это quik (через скрипт qlua) пошет новые данные в отдельный файл. Т.е. создает файл 0.txt,1.txt,2.txt,99.txt,0.txt (и далее перезапись старых 1.txt,2.txt) с текстом S|BRJ7|50.44|E и я из C# программы через FileSystem монитор (класс в .net), отлавливаю появление этого файла и читаю. Если не прочел — жду 1мс и читаю снова.
Файлы qlua кидает в ram disk, но можно и на SSD, без разницы. Пока это окончательный вариант, работает уже пару лет.

теги блога Счастливый Конец

....все тэги



UPDONW
Новый дизайн