Блог им. 3Qu

Quik->Lua->C++DLL. Опыт разработки и немного кода.

    • 04 февраля 2020, 13:54
    • |
    • 3Qu
  • Еще

Начал вчера работы по реализации "Брошенной стратегии". Хорошо когда есть наработки: взял готовые куски кода, немного доработал под новые нужды, соединил их вместе и уже все готово — почти все необходимые данные передаются в DLL, расставляются по местам и готовы к использованию. С этим почти закончено, остальное будет делаться по ходу пьесы, и по мере необходимости.

С передачей данных закончено, а стратегия даже не начиналась. Система новая и архитектора системы пока не ясна, есть несколько вариантов, выбрать из которых не так просто.
Пока суд, да дело, решил написать о передаче данных из Quik в С++DLL.
О том как сделать простую С++DLL для работы с Quik-Lua написано на сайте https://quikluacsharp.ru  здесь и о передаче данных из Lua — здесь и в других материалах сайта. Наверняка многие из вас все это видели и знают, а некоторые это даже применяют. Я это все не использую, не очень разбирался, но, тем не менее, сам сайт https://quikluacsharp.ru очень полезный и в нем есть масса информации о применении Lua в Quik, которая никак не отражена в документации.
В примерах quikluacsharp.ru меня не устраивает в реализации передачи данных то, что все данные еще в Lua превращаются в текстовую CSV-строку, потом в виде строки передаются в DLL, оттуда в систему, в которой CSV-строка разбирается (парсится), и только тогда снова превращается в данные. На мой взгляд, такой подход порождает много сложностей еще до попадания данных на обработку системой.
Я это делаю проще и отправляю данные из Quik непосредственно в формате Lua, без каких либо дополнительных преобразований, что существенно упрощает код, его прозрачность и читаемость.
Давайте рассмотрим такую передачу данных на примере.
Код Lua:

function main()
        ds_s, Err1 =CreateDataSource (EX_CODE, FUT_S, INTERVAL_M1) --создаем источник данных *)
        if Err1 == "" or Err1 == nil then
                message("Подписка ОК 1")
                while not (ds_s:Size() >0) do
                        sleep(10)
                end
        else            
                message("Ошибка 1" .. Err1)
        end
        Err1 = ds_s:SetUpdateCallback (cbCandleS) --определяем функцию события терминала, получащую данные свечи. *)
--
--

Это кусок функции main() в котором мы создаем источник данных и подписываемся на информацию о свечах по фьючерсу FUT_S. Информацию о последней свече терминал будет записывать в переменную ds_s на каждом тике. Остальные строки — это проверка, что все прошло успешно.

Теперь определим функцию, которая будет получать данные из переменной ds_s.

function GetCandle(ds, fut, i) -- получение данных i-й свечи
     ct = {ds:T(i), fut, ds:O(i), ds:H(i), ds:L(i), ds:C(i), ds:V(i)}  -- *)
     return ct
end

Все данные о свече заносятся в возвращаемую функцией переменную ct.
Нам осталось теперь поместить эту функцию GetCandle() в функцию события терминала, которая будет срабатывать при каждом изменении данных в свече.

-- событие изменения свечи S и отправка в DLL
function cbCandleS(i) --
     local dt ={}
     local evt =0
     dt = GetCandle(ds_s, FUT_S, i) -- получение данных свечи
     --message("Изменение свечи S")
      a, b = CCS.cvCandleS(dt) -- Вызов функции DLL, отправка данных в DLL
     --message( "CCS.cvCandleS(dt) " .. a)
end

Функция GetCandle() будет вызываться на каждом тике, получать данные, и эти данные будут отправляться в DLL функцией CCS.cvCandleS(dt).
Вот и весь код Lua, необходимый для отправки данных о свече в DLL. Аналогично в DLL отправляются другие данные и массивы данных, такие как стакан, лента сделок, история TOHLCV и пр.
Код, естественно взят из рабочей программы Lua, и уже используется в системе, добавлены только комментарии.

Думаю, на сегодня достаточно. И если материал будет полезен (не забывайте ставить лайки, Дамы и Господа!), то в следующем мы рассмотрим обработку этих данных уже в DLL.

*) — функция определена в документации Quik Qlua.

