Блог им. bosco

On-Line получение данных из Quik в Java и не только

    • 14 ноября 2014, 23:51
    • |
    • П М
  • Еще
Как говорится, делай добро и бросай его в воду.
Выношу на свет плоды своих трудов. Трудов не одного дня. На текущий момент это же решение уже работает у меня в составе робота.
Проверено.

Что это такое: с помощью скрипта QApi.lua на стороне Quik организуется сервер, который умеет принимать команды с клиента и отдавать ему результаты выполнения этих команд.

какие команды и данные может выдавать скрипт
— получение стакана по заданной бумаге (class, security)
— получение последних N свечей по заданной бумаге   (class, security, interval, count)
— получение времени сервера
— получение торговой даты
— получение статуса квика — подключен он к серверу или нет

Зачем это надо: работает достаточно быстро — десятые доли секунды, стакан отдаётся с разной скоростью, т.к. скрипт для начала ждёт чтобы стакан изменился (гарантированно последние данные), не требует на стороне квика никаких настроек и открытых графиков. всё что надо — запустить скрипт.

Как это работает используется Windows Named Pipe, работа с которой происходит чере технологию FFI — foreign function interface, эта технология поддерживается для многих языков, таких как Java и Perl, например. Из VBA и C# можно работать с Windows Pipe напрямую, сделав объявления соответствующих функций из kernel32.

Похвастаюсь, в процессе работы с FFI я нашел существенную ошибку, которая не позволяла корректно работать с Trans2Quik.dll (да, это я тоже сделал на Java, но это уже отдельный проект), а именно — падала при переходе в Callback по обновлению статуса заявки. Я связался с разработчиком и он любезно это исправил. На форуме Quik разные люди в разное время не могли побороть эту проблему 3 года...

Что нужно чтобы запустить у себя 
  • ну во-первых Quik, во вторых, нужна скомпилированная библиотека ffi.dll, я брал отсюда: github.com/jmckaskill/luaffi. Там надо будет подшаманить с qlua.dll, чтобы получить из неё qlua.lib
  • затем, если вы будете работать на java, вам понадобиться jna, я брал отсюда https://github.com/twall/jna 
Где можно взять исходники 
а собственно вот: github.com/boscogh/quik_pipe

Честно скажу, это мой первый опыт опен-сорса, может я что-то сделал не так, исправлюсь.
Надеюсь это всё кому-то поможет.

Зачем я всё это выкладываю? Хочу найти работу в очень серьёзном трейдинге. «Ну ваааазьмите меня» 
Люблю системное программирование. И трейдинг.
4.2К | ★42
71 комментарий
да, немного про ограничения: сервер работает только с локальными клиентами (с этой машины), максимум одновременно только один клиент.

клиент может подключаться и отключаться, сервер это легко переживает.
avatar
ПBМ, а в случае многопоточной работы одного клиента? То есть мы создаём одного клиента, который из нескольких десятков потоков выставляет/снимает заявки, запрашивает данные из таблиц и т.п., сервер с подобным должен справиться? Сейчас у нас именно такая реализация, работает нестабильно, иногда виснет при запросах.
avatar
anovikov1992, о каких заявках речь?
в текущей реализации никакая многопоточность не поддерживается.
взаимодействие идёт по схеме: запрос -> ответ.
avatar
«получение времени сервера»

Вот эта штука, интересно, как реализована?
avatar
RIH2, в lua есть такое API,
см 183 строку github.com/boscogh/quik_pipe/blob/master/qapi.lua
avatar
Павел Bosco М, ага, спасибо.
avatar
RIH2, А время биржи есть там (не сервера квика)?
avatar
RIH2, так это и есть время биржи, нет?
т.е. это то время, которое отображается в квике снизу слева как «время сервера»
avatar
Павел Bosco М, не знаю, не уверен. Мне казалось что время сервера это время сервера QUIK, а время биржи это другое (собственно время биржи, по которому заключаются сделки). Так достоверно было на другом терминале и я думал что на квике так же, и поскольку моё мнение не было изменено за 5 лет, видимо и оснований для этого не было. Но мог и просто не заметить, давно уже не смотрел за этим всем.
avatar
RIH2, с другими терминалами не работал, но заявки регистрируются по времени сервера, у меня робот успевает вставать ровно на открытии следующей часовой свечи.
т.е. смотрю каждые 100 мс на время сервера, если уже хх:00:00, то читаю последние 3 свечи, разбираю для того часа который завершился и по необходимости выставляю заявку. В квике она отображается как xx:00:00,
насколько я понимаю, это уже время, когда она на биржу попала?

