Данная заметка является введением в основы разработки роботов на встроенной в торговый терминал QUIK виртуальной машине VM LUA.
Немного о языке LUA…
—————————————-
В настоящее время в торговый терминал QUIK встроена виртуальная машина LUA (VM LUA).
Это аналогично виртуальной машине JAVA или виртуальной машине NET.
Выполнение любой программы на языке LUA происходит в два этапа.
На первом этапе, при загрузке скрипта, программа переводится из текстовой формы в байт код.
При этом каждая команда записывается в виде 4 -х байтового кода (формат long -целое число)
Существуют двух и трех-адресные команды.
Достоинством VM LUA является использование обращения к таблицам (массивам) по ссылке. Это позволяет существенно уменьшить требуемый объем памяти и получить высокую скорость исполнения программы.
Как и VM NET, VM LUA имеет встроенный сборщик мусора, что обеспечивает более эффективное использование оперативной памяти.
Следующим достоинством реализации роботов на основе LUA является тот факт, что реализованный механизм получения торговой информации с помощью колбек функций обеспечивает передачу данных в скрипт даже раньше, чем запись этой информации во внутренние таблицы терминала.
Таким образом, при существенном упрощении настройки , обеспечивается практически такая же скорость доступа к данным, как и с помощью интерфейса DDE.
VM LUA работает существенно быстрее, чем портфель, написанный на встроенном языке QPILE.
В дополнение к перечисленным достоинствам, следует указать возможность создания собственных исполняемых библиотек , реализующих сложные алгоритмы вычислений и оптимизации, с использованием для их создания любых языков программирования.
Основы реализации торговых роботов на LUA
————————————————————-
Рассмотрим некоторые особенности реализации торговых алгоритмов.
Программу на QUIK LUA можно представить в виде набора основных функций, которые вызывает терминал QUIK при появлении новой торговой информации или возникновения событий. Такая реализация алгоритма называется событийной.
Например, терминал QUIK получил информацию в таблицу всех сделок о совершении какой-либо сделки . Перед записью информации об этой сделке в свою внутренную таблицу, терминал вызовет функцию в скрипте LUA с именем onAllTrade.
Таким образом, чтобы обработать данную информацию в своем скрипте мы должны написать функцию:
function onAllTrade(cl,se)
….— здесь мы пишем алгоритм обработки информации о сделке
end
При вызове этой функции, QUIK передаст ей значение кода класса (cl) и кода инструмента (se), по которому совершена сделка.
Так как QUIK вызывает эту функцию для всех сделок, по всем инструментам, которые мы указали в настройках терминала, а торговать мы будет, например, лишь индексом RTS, то внутри данной функции необходимо отфильтровать нужный нам инструмент:
function onAllTrade(cl,se)
if se==»RIH4″ then
….— здесь мы пишем алгоритм обработки информации о сделках по индексу
end
end
Для работы программы на LUA в терминале QUIK необходимо написать еще минимум две специальные функции с именами main и onStop.
Приведу примеры этих функций из реально работающей своей программы:
function main()
nkqami.init(); —Инициализация связи с амиброкером
dofile(dirNK..»Nktab.lua«) — Загрузка графического интерфейса с пользователем
Load_ini(fileName); — Загрузка исходных данных робота
init(); — Чтение существующей информации из таблиц терминала
restore(nk.robot); — обновить таблицу робота
start=true — установить флаг — «начало работы «
nkcom.ResetEvent(event); — сбросить системный флаг потока
nkcom.WaiteEvent(event,-1); — ожидание системного события
for idx,t in pairs(nk) do
if type(t)==»table» and t.id~=nil then DestroyTable(t.id); end;
end;
end
————————
function OnStop(stop_flag) — вызывается при закрытии скрипта в окне скриптов
nkcom.SetParent(); — установить системный флаг потока
Save_ini(fileName) — сохранить рабочие данные робота
nkqami.close(); —закрытие связи с Амиброкером
for idx,t in pairs(nk) do
if type(t)==»table» and t.id~=nil then DestroyTable(t.id); end;
end;
start=false;
nkcom.SetEvent(event);
nkcom.CloseHandle(EventNKwindow);
end
Функция onStop будет вызвана лишь один раз, если мы закроем скрипт, нажав на кнопку «остановить» в окне QUIK запуска скриптов.
Функция main вызывается терминалом QUIK при запуске скрипта.
Данная функция запускается в отдельном потоке и в простейшем случае содержит бесконечный пустой цикл.
Все остальные функции исполняются в потоке терминала QUIK.
В моем варианте реализации , функция main тоже исполняется лишь один раз.
Вернее сказать, используя системные события, я останавливаю отдельный поток и ,таким образом, вообще не загружаю процессор на исполнение циклов ожидания.
Вам же, в своих программах, вместо моих операторов внутри цикла while необходимо написать вызов функции sleep(200). Эта функция будет останавливать дополнительный поток на 200 ms при многократном исполнении цикла.
Вот такими будут функции main и onStop в простейшем варианте:
function main()
start=true — установить флаг — «начало работы «
while start do — цикл
sleep(200) — останов потока на 200 мs
end
end
————————
function OnStop(stop_flag) — вызывается при закрытии скрипта в окне скриптов
start=false;
end
Первоначально, когда Вы лишь осваиваете работу в LUA, рекомендую реализовывать весь торговый алгоритм внутри колбек-функций.
В документации имена этих функций начинаются с on…
Когда Вы хорошо освоите основы программирования с использованием событийной модели, можно переносить часть вычислений в функцию main, либо создавать новые потоки для ускорения расчетов, как это сделано у меня. Конечно, эффект ускорения от многопоточной реализации торгового алгоритма будет лишь при условии, что у Вас многоядерный процессор либо кластер.
Про потоки…
——————————-
Потоками назваются ядра процессора, либо процессоры в кластере.
Если у Вас многоядерный процессор, то можно реализовать многопотоковые вычисления на LUA и таким образом организовать параллельные вычисления и ускорить расчеты.
Кроме этого, я в своих разработках реализовал колбек функции обработки событий от программ технического анализа, в частности от Амиброкера, а в Амиброкере — колбек функции обработки событий от терминала QUIK.
———————————-
Хочу заметить, что возможность подлючения к своей программе различных исполняемых библиотек практически снимает какие-либо ограничения на сложность реализуемых алгоритмов.
Подключение дополнительных библиотек в виде DLL модулей — это стандартный прием , используемый в реализации всех, без исключения, программ, работающих под управлением OC Windows.