Литература.
Роберту Иерузалимски: Программирование на языке Lua. Ее можно найти в интернете.

 

  • обсудить на форуме:
  • Quik Lua
★51
30 комментариев
очень познавательно, можете поделиться кодом (если не сложно) на LUA для выставления заявок, лимитных, стопов, чтение данных по уже выставленным заявкам, их снятию :) и тд, кстати, все корректно выставляется?
Уж очень хочется автоматизировать систему по отслеживанию TP и автоматических SL, правда у меня инструмента два.. 
avatar
Присоединяюсь. если можно на почту faradoxe#bk.ru
avatar
А не проще прям в DLL прописать функцию main и там обращаться к данным. И ничего передавать не нужно.

lua_pushcclosure(L, Lua_main, 0); //Добавляет функцию в стек
lua_setglobal(L, «main»); //Регистрирует её в QLua

avatar
Karim, можно и так.
У меня по другому сделано. main() остается в Lua, а бесконечный цикл из main() перенесен в DLL. Получается читаемый код Lua, и более простой, без нагромождений, код DLL.
В общем, это на любителя. 
avatar
3Qu, а у Вас нет инфы,  как пользоваться встроенной системой api
Задавал вопрос на форуме квика ничего толкового не ответили.
Я не программист,  просто пытаюсь автоматизировать свои торговые действия.
Сейчас следующая ситуация, написпл код на питоне,  данные их квика грузятся  в таблицы mysql по odbc,  тут все просто.
Заявки считыааются через tri файл, тоже все просто.
Проблема в том , что в питон у меня цикл по таймеру , скрипт раз в 30 секунд считыаает изменения в таблицах, пишет в три файл. Там тоже таймер,  квик раз в три секунды читает три файл.

Хотелось бы обойтись без этих таймеров. Пытался разобраться что такое апи, на примере телеграме ботов.

Все работает,  пишешь сообщение, скрипт питона его читает и тут же отправляет ответ, там устанавливается внешняя библиотека для обработки событий ,
В моем понимании, скрипт работает как бы в постоянном ожидании какого то input, и реагирует на него

А как это реализовать с квиком,  вообще не понятно куда копать
avatar
Дмитрий К, насколько мне известно в Quik есть только торговое API для подачи заявок через DLL trans2quik. На сайте ARQA есть документация для скачивания. Остальное через Lua — тоже своего рода API.)
С Python, если мне что придет в голову, напишу позже.
avatar
Дмитрий К, не исключаю что для не программиста решение через файлы импорта является одной из самых надёжных для самописных (им самим) связок.

Можете уточнить чем именно вас не устраивает работа через таймер?
У меня долгое время был макрос под Excel, из которого я тупо кидал заявки в текстовом виде — и все работало. Таймер квика был 1 секунда. Общая реакция всей цепочки 4-5сек.

Сейчас на купленным за 100 т.р. Мультичартсом с прямо скажем не самым лучшим хоть и оригинальным квик-коннектором скорость размещения заявок 4-6 секунд. 
В принципе для данных ТС меня вполне устраивает, но буду откровенен — покупая профессиональный продукт рассчитывал на меньшее время. Однако проблема в том, что я не учёл, что квик то никуда не делся. Поэтому никто не даёт вам гарантии, что потратив время и силы вы получите на порядок лучшее решение. В общем, подумайте действительно ли вас текущая схема критически не устраивает.
avatar
Носорог, «Однако проблема в том, что я не учёл, что квик то никуда не делся.»

Квик ни при чем скорее всего. Думаю дело в том что Мультик шлет ордер на первом тике следующего бара. Вообще я бы попинал их техподдержку почему так.
avatar

quant_trader, ну это то да — для мультика (ровно как и для большинства других программ, про которые слышал) — бар заканчивается тогда, когда  получен тик от периода времени нового бара. Еще есть доп вариант  — или если прошел ну очень большой таймаут (к примеру 5 минут при минутном баре).

У мультика конечно есть внутрибарная торговля — обработка каждого тика, хотя в принципе никто не мешает сделать длину бара 1сек или 3 сек. 