я скальпингом не баловался, насколько я могу понять, через квик это дело не самое быстрое. Сегодня у меня в районе 14:00 (для этого случая ставлю в 13:59:59, пораньше) была выставлена заявка, на покупку, но исполнилась она далеко не сразу, хотя цена уходила и чуть ниже. Исполнилась только через 5 минут. Не знаю почему, но дело точно было не во времени

UPD: пардон. это я уже глючу, заявка на продажу была. поэтому пока цена была ниже, она и не срабатывала… пора спать :)
avatar
Павел Bosco М, а кроме программирования вы ещё что-то умеете?
avatar
Mr. Bean, по работе? пишите в личку, может и умею.
текущий профиль работы у меня не связан с трейдингом. хотя связан с банками.
образование — инженерное, программист.
занимаюсь интеграцией банковских систем.
ну и не только банковских. любых где есть данные и интерфейсы по работе с ними.
avatar
Павел Bosco М, а почему через quik скальпить не быстро? Дело в отсутствии удобных инструментов или в медленной скорости самого quikа?
Спасибо за ваши примеры кода, как раз начинаю изучение построения роботов. Сам java программист, и думал что придется осваивать C# для этих целей.
avatar
gry, что нам программистам, сложно еще один язык освоить? =)
c# интересен когда переходите на другие системы типа TsLab
avatar
спасибо за примерчик.
дайте, пжлст, мыло — есть темка.
тханк ю.
avatar
Ринат Негметов, зайди ко мне в профиль, там первая ссылка «Написать письмо»
avatar
да с lua можно и наружу транслировать все пироги
а мне интересно, как можно из своей софтины связаться с серваком брокера, чтобы он думал что моя софтина — квик и отдавал данные, и принимал команды
avatar
velikan, наверное можно и так, но вряд ли получится быть квиком быстрее квика.
тогда уж лучше кардинально решить проблему и соединяться с сервером биржи напрямую, через Plaza. я так ещё не делал.
avatar
Павел Bosco М, быстрее — получится, квик потому что думает не только про купить/продать но и про кучу всего остального — комплексная софтина
а напрямую — да, тут никакой квик не поможет, только деньги :) наверное
avatar
velikan, попробуйте отснифить порт. заодно и нам расскажите про протокол =)
avatar
Андрей К, пробовал — основная проблема в том, что я нихера не понимаю в логах wireshark :(
avatar
> делай добро и бросай его в воду.
Больше нравится «делай добро и беги» :)
avatar
автор, dde то тебе чем не угодил?
avatar
GreenBear, передача данных через DDE по идее медленнее, чем через Lua.
avatar
Enfernuz, медленнее?
avatar
GreenBear, медленнее 100%.
плюс такие разработки могут привести к полноценной серверной части на qlua. Например двусторонний обмен данными и выполнение команд на сервере со стороны клиента
avatar
Андрей К, проясните этот момент на каком этапе медленне? Я на sql сервер передаю например все сделки и не заметил даже секундной задержки.

Я бы разработчиков квика заставил землю есть. LUA, QPile, DDE еще какая-то лажа… Все что необходимо это простой интерфейс с реализациями функций: connect, getHistory, trade. всё! такие разработки приведут только к потери времени.
avatar
GreenBear, вообщем дело такое.
Тут я бы разделил для себя вот что. Говорим про какой то автоматический вход в позицию. Выделяем такие параметры: моменты входа (какие то уровни со скопление ликвидности или просто вход свободный по рынку), возможный тейк, возможное время нахождение в сделке.

