Блог им. 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. Ее можно найти в интернете.
Уж очень хочется автоматизировать систему по отслеживанию TP и автоматических SL, правда у меня инструмента два..
lua_pushcclosure(L, Lua_main, 0); //Добавляет функцию в стек
lua_setglobal(L, «main»); //Регистрирует её в QLua
У меня по другому сделано. main() остается в Lua, а бесконечный цикл из main() перенесен в DLL. Получается читаемый код Lua, и более простой, без нагромождений, код DLL.
В общем, это на любителя.
Задавал вопрос на форуме квика ничего толкового не ответили.
Я не программист, просто пытаюсь автоматизировать свои торговые действия.
Сейчас следующая ситуация, написпл код на питоне, данные их квика грузятся в таблицы mysql по odbc, тут все просто.
Заявки считыааются через tri файл, тоже все просто.
Проблема в том , что в питон у меня цикл по таймеру , скрипт раз в 30 секунд считыаает изменения в таблицах, пишет в три файл. Там тоже таймер, квик раз в три секунды читает три файл.
Хотелось бы обойтись без этих таймеров. Пытался разобраться что такое апи, на примере телеграме ботов.
Все работает, пишешь сообщение, скрипт питона его читает и тут же отправляет ответ, там устанавливается внешняя библиотека для обработки событий ,
В моем понимании, скрипт работает как бы в постоянном ожидании какого то input, и реагирует на него
А как это реализовать с квиком, вообще не понятно куда копать
С Python, если мне что придет в голову, напишу позже.
Можете уточнить чем именно вас не устраивает работа через таймер?
У меня долгое время был макрос под Excel, из которого я тупо кидал заявки в текстовом виде — и все работало. Таймер квика был 1 секунда. Общая реакция всей цепочки 4-5сек.
Сейчас на купленным за 100 т.р. Мультичартсом с прямо скажем не самым лучшим хоть и оригинальным квик-коннектором скорость размещения заявок 4-6 секунд.
В принципе для данных ТС меня вполне устраивает, но буду откровенен — покупая профессиональный продукт рассчитывал на меньшее время. Однако проблема в том, что я не учёл, что квик то никуда не делся. Поэтому никто не даёт вам гарантии, что потратив время и силы вы получите на порядок лучшее решение. В общем, подумайте действительно ли вас текущая схема критически не устраивает.
Квик ни при чем скорее всего. Думаю дело в том что Мультик шлет ордер на первом тике следующего бара. Вообще я бы попинал их техподдержку почему так.
quant_trader, ну это то да — для мультика (ровно как и для большинства других программ, про которые слышал) — бар заканчивается тогда, когда получен тик от периода времени нового бара. Еще есть доп вариант — или если прошел ну очень большой таймаут (к примеру 5 минут при минутном баре).
У мультика конечно есть внутрибарная торговля — обработка каждого тика, хотя в принципе никто не мешает сделать длину бара 1сек или 3 сек.
Мультик в целом добротный продукт — мне нравится с каждым днем все больше. 90% моих проблем — именно из-за квик-коннектора, который по слухам писал давно ушедший программист, и теперь в его коде мало кто разберется. Как я понял квик технически не понимает те же маркет/стоп приказы — фактически он их эмулирует лимитками по максимальной/минимальной цене, но при этом теряются некоторые логические связи, из-за чего не всегда можно понять по какой причине обратно в торговую систему прилетела сделка. Поэтому автор квик-коннектора обложился паузами — (секунду туда — могет квик что пояснит, пару секунд сюда — могет еще что-то прояснится из таблицы обезличенных сделок, заодно поймем прошел ли наш ордер на бирже), в итоге чтобы собрать полноценную картину мультику и приходится выдерживать паузу в несколько секунд. Я как то уменьшал эти тайминги, так у меня циклически мультик генерил серию ордеров в 16 этажей, потом (задним числом) от квика прилетает информация, что на 5 этаже лифт оказывается должен был кого-то высадить, после чего мультик отменял свои пакеты начиная с 6 и до 16-го, квик опять тупил — и в итоге этот рассинхрон рос как снежный ком, в итоге мультик выводил сообщение «походу мои приказы исполняются с неприменимой задержкой, я останавливаю работу робота». В мультике даже есть опция — не пытаться разобраться с прошлым рассинхроном, если только что квик снова что-то переиначил. В общем, все очень очень запутанно.
В том числе поэтому я и не рекомендую лишний раз пытаться писать свой софт на низком уровне взаимодействия с квиком — можно потратить очень много времени и сил. Для непрофессионалов взаимодействие через файлы импорта экспорта избавляют от 99% проблем с внутренней кухней. И не всегда в ней виноваты разработчики квика, сам по себе процесс взаимодействия систем в трейдинге — не такая тривиальная задача как кажется.
Кстати, если кто не знает — мультик написали (и владеют) те же ростовские ребята, что и трейдингвью. Прям гордость за наших :)
Можно попробовать слать ордера прямо из кода робота в файл или даже не в файл и не пользоваться адаптером.
quant_trader, ну уж нет, там минусов в 100 раз больше, чем плюсов.
Все что я написал выше — казалось непрофессионалных программистов. ИМХО им лучше всего ограничиться работой через текстовый файл, а всю внутреннюю кухню квика оставить на ответственности его разработчиков.
Но если я уже потратил деньги на приобретение продукта, написанного как никак, но в разы более профессиональным программистом чем я, никакого смысла уходить после этого и начинать самому колхозить с тектовым (и даже нетектовыми) взаимодействием — нет. Глюки и неудобства есть в любом софте, машине или человеке. Да, мне хотелось бы чтобы мои сделки на бирже проходили моментально (как раз перед Куклом :), но в реальности я понимаю что я и не работаю в нише высокочатотной торговли и поэтому несколько секунд для моих систем — это нормально. Не в моментальной скорости их фишка. Поэтому свое время и силы я лучше потрачу на поиск новых и оптимизацию текущих ТОРГОВЫХ, а не IT систем. Каждый должен делать свое дело.
Я целый год мучался с алтфадиректом со встроенным диспетчером роботов, он (альфадирект) у меня постоянно отваливался от интернета .
Сейчас две недели гоняю каждый день с 10 утра до 24 на амеракциях на спб. Квик вообще надежный, ничем не срубить соединение похоже.
Просто хочется улучшить потому что понятно, что можно улучшить. Если например сигнал на новые заявки приходит только через полчаса, зачем производить вычисления, далее, я вижу, как в ответ на мои заявки моментально меняются заявки в стакане, причем, учитывая, что это одна акция или облигация на объем 50-1000р, это явно частные мелкие роботы- то есть технически это должно элементарно реализовываться по идее.
Ну просто интересно для себя разобраться
Дмитрий К, ну тогда самая бородатая программисткая мудрость-анекдот:
«сынок оно работает? Входит и заходит? НИЧЕГО ТРОГАЙ» :)
Я за три года смог алгоритмизироаать устойчиво работающих всего 2 шт. Разбираться теперь как это переделать в с++, энтузиазма просто нет
Вот именно. Поэтому мультики/тслабы рулят.
У Луа, кстати совершенно простой C-API и для работы с ним особой квалификации не требуется.
Если хочется самостоятельно получать бары, складировать их в БД, обрабатывать пропуски и докачки то почему бы и нет, но при наличии готовых решений которые надо допилить по отправке ордеров имхо неоптимально. Ну то есть я считаю что проще написать свой коннектор по ордерам для условной проги теханализа а не целиком свой тслаб. Вот как то так.
Это конечно про небыстрых роботов на графике, стаканные или там весь весь рынок смотреть это другая тема, там как раз луа и длл.
Lua простой язык, и на изучение уйдет макс пару недель. И почитайте вот это. Этот подход я иногда применяю — Коммуникации Lua с внешним миром.
Ничего более умного для Питон в голову н приходит.
Из одного питон скрипта в другой все это реализуется на более чем элементарно, а вот как запустить клиент из луа скрипта, сходу ничего элементарного не удалось нагуглить, надо вникать в тонкости языка видимо
Всем геям пишущим видосики с балкона (или с маминой дачи) — учиться!
Побольше бы таких толковых постов на СЛ!
Примеры, как пользоваться, там тоже есть. Наиболее полная и профессионально выполненая реализация, imho
Здесь есть материал как делать свои DLL на С++ и Delphi / Lazarus для Lua в QUIK.
Уже есть поддержка QUIK 8.5 для C++ примера DLL для Lua
Как из QLUA отправить данные в свою DLL вроде понятно. А как получить эти данные в стороннем приложении написанном на C++ я что-то ума не дам.
Мне необходимо в своей программе получать данные о сделке и инструменте в момент совершения сделки в Quik. И нужна именно реализация через свою dll. Ну то есть QLUA -> DLL -> C++ и все это в реальном времени, не через файлы.
Подскажите с реализацией, я пока в этом новичок.