Как я и обещал на прошлом уроке, с сегодняшнего дня мы начнем писать робота. Для начала разработаем что-нибудь простенькое, например, робота спредера, который по заданному инструменту смотрит цены в стакане, если спред достаточно большой, то выставляет заявки от лучших цен покупки/продажи с заданным шагом.
Предыдущие статьи:
Qlua для чайников. Часть 1
Qlua для чайников. Часть 2. Циклы
Итак, если цены 1000/1100, а шаг 10, то робот должен выставить заявки по 1010/1090. В случае изменения цен робот должен снимать заявки и выставлять новые. Если какая-то заявка исполнилась или частично исполнилась, то робот должен это учитывать, либо вообще не перевыставлять исполненную заявку, пока не исполниться противоположная, либо выставлять на количество остатка.
Итак, берем наш шаблон. Все лишнее оттуда удаляем:
is_run=true
function main()
while is_run do
sleep(2000)
end
end
function OnStop(stop_flag)
is_run=false
end
|
И начинаем делать первый шаг. А именно, писать код, который бы читал крайние цены из стакана. Все эти данные можно брать из текущей таблицы параметров:
Но стоп! Если мы уже ввели заявки, то крайние цены – это будут цены наших заявок. Тогда нам придется изменить цены заявок, рассчитывая новые цены от их же цен! После чего это повториться и так до тех пор, пока заявки не встретятся. Значит таблица текущих параметров не катит. Надо напрямую обращаться к стакану.
В qlua есть предопределенная функция OnQuote, она вызывается каждый раз, когда меняется стакан. У этой функции два параметра «Код класса» и «Код инструмента», по которому изменилось содержимое стакана. Давайте посмотрим, как работает данная предопределенная функция. Вставим в конец программы вот такие строки:
function OnQuote(class_code, sec_code)
message(class_code.." "..sec_code,1);
end
|
И запустим программу, чтобы посмотреть, как она будет работать:
Итак, это сообщение мы будем видеть каждый раз, когда по какой-либо бумаге будут меняться данные в стакане, причем только по тем бумагам, по которым стакан открыт. Закройте стакан – сообщения прекратятся. Да, это неудобно, но если вы решили программировать под Quik, остается только смириться, принять это как данность и идти дальше.
У нас может быть открыто несколько стаканов. Следовательно, событие могут приходить от каждого из них. Их придется как-то фильтровать. Для этого выберем какую-нибудь бумагу, и будем сравнивать параметры функции OnQuote с выбранной нами бумагой. Но лучше всего сделать это путем указания параметров в начале программы, как я делал это в других моих статьях (
http://robostroy.ru/community/article.aspx?id=765). Вот например так:
p_classcode=«TQBR» --Код класса
p_seccode=«LKOH» --Код инструмента
is_run=true
function main()
while is_run do
sleep(2000)
end
end
function OnStop(stop_flag)
is_run=false
end
function OnQuote(class_code, sec_code)
if class_code==p_classcode and sec_code==p_seccode then
message(class_code.." "..sec_code,1)
end
end
|
И вот мы познакомились с новой конструкцией языка – if. Между операторами if и then прописывается условие. Условий может быть несколько, их можно объединять словами and (И) либо or (ИЛИ). Если условие выполняется, то система выполнит команды между then и end. Иначе пропустит их.
Но нас интересует не значения class_code, sec_code, ибо они нужны только для фильтрации, а непосредственно котировки. Их можно получить при помощи функции getQuoteLevel2.
Сама функция возвращает таблицу стакана в несколько экзотическом виде. Поэтому прежде чем двигаться дальше нам придется научиться с ними работать. Создадим программку, которая после каждого изменения стакана создает файл, куда выводит его содержимое. Для этого просто немного переделаем наш текущий пример, вот как будет выглядеть его текст после переделки:
...
Полная версия статьи, а также все вопросы
robostroy.ru