Если у нас осуществляется вход в сильно валотильный и сильно ликвидный момент на рынке, при этом тейк не более 500п (к примеру) и время сделки короткое (ну например 10-60сек), то коннект нам нужен быстрый. Я бы не сказал что могут решать микросекунды, но на dde при нынешнем рынке нас может легко просквозить на 100п (ри), в си и того сейчас больше. Если мы высиживаем до 500п, то такие потери конечно существены.
Если мы принимаем решение сидеть глобально (ну например отбой от какой нибудь сотой машки), сидеть пару часов и пару тысяч, то конечно можно и dde.
Это я все высказал свое мнение.
Далее. Существуют ряд приводов для quik. Я думаю все вы их знаете. И они когда то начинали с dde. Было достаточно много жалоб на такой вид коннекта от пользователей. И постепенно эти коннекты ушли.
avatar
Андрей К, так и думал, что на уровень миллисекунд спустимся. Я сильно сомневаюсь в вашей правоте. Посерфил инет на эту тему, в основном вопрос поднимается на S#. Делаю выводы:
— или у разрабов S# руки кривые.
— или старые версии quik были кривые.

на форуме quik'a обсуждают что срезы стакана в квик приходят 1-3 раза в секунду т.е. бороться за скрость < 10 мс. нет никакого смысла! а значит gate + plaza вам помогут, а не LUA.

Приводами квик не пользовался, их историю не знаю.
avatar
GreenBear, я поделился с вами своим опытом. Привел цифры. И примеры, когда они критичны. Вы захотели, чтобы я пояснил, я рассказал.
Я акцентировал внимание, на решаемые задачи. Когда то подходит dde и не стоит усложняться в qlua, когда то подходит qlua и не стоит тратиться и еще больше усложняться на плазу и тд. Всему свое место.

Что касательно старых версий quik. DDE — это отдельная разработка microsoft, вышедшая еще из 90-ых. Сам quik не особо имеет отношение к ней, просто средствами windows передает данные, некий такой блок внутри windows
avatar
Андрей К, ок. не буду больше флудить :)
avatar
GreenBear, для DDE надо делать гораздо больше манипуляций — создать таблицу, настроить вывод, включить его.
Мой вариант ничего этого не требует, даже для свечек.
Ещё, мне не нравилось что DDE — пассивный. Т.е. Quik решает, когда прислать тебе данные. В моём варианте, клиент сначала просит что ему надо, а сервер отвечает.
Потом lua универсальнее. Как узнать по DDE время сервера и статус подключения? Можно ли по DDE отправлять одновременно и свечи и стаканы?
Наверное тоже можно… но не легко.
Ну и, честно говоря, парсить данные из буфера в нужном тебе формате гораздо проще чем заморачиваться с парсингом достаточно не простой структуры данных в DDE.
DDE я тоже делал, начал с него. Получилось, но не понравилось.
Windows Pipe попроще будет. И да, может доказательств у меня нет, но по-моему всё-таки действительно быстрее.
Я действительно считаю на миллисекунды. Меньше чем на 100 миллисекунд — это уже не квик. А для квика это время вполне достижимо. И для крупных таймфреймов, типа 1 час — более чем достаточно.
avatar
Павел Bosco М, писать скрипт на LUA быстрее чем делать вывод на DDE? :)
делаете вывод на сервер SQL пишет запрос и ничего не надо парсить + сохраняете историю для анализа.
частота вывода указывается в настройках, а проверка — изменился ли стакан, увеличивает время доставки инфы ;)

ну не буду больше утраивать полемику. без перфоманса достижение кажется сомнительным.
avatar
GreenBear, устроил полемику и бежать? :)
вопросы:
1. как организовать вывод свечек по ДДЕ? никак, без вспомогательного скрипта.
2. можно ли выводить по одному каналу DDE несколько инструментов?
3. что делать, когда фьючерс истёк и надо переходить на следующий, можно ли перейти автоматически?
4. можете ли вы получить котировку, свечку, ровно в тот момент, когда она нужна вам? а не когда сервер решил её вам отдать?
и вообще, по-моему вы всё-таки говорите не про DDE в SQL, а про ODBC.
что касается перформанса. приводите ваши цифры, интересно.
возьмём свечи. закончился час. через какое время у вас появится новая свеча?
вообще подумайте немного логически, что быстрее, обратиться напрямую в квик за нужными данными, пусть и через pipe/lua или обратиться к серверу SQL через тот же самый pipe (сюрприз!), который получает данные из Quik тоже не посредством волшебства, а скорее всего через pipe?
avatar
Павел Bosco М,
1) таблицы настраиваются и экспортируются!
2) 1)
3) 1)
4) могу ). триггеры, таймеры...
ну да odbc.
когда я делал нужный мне индикатор, он обновлялся каждую секунду.
quik -> odbc -> робот. quik -> lua -> робот. не могу сказать точно, что быстрее.
и добавлю, организация автоматизации в квике меня сильно раздражает, ушел на transaq connector, больше свободы и больше контроля.
avatar
GreenBear, между odbc и роботом ещё ms-sql, я об этом
т.е.
quik -> odbc -> ms-sql -> odbc -> робот
а так, кому что удобнее.
avatar
quik -> odbc -> ms-sql -> odbc -> робот



