П М
П М личный блог
14 ноября 2014, 23:51

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

Как говорится, делай добро и бросай его в воду.
Выношу на свет плоды своих трудов. Трудов не одного дня. На текущий момент это же решение уже работает у меня в составе робота.
Проверено.

Что это такое: с помощью скрипта 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

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

Зачем я всё это выкладываю? Хочу найти работу в очень серьёзном трейдинге. «Ну ваааазьмите меня» 
Люблю системное программирование. И трейдинг.
71 Комментарий
    • anovikov1992
      09 июля 2019, 13:51
      ПBМ, а в случае многопоточной работы одного клиента? То есть мы создаём одного клиента, который из нескольких десятков потоков выставляет/снимает заявки, запрашивает данные из таблиц и т.п., сервер с подобным должен справиться? Сейчас у нас именно такая реализация, работает нестабильно, иногда виснет при запросах.
  • RIH2
    15 ноября 2014, 00:01
    «получение времени сервера»

    Вот эта штука, интересно, как реализована?
      • RIH2
        15 ноября 2014, 00:10
        Павел Bosco М, ага, спасибо.
        • RIH2
          15 ноября 2014, 00:11
          RIH2, А время биржи есть там (не сервера квика)?
            • RIH2
              15 ноября 2014, 00:27
              Павел Bosco М, не знаю, не уверен. Мне казалось что время сервера это время сервера QUIK, а время биржи это другое (собственно время биржи, по которому заключаются сделки). Так достоверно было на другом терминале и я думал что на квике так же, и поскольку моё мнение не было изменено за 5 лет, видимо и оснований для этого не было. Но мог и просто не заметить, давно уже не смотрел за этим всем.
                • Mr. Bean
                  15 ноября 2014, 00:38
                  Павел Bosco М, а кроме программирования вы ещё что-то умеете?
                • gry
                  15 ноября 2014, 10:59
                  Павел Bosco М, а почему через quik скальпить не быстро? Дело в отсутствии удобных инструментов или в медленной скорости самого quikа?
                  Спасибо за ваши примеры кода, как раз начинаю изучение построения роботов. Сам java программист, и думал что придется осваивать C# для этих целей.
                  • Андрей К
                    15 ноября 2014, 12:49
                    gry, что нам программистам, сложно еще один язык освоить? =)
                    c# интересен когда переходите на другие системы типа TsLab
  • crazyFakir
    15 ноября 2014, 01:55
    спасибо за примерчик.
    дайте, пжлст, мыло — есть темка.
    тханк ю.
  • velikan
    15 ноября 2014, 10:40
    да с lua можно и наружу транслировать все пироги
    а мне интересно, как можно из своей софтины связаться с серваком брокера, чтобы он думал что моя софтина — квик и отдавал данные, и принимал команды
      • velikan
        15 ноября 2014, 11:15
        Павел Bosco М, быстрее — получится, квик потому что думает не только про купить/продать но и про кучу всего остального — комплексная софтина
        а напрямую — да, тут никакой квик не поможет, только деньги :) наверное
    • Андрей К
      15 ноября 2014, 12:54
      velikan, попробуйте отснифить порт. заодно и нам расскажите про протокол =)
      • velikan
        15 ноября 2014, 16:02
        Андрей К, пробовал — основная проблема в том, что я нихера не понимаю в логах wireshark :(
  • Artem Melnichenko
    15 ноября 2014, 14:44
    > делай добро и бросай его в воду.
    Больше нравится «делай добро и беги» :)
  • 111111111
    15 ноября 2014, 14:54
    автор, dde то тебе чем не угодил?
    • Watcher
      15 ноября 2014, 15:04
      GreenBear, передача данных через DDE по идее медленнее, чем через Lua.
      • 111111111
        15 ноября 2014, 15:17
        Enfernuz, медленнее?
        • Андрей К
          15 ноября 2014, 15:29
          GreenBear, медленнее 100%.
          плюс такие разработки могут привести к полноценной серверной части на qlua. Например двусторонний обмен данными и выполнение команд на сервере со стороны клиента
          • 111111111
            15 ноября 2014, 15:53
            Андрей К, проясните этот момент на каком этапе медленне? Я на sql сервер передаю например все сделки и не заметил даже секундной задержки.

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

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

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

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

                  Что касательно старых версий quik. DDE — это отдельная разработка microsoft, вышедшая еще из 90-ых. Сам quik не особо имеет отношение к ней, просто средствами windows передает данные, некий такой блок внутри windows
                  • 111111111
                    15 ноября 2014, 22:17
                    Андрей К, ок. не буду больше флудить :)
      • 111111111
        15 ноября 2014, 22:15
        Павел Bosco М, писать скрипт на LUA быстрее чем делать вывод на DDE? :)
        делаете вывод на сервер SQL пишет запрос и ничего не надо парсить + сохраняете историю для анализа.
        частота вывода указывается в настройках, а проверка — изменился ли стакан, увеличивает время доставки инфы ;)

        ну не буду больше утраивать полемику. без перфоманса достижение кажется сомнительным.
          • 111111111
            15 ноября 2014, 22:59
            Павел Bosco М,
            1) таблицы настраиваются и экспортируются!
            2) 1)
            3) 1)
            4) могу ). триггеры, таймеры...
            ну да odbc.
            когда я делал нужный мне индикатор, он обновлялся каждую секунду.
            quik -> odbc -> робот. quik -> lua -> робот. не могу сказать точно, что быстрее.
            и добавлю, организация автоматизации в квике меня сильно раздражает, ушел на transaq connector, больше свободы и больше контроля.
              • 111111111
                15 ноября 2014, 23:18
                quik -> odbc -> ms-sql -> odbc -> робот



  • Watcher
    15 ноября 2014, 15:03
    Господи, 10/10!
    Автор, как отблагодарить?

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

        Попытался по вашей схеме наладить передачу через 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/ (зачем?)

        Классический вопрос: что я делаю не так?
          • Watcher
            17 ноября 2014, 03:42
            Павел Bosco М, спасибо, вроде разобрался.
            А заявки вы как отправляете?
              • Watcher
                20 ноября 2014, 00:45
                Павел 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 уже сам по себе режет быстродействие своей политикой получения данных с сервера. Но с этой обёрткой у меня уже принципиальный вопрос — «могу ли я?» :)
                Если осилю — поделюсь.
  • asteroid
    15 ноября 2014, 18:22
    а почему никто не пробует сделать все с zmq или подобными?
  • Alexandr
    15 ноября 2014, 19:31
    Вот здесь: forum.mql4.com/ru/3393#79641



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



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



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



    Это я к тому, что такой метод передачи очень надёжный… и ничего не вешает.
  • asane
    17 ноября 2014, 06:41
    коллеги! можно попросить ffi.dll и ffi.lib или что там еще билдится и требуется проекту прикрепить или на файлообменник выложить? спасибо!
  • asane
    17 ноября 2014, 13:53
    спасибо!
    • anovikov1992
      19 июня 2019, 10:38
      ПBМ, спасибо за работу, помогает скрипт. Такой вопрос возник, по какой-то причине функции по получению времени сервера, торговый день, соединение с сервером работают исправно, а вот получение данных из таблицы текущих торгов (использование getParamEx() ) никак не удаётся запустить. Подскажите пожалуйста, может что-то поменялось с того времени или же какие-то настройки в терминале необходимо произвести?
        • anovikov1992
          20 июня 2019, 13:59
          ПBМ, в потоке котировок выбрал всё, что доступно. «Фортс» в нём не вижу

          Может с моим подключением мне нельзя получать данные из этой таблицы? У меня сейчас тестовый доступ к учебному серверу
  • Krl
    29 июня 2019, 20:58
    Подскажите пожалуйста подобный способ возможно реализовать с помощью python? Есть ли возможность работать с заявками через pipe, не используя trans2quik? (я имею ввиду постановку, снятие, контроль исполнения заявок)
  • Krl
    30 июня 2019, 12:14
    да, это я тоже сделал на Java, но это уже отдельный проект), а именно — падала при переходе в Callback по обновлению статуса заявки.
    У меня такая же ерунда видимо в скрипте… запускаю скрипт (python)… выставляю заявки… снимаю, исполнение… все работает!  коллбеки приходят… все работает нормально… но затем просто отваливается скрипт (как будто выходит и цикла) у себя в скрипте все окутал логгированием и исключениями… но они все молчат. Я подозревал, что вылетает где то внутри длл… но событие это отследить не смог… причину воспроизведения ошибки тоже. Подскажите как Вы это победили?
      • Krl
        08 июля 2019, 12:09
        ПBМ, Наверняка уже достал Вас вопросами и просьбами… Но все же рискну… Не могли бы помочь с компиляцией ffi.dll (64 bit). Я бы хотел научиться делать это сам, не могли бы не много пошаговой инструкции дать. Использую visual studio 2017. Раньше с такими задачами не сталкивался...(
          • Krl
            08 июля 2019, 22:38
            ПBМ, Попробовал скомпилировать… Как прочитал выше в комментариях сделал qlua.lib. Взял файл qlua.lib, qlua.dll (из дистрибутива quik 8) и создал папку:
            2) Прописал пути к файлам в батнике:


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


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

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


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

                библиотека немного другая, но основа у нее та же самая… с luaffi по сути я делал аналогичное
                  • Krl
                    17 июля 2019, 23:30
                    ПBМ, dll прицепилась все отлично! Только теперь при использовании Вашего старого скрипта handle у pipe = -1. (он не создается) Там поменялся синтаксис или  загвоздка в чем то другом? Проверил работоспособность функции int MessageBoxA(void *w, const char *txt, const char *cap, int type); из скрипта все получается… Может луа у меня какая нибудь не та с квиком лежит? 
  • jesc
    08 декабря 2020, 12:54
    Добрый День!
    ПBМ
    , Krl, вам удалось победить ошибку? У меня то же самое:

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

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

Активные форумы
Что сейчас обсуждают

Старый дизайн
Старый
дизайн