Заметка

Роботы на qlua: разбираемся с новыми возможностями Quik

  4  

Некоторое время назад в Quik появился встроенный язык программирования qlua, который расширяет возможности пользователей в плане создания торговых роботов под эту платформу. Сравним возможности qlua с возможностями qpile и напишем простого робота.

Случайно узнал, что в Квике появился новый язык программирования, на котором можно писать торговых роботов – qlua. Если честно, мне никогда особо не нравился qpile по следующим причинам:

  • Отсутствие нормального отладчика, что делает процесс отглючивания роботов весьма и весьма муторным и трудоемким.
  • Непохожесть многих конструкций qpile на такие распространенные языки, как C, Pascal и их множественные диалекты. Из-за этого сам процесс программирования становиться очень неудобным и трудоемким. То, что легко написать, к примеру, на Pascal, на qpile пишется через «танцы с бубнами».
  • В qpile для того чтобы добавить в коллекцию элемент нужно вызвать функцию добавления в коллекцию и результат этот функции присвоить коллекции. Это неудобно и провоцирует ошибки, которые потом из-за плохого отладчика трудно находить.
  • Очень неудобно отсутствие локальных переменных. В свое время я находил выход из этой ситуации – если в какой-то функции надо использовать внутренние переменные, которые не должны испортить общие данные, то такую переменную обозначал префиксом, сокращенным от имени процедуры. Хотя это тоже очень неудобно. Согласитесь, это извращение, называть переменную aoI (если она внутри функции AddOrder) или  robCurrentPrice (если функция называется ReadOrderBook). Но другого выхода, к сожалению, нет.

В общем, новость я воспринял с энтузиазмом, надеясь, что в новом языке исправлены эти недочеты.