avatar
Господи, 10/10!
Автор, как отблагодарить?

Написал свой алгоритм на Lua, но скрипт после некоторого времени вешает Quik. Написал на С# с использованием StockSharp — так там коннектор Quik Lua только недавно приделали, и кое-каких нужных вещей ещё нет. А покупать Plaza 2 пока жаба душит.
Сам Java-программист по текущему месту работы, поэтому такая библиотека очень кстати.
avatar
Enfernuz, есть яндекс кошелёк
410011439569740
avatar
Хотел было в личку вопрос отправить, но тут на СЛ практически во всём дискриминация по рейтингу, в том числе и на отправку личных сообщений.

Попытался по вашей схеме наладить передачу через qapi.lua и столкнулся с проблемой: после нескольких секунд работы скрипта qapi.lua терминал падает с ошибкой Windows:

[ Сигнатура проблемы:
Имя события проблемы: APPCRASH
Имя приложения: info.exe
Версия приложения: 6.14.0.12
Отметка времени приложения: 53b69afe
Имя модуля с ошибкой: StackHash_97c2
Версия модуля с ошибкой: 6.1.7601.17514
Отметка времени модуля с ошибкой: 4ce7ba58
Код исключения: c0000374
Смещение исключения: 000ce653
]

Что я делал до того, как:
1) Сбилдил ffi.dll и ffi.lib — положил их в %Path_to_Lua%/5.1/lib/
2) ffi.dll положил в %путь_до_терминала%/lua/
3) получил с помощью MSVC Command Prompt из qlua.dll (лежит в папке терминала) инфу для создания qlua.def
4) с помощью той же коммандной строки создал qlua.lib
5) положил qlua.dll и qlua.lib в %Path_to_Lua%/5.1/lib/ (зачем?)

Классический вопрос: что я делаю не так?
avatar
Enfernuz, вообще как-то не так.
надо сначала сделать 3) 4), потом для 1) указать qlua в качестве «lua.dll» и «lua.lib» в файле msvc_build — т.е. qlua.dll и qlua.lib, затем библиотечку ffi надо положить в каталог с info.exe, скрипт можно класть куда угодно, это не существенно.
у меня тоже не получилось с первого раза.
там есть в ffi тестовый пример «test.lua», он должен отрабатывать без violation. стартовать и заканчивать.
на нём проще потренироваться, т.к. для него надо только lua, без квика.
avatar
Павел Bosco М, спасибо, вроде разобрался.
А заявки вы как отправляете?
avatar
Enfernuz, через Trans2Quik.dll и FFI тоже
твои деньги на кошелёк упали? спасибо :)
avatar
Павел Bosco М, я пытаюсь сделать java-обёртку для trans2quik.dll с помощью JavaCPP (https://github.com/bytedeco/javacpp), но нифига что-то не выходит (туповат я, что ли, но тамошних примеров недостаточно). Внутрях она на JNI, а это выигрыш в быстродействии по сравнению с JNA (http://developers.opengamma.com/blog/2012/05/25/jna-jni-and-raw-java-performance).
Хотя, может, игра с JNI вместо JNA и не стоит свеч, т.к. Quik уже сам по себе режет быстродействие своей политикой получения данных с сервера. Но с этой обёрткой у меня уже принципиальный вопрос — «могу ли я?» :)
Если осилю — поделюсь.
avatar
Enfernuz, спасибо, у меня рабочий вариант, мне он нравится. Jna очень быстрый, там ведь ассемблер внутри. Ссылку гляну завтра.
avatar
Enfernuz, посмотрел статью. думаю не стоит тебе мучаться с JNI.
никаких больших матриц с последовательным доступом в методах не передаётся.
максимум 11 чтоли аргументов простого типа для работы с заявкой.
а график из статьи начинает отличаться для JNA и JNI только после матрицы 200х200
получение свечей например происходит за 1 милисекунду (при условии что труба уже создана) и то, я сравниваю через System.currentTimeMillis(), скорее всего там даже чуть быстрее всё.

