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