Итак свое знакомство с миром qlua я начал с того, что слегка «погуглил» эту тему. И вот что узнал: qlua – это адаптирвоанный под Quik язык lua, который поддерживается новыми версиями Quik. Сам язык lua по своим возможностям и идеологии ближе всего к JavaScript, но отличается гораздо более гибким конструкциями. Скажу сразу, что это не самый лучший вариант, так как не содержит понятий класса и объекта в явном виде (лучше бы они взяли за основу C# или, на худой конец, Object Pascal).  Однако это все же намного более продвинутый язык, чем пресловутый qpile.

Итак, первым делом я решил опробовать на qlua простейшего робота (учебный пример), торгующего по пересечению двух мувингов (быстрый пересекает медленный снизу вверх – покупка, сверху вниз – продажа). Полный код робота прикрепленным файлом.

Принцип работы робота следующий: в цикле вызывается тело робота:

function main()

      while is_run do

            sleep(2000)

            robot()

      end

end

Вызов происходит с задержкой, указанной в параметрах функции sleep (в миллисекундах).  Это, кстати, уже фишка qlua, на qpile интервал вызова робота мы могли задать только в секундах и только в настройке портфеля,  а тут этот можно делать программно и программно же менять прямо в ходе работы робота.

Теперь посмотрим само тело робота:

function robot()

      local N1=getNumCandles("MA1")

      local N2=getNumCandles("MA2")

      local N=getNumCandles("Price")

      t1,n1,i1=getCandlesByIndex("MA1", 0, N1-3, 2)

      t2,n2,i2=getCandlesByIndex("MA2", 0, N2-3, 2)

      t,n,i=getCandlesByIndex("Price", 0, N-1, 1)

     

      --сигнал на продажу (первый мувинг пересекает второй сверху вниз

      if t1[0].close>t2[0].close and t1[1].close<t2[1].close then

            Trade("S",count+p_count,t[0].close-p_spread)

      end

     

      --сигнал на покупку (первый мувинг пересекает второй снизу вверх

      if t1[0].close<t2[0].close and t1[1].close>t2[1].close then

            Trade("B",p_count-count,t[0].close+p_spread)

      end

     

end

Оно читает данные с графиков и текущие котировки, производит проверку сигналов и вызывает процедуру trade, которая, собственно говоря, и совершат сделку, вызывая типовую функцию sendTransaction:

function Trade(a_oper,a_count,a_price)

      if a_count>0 then

            t = {

                        ["CLASSCODE"]=p_classcode,

                        ["SECCODE"]=p_seccode,

                        ["ACTION"]="NEW_ORDER",

                        ["ACCOUNT"]=p_account,

                        ["CLIENT_CODE"]=p_clientcode,

                        ["TYPE"]="L",

                        ["OPERATION"]=a_oper,

                        ["QUANTITY"]=tostring(a_count),

                        ["PRICE"]=tostring(a_price),

                        ["EXPIRY_DATE"]="GTS",

                        ["TRANS_ID"]="1"

                  }

            res=sendTransaction(t)

            message("Количество до "..tostring(count).."  количество сделки "..tostring(a_count).."  тип операции"..a_oper,1)

            if a_oper=="B" then

                  count=count+a_count

            else

                  count=count-a_count

            end

            message("Количество после "..tostring(count),1)

      end

end

Так как это всего лишь учебный пример, то контроль позиции осуществляется через глобальную переменную count, которая соответствующим образом меняется после каждой сделки и показывает, сколько у нас на балансе инструментов. Исходя из нее мы и вычисляем, сколько бумаг нам надо купить или продать.

Параметры робота задаем в самом начале текста (инструмент, размер позиции и так далее):

--Параметры:

p_classcode="SPBFUT" --Код класса

p_seccode="GZM3" --Код инструмента

p_account="SPBFUT005H3" --Код счета

p_clientcode="SPBFUT005H3" --Клиентский код

p_count=2 --Размер позиции

p_spread=100 --Проскальзывание

Итак, как видим, все процедуры те же самые, что и в qpile, только добавился синтаксис lua и плюс еще кое какие фишки, а именно:

  • Наличие глобальных и локальных переменных.
  • Более удобная работа со структурами данных, в частности, те же самые таблицы. Есть возможность обратиться по индексу или перебрать через цикл с итератором.
  • Подключение внешних компонент,  написанных на других языках программирования.
  • Многопоточность, использование callback функций.
  • Возможность обращения к свечам по номеру (очень полезная, кстати, вещь, помню как мучился без нее в qpile!)

Тем не менее, в qlua перешло множество досадных недоработок qpile, и это сводит на нет все приятные впечатления от нового языка:

  • Отладчика нет вообще.
  • По-прежнему, чтобы получить данные с графика, его необходимо открыть. Иными словами, написал робота, но, прежде чем его запустить, делаешь кучу настрое ручками. И ладно, если используется только 1-2 графика, а если, например, с десяток, это может доставить немалы неудобства.
Прикрепленные файлы

·   Код робота на qlua.rar

Комментарии

s_mike — 5 июня 2013 г.

Локальные переменные в qpile: http://www.bot4sale.ru/blog-menu/m4/m4-blog-list/253-local-vars.html

Статические переменные в qpile: http://www.bot4sale.ru/blog-menu/m4/m4-blog-list/285-qpile-static.html

Оператор Switch в qpile: http://www.bot4sale.ru/blog-menu/m4/m4-blog-list/243-qpile-switch.html

Параметры функций по умолчанию в qpile: http://www.bot4sale.ru/blog-menu/m4/m4-blog-list/246-qpile-default-parameters.html

Оператор With в qpile: http://www.bot4sale.ru/blog-menu/m4/m4-blog-list/244-fill-maps.html

а также циклы while, do, begin.end и проч.

1 +

megabax — 5 июня 2013 г.

s_mike, а при чем здесь qpile?

1 +

s_mike — 5 июня 2013 г.

["PRICE"]=tostring(a_price)

Неправильно. В общем случае строка должна формироваться с требуемой точностью, а не по правилам tostring().

0 +

tujh — 8 октября 2013 г.

Здравствуйте скачал исходный код робота и не знаю как завести его в квик. Помогите пожалуйста. Спасибо.

0 +

drghestykmb — 23 июня 2014 г.

аттемпт нил валуе пишет.на блокг\нот написал.ввел значения контракта.

0 +

drghestykmb — 8 июля 2014 г.

появился встроенный язык программирования qlua".программа работает.маленькая.

0 +

robotqlua — 28 октября 2014 г.

Добрый день!
Прошу открыть доступ к прикрепленному файлу робота по пересечению двух средних (телефон начинается не с +7).
Спасибо.

0 +

orekton — 29 октября 2014 г.

robotqlua, качайте

0 +

Андрей54 — 1 января 2016 г.

Здраствуйте,а можно также з откритим итересом зделать как з мувингами,если можно то как?

0 +

logan1085 — 3 января 2016 г.

вот интересный вопрос вы объявляете функцию Trade после функии robot, но используете её в теле функции робота, не возникнет ли в данном случае ошибки из-за порядка представления функции?
обычно же прежде чем функцию использовать надо её объявить? а у вас сначала используете в коде, потом объявляете, тестировали работу робота?
спасибо.

0 +

drghestykmb — 1 мая 2016 г.

что скажете о одном цикле и бесконечности
function OnStop(stop_flag)
is_run=false
--stop_flag=1

0 +

drghestykmb — 1 мая 2016 г.

["EXPIRY_DATE"]="TODAY" сейчас биржа работает без другого ...

0 +

Написать комментарий

Чтобы написать комментарий, необходимо авторизоваться.

Написать администратору