сетевые задержки и задержки сервера Quik будут на несколько порядков больше.
avatar
а почему никто не пробует сделать все с zmq или подобными?
avatar
asteroid, а смысл? есть API ядра Windows, просто и быстро. зачем изучать какие-то сторонние вещи, написанные для прикладных (не системных) задач?
avatar
Вот здесь: forum.mql4.com/ru/3393#79641



Есть пример для МТ4 как организовать связь между двумя терминалами МТ4 (на одном компе)при помощи PostThreadMessageA() и соответственно GetMessageA().



В своё время я гнал котировки (тики) из одного терминала в другой (в той ветке мой последний пост с картинками). Полагаю что это точно быстрее DDE работает :)



P.S. Комп работал безостановочно с ночи понедельника до конца торгов в пятницу. Перегружал его только в выходные.



Это я к тому, что такой метод передачи очень надёжный… и ничего не вешает.
avatar
коллеги! можно попросить ffi.dll и ffi.lib или что там еще билдится и требуется проекту прикрепить или на файлообменник выложить? спасибо!
avatar
avatar
спасибо!
avatar
залил обновлённый код на GitHub, по результатам тестирования в бою. исправил проблемы при отключении-подключении сервера (только если вы пользуетесь скриптом круглосуточно без его выключения)
ну и ещё несколько мелочей.
avatar
ПBМ, спасибо за работу, помогает скрипт. Такой вопрос возник, по какой-то причине функции по получению времени сервера, торговый день, соединение с сервером работают исправно, а вот получение данных из таблицы текущих торгов (использование getParamEx() ) никак не удаётся запустить. Подскажите пожалуйста, может что-то поменялось с того времени или же какие-то настройки в терминале необходимо произвести?
avatar
anovikov1992, скорее всего не включен параметр в «поток котировок» «фортс» -> «гарантийное обеспечение покупателя»

avatar
ПBМ, в потоке котировок выбрал всё, что доступно. «Фортс» в нём не вижу

Может с моим подключением мне нельзя получать данные из этой таблицы? У меня сейчас тестовый доступ к учебному серверу
avatar
anovikov1992, возможно у вас это называется… Фьючерсы, но может быть там нет параметра «гарантийное обеспечение покупателя»
посмотрите что вам доступно в «фильтре параметров» для фьючерсов.
либо же вы указываете не тот класс или код инструмента.
avatar
Подскажите пожалуйста подобный способ возможно реализовать с помощью python? Есть ли возможность работать с заявками через pipe, не используя trans2quik? (я имею ввиду постановку, снятие, контроль исполнения заявок)
avatar
да, это я тоже сделал на Java, но это уже отдельный проект), а именно — падала при переходе в Callback по обновлению статуса заявки.
У меня такая же ерунда видимо в скрипте… запускаю скрипт (python)… выставляю заявки… снимаю, исполнение… все работает!  коллбеки приходят… все работает нормально… но затем просто отваливается скрипт (как будто выходит и цикла) у себя в скрипте все окутал логгированием и исключениями… но они все молчат. Я подозревал, что вылетает где то внутри длл… но событие это отследить не смог… причину воспроизведения ошибки тоже. Подскажите как Вы это победили?
avatar
4ypakabra, у меня была проблема в JNA библиотеке, FFI части, всё падало целиком при приходе ответа в колбек, связано было с тем что FFI некорректно формировало стек вызова. У вас явно другая проблема.

на python у меня мало опыта программирования, не знаю деталей вызова dll из него. 