Мультик в целом добротный продукт — мне нравится с каждым днем все больше. 90% моих проблем — именно из-за квик-коннектора, который по слухам писал давно ушедший программист, и теперь в его коде мало кто разберется. Как я понял квик технически не понимает те же маркет/стоп приказы — фактически он их эмулирует лимитками по максимальной/минимальной цене, но при этом теряются некоторые логические связи, из-за чего не всегда можно понять по какой причине обратно в торговую систему прилетела сделка. Поэтому автор квик-коннектора обложился паузами — (секунду туда — могет квик что пояснит, пару секунд сюда — могет еще что-то прояснится из таблицы обезличенных сделок, заодно поймем прошел ли наш ордер на бирже), в итоге чтобы собрать полноценную картину мультику и приходится выдерживать паузу в несколько секунд. Я как то уменьшал эти тайминги, так у меня циклически мультик генерил серию ордеров в 16 этажей, потом (задним числом) от квика прилетает информация, что на 5 этаже лифт оказывается должен был кого-то высадить, после чего мультик отменял свои пакеты начиная с 6 и до 16-го, квик опять тупил — и в итоге этот рассинхрон рос как снежный ком, в итоге мультик выводил сообщение «походу мои приказы исполняются с неприменимой задержкой, я останавливаю работу робота». В мультике даже есть опция — не пытаться разобраться с прошлым рассинхроном, если только что квик снова что-то переиначил.  В общем, все очень очень запутанно.

В том числе поэтому я и не рекомендую лишний раз пытаться писать свой софт на низком уровне взаимодействия с квиком — можно потратить очень много времени и сил. Для непрофессионалов взаимодействие через файлы импорта экспорта избавляют от 99% проблем с внутренней кухней. И не всегда в ней виноваты разработчики квика, сам по себе процесс взаимодействия систем в трейдинге — не такая тривиальная задача как кажется. 

Кстати, если кто не знает — мультик написали (и владеют) те же ростовские ребята, что и трейдингвью. Прям гордость за наших :)

 

avatar
Носорог, это не квик тупит, это адаптер Мультика.

Можно попробовать слать ордера прямо из кода робота в файл или даже не в файл и не пользоваться адаптером.
avatar

quant_trader, ну уж нет, там минусов в 100 раз больше, чем плюсов.

Все что я написал выше — казалось непрофессионалных программистов. ИМХО им лучше всего ограничиться работой через текстовый файл, а всю внутреннюю кухню квика оставить на ответственности его разработчиков.

Но если я уже потратил деньги на приобретение продукта, написанного как никак, но в разы более профессиональным программистом чем я, никакого смысла уходить после этого и начинать самому колхозить с тектовым (и даже нетектовыми) взаимодействием — нет. Глюки и неудобства есть в любом софте, машине или человеке. Да, мне хотелось бы чтобы мои сделки на бирже проходили моментально (как раз перед Куклом :), но в реальности я понимаю что я и не работаю в нише высокочатотной торговли и поэтому несколько секунд для моих систем — это нормально. Не в моментальной скорости их фишка. Поэтому свое время и силы я лучше потрачу на поиск новых и оптимизацию текущих ТОРГОВЫХ, а не IT систем. Каждый должен делать свое дело. 

avatar
Носорог, так то вообще все устраивает, работает все как часы.
Я целый год мучался с алтфадиректом со встроенным диспетчером роботов, он (альфадирект) у меня постоянно отваливался от интернета .
Сейчас две недели гоняю каждый день с 10 утра до 24 на амеракциях на спб. Квик вообще надежный, ничем не срубить соединение похоже.

Просто хочется улучшить потому что понятно, что можно улучшить. Если например сигнал на новые заявки приходит только через полчаса,  зачем производить вычисления, далее, я вижу, как в ответ на мои заявки моментально меняются заявки в стакане, причем, учитывая, что это одна акция или облигация на объем 50-1000р, это явно частные мелкие роботы- то есть технически это должно элементарно реализовываться по идее.

Ну просто интересно для себя разобраться 
avatar

Дмитрий К, ну тогда самая бородатая программисткая мудрость-анекдот:

«сынок оно работает? Входит и заходит? НИЧЕГО ТРОГАЙ» :)

