3Qu
3Qu личный блог
04 февраля 2020, 13:54

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

Начал вчера работы по реализации "Брошенной стратегии". Хорошо когда есть наработки: взял готовые куски кода, немного доработал под новые нужды, соединил их вместе и уже все готово — почти все необходимые данные передаются в 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. Ее можно найти в интернете.

 

30 Комментариев
  • iuiu
    04 февраля 2020, 14:17
    очень познавательно, можете поделиться кодом (если не сложно) на LUA для выставления заявок, лимитных, стопов, чтение данных по уже выставленным заявкам, их снятию :) и тд, кстати, все корректно выставляется?
    Уж очень хочется автоматизировать систему по отслеживанию TP и автоматических SL, правда у меня инструмента два.. 
  • Евгений
    04 февраля 2020, 15:38
    Присоединяюсь. если можно на почту faradoxe#bk.ru
  • Karim
    04 февраля 2020, 17:26
    А не проще прям в DLL прописать функцию main и там обращаться к данным. И ничего передавать не нужно.

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

  • Turbo Pascal
    04 февраля 2020, 17:49
    Очень хорошо. Люблю посты кратко, по делу, без воды и соплей. Хвала такому писателю, который тратит в 100 раз больше времени на написание, чем читатель на чтение!

    Всем геям пишущим видосики с балкона (или с маминой дачи) — учиться!

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

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