вылет в dll приведёт к закрытию quik и формированию .dmp, который можно загрузить в MSVC и посмотреть где была ошибка. у вас явно не вылет.
avatar
ПBМ, Наверняка уже достал Вас вопросами и просьбами… Но все же рискну… Не могли бы помочь с компиляцией ffi.dll (64 bit). Я бы хотел научиться делать это сам, не могли бы не много пошаговой инструкции дать. Использую visual studio 2017. Раньше с такими задачами не сталкивался...(
avatar
4ypakabra, это ведь не моя программа.
разработчики снабдили её инструкцией, качаете исходник, открываете Makefile, там сразу слова

# For MSVC, please follow the instructions given in src/msvcbuild.bat.

открываете батник, читаете, настраиваете..

если будут сложности — спрашивайте. но нужно хотя бы начать.

avatar
ПBМ, Попробовал скомпилировать… Как прочитал выше в комментариях сделал qlua.lib. Взял файл qlua.lib, qlua.dll (из дистрибутива quik 8) и создал папку:
2) Прописал пути к файлам в батнике:


3) Попытался запустить батник...(


Сам Интерпретатор Lua брал отсюда: https://sourceforge.net (lua5_1_4_Win64_bin)

Подскажите пожалуйста в чем может быть проблема??


avatar
4ypakabra, ну как бы для того чтобы собирать исходники, нужны исходники.

в прошлом комментарии я ошибся и ссылался на исходники lua-jit, а не lua-ffi, т.е. другой проект. 

для lua-ffi инструкция собственно на сайте
https://github.com/jmckaskill/luaffi

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

ошибки, которые у вас вылетают, говорят что не найден самый первый файл с исходником
call_arm.dasc 

т.е. думаю, просто надо было перейти сначала в каталог с батником/исходниками.

avatar
ПBМ, я записал все свои действия пошагово вот тут https://github.com/facebookarchive/luaffifb/pull/13#issuecomment-509774274 
Если не сложно подскажите что я делаю не так… бьюсь уже 2 сутки не могу никак с мертвой точки сдвинуться! Понимаю, что оно Вам нафиг не надо… но надежда только на Вас

библиотека немного другая, но основа у нее та же самая… с luaffi по сути я делал аналогичное
avatar
4ypakabra, пардон, пропустил ваш коммент, 
я пересобрал ffi.dll, правда без отладочной информации, что-то там никак не подцеплялось, а разбираться было лень.
но думаю будет работать и так.
www.dropbox.com/s/mqtpqyhi4b35lcq/ffi.dll?dl=1
avatar
ПBМ, dll прицепилась все отлично! Только теперь при использовании Вашего старого скрипта handle у pipe = -1. (он не создается) Там поменялся синтаксис или  загвоздка в чем то другом? Проверил работоспособность функции int MessageBoxA(void *w, const char *txt, const char *cap, int type); из скрипта все получается… Может луа у меня какая нибудь не та с квиком лежит? 
avatar
Добрый День!
ПBМ
, Krl, вам удалось победить ошибку? У меня то же самое:

assert(ffi.C.ConnectNamedPipe(handle, poverlapped), «create connection error»)
--bad argument #1 to 'ConnectNamedPipe' (cannot convert 'number' to 'void *')

Если не трудно, подскажите, как исправить? ffi.dll скачал по вашей ссылке
avatar

Читайте на SMART-LAB:
Фото
Снижение военной премии в нефти: что это меняет для доллара и G10
Во второй половине понедельника – начале вторники рынки активно пересматривают премию за худший сценарий на энергетическом рынке, что цепочкой...
Фото
12 марта Группа Ренессанс страхование опубликует МСФО за 2025 год
Напоминаем, что 12 марта 2026 года RENI опубликует МСФО Группы за 2025 год, а также проведет День инвестора, чтобы рассказать о ситуации на...
⚙️ Как Займер использует ИИ в своей работе
Мы часто говорим, что наш сервис — высокотехнологичный, и это не пустые слова. Ранее мы уже рассказывали, как в Займере работают скоринг и...
Фото
Гендиректор Инарктики продал свои акции компании. Что это может значить?
Вечером в пятницу (6 марта ) вышел сущфакт о том, что Соснов Илья Геннадьевич, гендиректор Инарктики, продал свои акции компании. В нашем...

теги блога П М

....все тэги



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