avatar
Дмитрий К, стратегическая ошибка с Квиком — прикручивать любимый язык не имеющий готовых коннекторов :)
avatar
quant_trader, воз можно есть смысл изучать с++, но реально, чисто с материальной точки зрения, выгоднее тратить время на разработку эффективных торговых алгоритмов. 
Я за три года смог алгоритмизироаать устойчиво работающих всего 2 шт. Разбираться теперь как это переделать в с++, энтузиазма просто нет

avatar
Дмитрий К, «чисто с материальной точки зрения, выгоднее тратить время на разработку эффективных торговых алгоритмов»

Вот именно. Поэтому мультики/тслабы рулят.
avatar
quant_trader, с готовыми коннекторами возникает еще больше проблем чем с самописными.
У Луа, кстати совершенно простой C-API и для работы с ним особой квалификации не требуется.
avatar
3Qu, зависит от проги. Мультик/тслаб да, Амиброкер нет, там просто интерфейс trans2quik вместо коннектора.

Если хочется самостоятельно получать бары, складировать их в БД, обрабатывать пропуски и докачки то почему бы и нет, но при наличии готовых решений которые надо допилить по отправке ордеров имхо неоптимально. Ну то есть я считаю что проще написать свой коннектор по ордерам для условной проги теханализа а не целиком свой тслаб. Вот как то так.

Это конечно про небыстрых роботов на графике, стаканные или там весь весь рынок смотреть это другая тема, там как раз луа и длл.
avatar
Дмитрий К, я c Питон работаю, но ничего толкового для вас не придумал. Думаю, что пока вам лучше остаться на файловом обмене и попробовать файловый обмен с Lua. Это будет более эффективно и в смысле получения информации из Quik, и в смысле обмена информацией с терминалом. Lua может проверять наличие файла хоть через каждые 0.1 и посылать их по мере поступления инфы. Я не имею в виду отказ от ODBC.
Lua простой язык, и на изучение уйдет макс пару недель. И почитайте вот это. Этот подход я иногда применяю — Коммуникации Lua с внешним миром.
Ничего более умного для Питон в голову н приходит.
avatar
3Qu, чтоб отказаться от таймера, как вариант пришло в голову реализовать сокет соединение, в питоне сервер для приема сообщений, а из луа клиент для отправки,  
Из одного питон скрипта в другой все это реализуется  на более чем элементарно, а вот как запустить клиент из луа скрипта, сходу ничего элементарного не удалось нагуглить, надо вникать в тонкости языка видимо
avatar
Дмитрий К, и такое возможно. Такой вариант тоже имеется, но сделан Луа — сокеты в ДЛЛ — далее что угодно.
avatar
Дмитрий К, Можно из скрипта на питоне подавать через API заявки, если ещё актуально, пишите ([email protected] или ВК в профиле), в лс написать не могу, мало рейтинга.
Никита Драбышевский, на почту написал 
avatar
Очень хорошо. Люблю посты кратко, по делу, без воды и соплей. Хвала такому писателю, который тратит в 100 раз больше времени на написание, чем читатель на чтение!

Всем геям пишущим видосики с балкона (или с маминой дачи) — учиться!
avatar
Turbo Pascal, согласен, хоть сам работаю и пишу под мультичартс и данная информация практической пользы именно мне не даст, но плюсую и аплодирую однозначно!
Побольше бы таких толковых постов на СЛ!


avatar
есть готовые бинды C++ для Quik — Lua, если что
avatar
bwc, конечно есть. Лежат здесь: github.com/elelel/qluacpp.

Примеры, как пользоваться, там тоже есть. Наиболее полная и профессионально выполненая реализация, imho
avatar
quik2dde.ru/viewforum.php?id=14
Здесь есть материал как делать свои DLL на С++ и Delphi / Lazarus для Lua в QUIK.
Уже есть поддержка QUIK 8.5 для C++ примера DLL для Lua
avatar
Добрый день.
Как из QLUA отправить данные в свою DLL вроде понятно. А как получить эти данные в стороннем приложении написанном на C++ я что-то ума не дам. 
Мне необходимо в своей программе получать данные о сделке и инструменте в момент совершения сделки в Quik. И нужна именно реализация через свою dll. Ну то есть QLUA -> DLL -> C++ и все это в реальном времени, не через файлы.
Подскажите с реализацией, я пока в этом новичок.
avatar

теги блога 3Qu

....все тэги



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