Разное

Учебник qlua: QLua основы | QUIKBOT . EVOLUTION …

Содержание

QLua основы | QUIKBOT . EVOLUTION …

Чтобы скомпилировать(получить байт-код) Ваш скрипт, Вам понадобится файл luac.exe, находится в корневом каталоге Вашей LuaForWindows, если у Вас ее еще нет, то установите отсюда code.google.com
Затем, положите в папку с Вашим скриптом копию файла luac.exe, создайте в этой папке текстовый файл, добавьте в него строчку:
luac.exe -o MyScript.luac MyScript.lua
«MyScript» замените на имя Вашего скрипта и сохраните этот файл под любым названием, главное с расширением .bat
Теперь выполните этот файл и в папке появится еще один файл с расширением .luac, перекиньте его куда-нибудь, поменяйте его расширение на .lua и запускайте в терминале как обычный скрипт.

Тот же результат можно получить программным путем:

1
2
3
local f = io.open(FilePathLuac, 'wb')        -- FilePathLuac по этому пути будет создан скомпилированный файл, например: "C:\\MyScript.lua"
f:write(string.dump(loadfile(FilePathSrc)))  -- FilePathSrc путь к Вашему исходному файлу .lua
f:close()

Если у Вас появились какие-то вопросы, задайте их в комментариях под статьей !!!

Файл CSV-формата это обычный текстовый файл, с которым Excel и аналогичные программы могут работать как с таблицей. Каждая строка таблицы в этом файле записывается как новая строка со знаком переноса в конце, а значения полей разделены между собой каким-то символом, чаще «;». В самой первой строке такого файла можно (не обязательно) указать названия столбцов, так же через «;».

Ниже приведен пример создания такого файла и записи в него данных о совершенных сделках средствами QLua(Lua):
Смотреть полностью…

Сейчас в QLua появилась встроенная функция bit.test, которая решает ту же задачу, т.е. смысла в использовании функции CheckBit больше нет !

true — флаг установлен
false — флаг не установлен

-- Функция проверяет установлен бит, или нет (возвращает true, или false)
CheckBit = function(flags, _bit)
   -- Проверяет, что переданные аргументы являются числами
   if type(flags) ~= "number" then error("Ошибка!!! Checkbit: 1-й аргумент не число!") end
   if type(_bit) ~= "number" then error("Ошибка!!! Checkbit: 2-й аргумент не число!") end
 
   if _bit == 0 then _bit = 0x1
   elseif _bit == 1 then _bit = 0x2
   elseif _bit == 2 then _bit = 0x4
   elseif _bit == 3 then _bit  = 0x8
   elseif _bit == 4 then _bit = 0x10
   elseif _bit == 5 then _bit = 0x20
   elseif _bit == 6 then _bit = 0x40
   elseif _bit == 7 then _bit  = 0x80
   elseif _bit == 8 then _bit = 0x100
   elseif _bit == 9 then _bit = 0x200
   elseif _bit == 10 then _bit = 0x400
   elseif _bit == 11 then _bit = 0x800
   elseif _bit == 12 then _bit  = 0x1000
   elseif _bit == 13 then _bit = 0x2000
   elseif _bit == 14 then _bit  = 0x4000
   elseif _bit == 15 then _bit  = 0x8000
   elseif _bit == 16 then _bit = 0x10000
   elseif _bit == 17 then _bit = 0x20000
   elseif _bit == 18 then _bit = 0x40000
   elseif _bit == 19 then _bit = 0x80000
   elseif _bit == 20 then _bit = 0x100000
   end
 
   if bit.band(flags,_bit ) == _bit then return true
   else return false end
end

Пример использования

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
Run = true;
 
function main()
   -- ОСНОВНОЙ ЦИКЛ
   while Run do
      sleep(500);
   end;
end;
 
function OnOrder(order)
   --бит 0 (0x1)     Заявка активна, иначе – не активна  
   --бит 1 (0x2)     Заявка снята. Если флаг не установлен и значение бита «0» равно «0», то заявка исполнена  
   --бит 2 (0x4)     Заявка на продажу, иначе – на покупку. Данный флаг для сделок и сделок для исполнения определяет направление сделки (BUY/SELL)  
   --бит 3 (0x8)     Заявка лимитированная, иначе – рыночная  
   --бит 4 (0x10)    Разрешить / запретить сделки по разным ценам  
   --бит 5 (0x20)    Исполнить заявку немедленно или снять (FILL OR KILL)  
   --бит 6 (0x40)    Заявка маркет-мейкера. Для адресных заявок – заявка отправлена контрагенту  
   --бит 7 (0x80)    Для адресных заявок – заявка получена от контрагента  
   --бит 8 (0x100)   Снять остаток  
   --бит 9 (0x200)   Айсберг-заявка  
 
   -- Проверка бита 2
   if CheckBit(order.flags, 2) then 
      message("Заявка на продажу"); 
   else 
      message("Заявка на покупку"); 
   end;
end;
 
function OnStop()
   Run = false;
end;
 
-- Функция проверяет установлен бит, или нет (возвращает true, или false)
CheckBit = function(flags, _bit)
   -- Проверяет, что переданные аргументы являются числами
   if type(flags) ~= "number" then error("Ошибка!!! Checkbit: 1-й аргумент не число!") end
   if type(_bit) ~= "number" then error("Ошибка!!! Checkbit: 2-й аргумент не число!") end
 
   if _bit == 0 then _bit = 0x1
   elseif _bit == 1 then _bit = 0x2
   elseif _bit == 2 then _bit = 0x4
   elseif _bit == 3 then _bit  = 0x8
   elseif _bit == 4 then _bit = 0x10
   elseif _bit == 5 then _bit = 0x20
   elseif _bit == 6 then _bit = 0x40
   elseif _bit == 7 then _bit  = 0x80
   elseif _bit == 8 then _bit = 0x100
   elseif _bit == 9 then _bit = 0x200
   elseif _bit == 10 then _bit = 0x400
   elseif _bit == 11 then _bit = 0x800
   elseif _bit == 12 then _bit  = 0x1000
   elseif _bit == 13 then _bit = 0x2000
   elseif _bit == 14 then _bit  = 0x4000
   elseif _bit == 15 then _bit  = 0x8000
   elseif _bit == 16 then _bit = 0x10000
   elseif _bit == 17 then _bit = 0x20000
   elseif _bit == 18 then _bit = 0x40000
   elseif _bit == 19 then _bit = 0x80000
   elseif _bit == 20 then _bit = 0x100000
   end
 
   if bit.band(flags,_bit ) == _bit then return true
   else return false end
end

Если у Вас появились какие-то вопросы, задайте их в комментариях под статьей !!!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
-- Флаг поддержания работы скрипта
IsRun = true;
 
function main()
   -- Пытается открыть файл в режиме "чтения/записи"
   f = io.open(getScriptPath().."\\Test.txt","r+");
   -- Если файл не существует
   if f == nil then 
      -- Создает файл в режиме "записи"
      f = io.open(getScriptPath().."\\Test.txt","w"); 
      -- Закрывает файл
      f:close();
      -- Открывает уже существующий файл в режиме "чтения/записи"
      f = io.open(getScriptPath().."\\Test.txt","r+");
   end;
   -- Записывает в файл 2 строки
   f:write("Line1\nLine2"); -- "\n" признак конца строки
   -- Сохраняет изменения в файле
   f:flush();
   -- Встает в начало файла 
      -- 1-ым параметром задается относительно чего будет смещение: "set" - начало, "cur" - текущая позиция, "end" - конец файла
      -- 2-ым параметром задается смещение
   f:seek("set",0);
   -- Перебирает строки файла, выводит их содержимое в сообщениях
   for line in f:lines() do message(tostring(line));end
   -- Закрывает файл
   f:close();
   -- Цикл будет выполнятся, пока IsRun == true
   while IsRun do
      sleep(100);
   end;   
end;
 
function OnStop()
   IsRun = false;
end;

Если у Вас появились какие-то вопросы, задайте их в комментариях под статьей !!!

Во время работы терминала QUIK в нем происходят различные события, такие, как приход новой обезличенной сделки, выставление заявки, сработал стоп-ордер и т.п. Для того, чтобы своевременно и определенным образом реагировать на эти события, в скрипте QLua можно использовать функции обратного вызова, которые будут выполнять блок кода, расположенного внутри них, в тот момент, когда это событие произойдет.

Для каждого определенного события есть своя предопределенная разработчиками QLua функция!Смотреть полностью…

isConnected()   — возвращает 1, если QUIK подключен к серверу и 0, если не подключен

getScriptPath()   — возвращает путь, по которому находится скрипт, без последнего обратного слэша («\»), например, «C:\Program Files (x86)\Info\MyLua»

getInfoParam()   — возвращает значение параметра из окна:«Связь» -> «Информационное окно…»
Смотреть полностью…

Для приведения типов в QLua(Lua) служат всего 2 функции:

tostring()   — принимает любой параметр и конвертирует его в строку в подходящем формате, для применения конкретного формата, используйте функцию string.format

tonumber()   — пытается преобразовать переданный параметр в число, иначе возвращает nil

Стандартные арифметические операции:
«+» — сложение,
«-« — вычитание,
«/» — деление,
«*» — умножение,
«%» — остаток от деления (5%2 == 1).

   math.abs (x) — Модуль x.

   math.acos(x) — Возвращает арккосинус x

   math.asin(x) — Возвращает арксинус x (в радианах).

   math.atan(x) — Возвращает арктангенс x (в радианах).

   math.atan2(x, y) — Возвращает арктангенс x/y (в радианах), но использует знаки обоих параметров для вычисления «четверти» на плоскости. (Также корректно обрабатывает случай когда y равен нулю.)Смотреть полностью…

Материал статьи взят здесь: http://www.bot4sale.ru/blog-menu/qlua/spisok-statej/368-lua-time.html

Дата/время в QLua(Lua) может быть представлено либо в виде секунд, прошедших с полуночи 1 января 1970 года, либо в виде таблицы, имеющей следующие поля:

   year — год (четыре цифры)
   month — месяц (1 – 12)
   day — день (1 – 31)
   hour — час (0 – 23)
   min — минуты (0 – 59)
   sec — секунды (0 – 59)
   wday — день недели (1 — 7), воскресенью соответствует 1
   yday — день года
   isdst — флаг дневного времени суток, тип booleanСмотреть полностью…

Qlua для чайников. Часть 1

Многие хотели бы научиться писать биржевых роботов или хотя бы автоматизировать некоторые свои биржевые операции, но пугаются самого процесса программирования, считая его чем-то сложным. Эта статья написана для того, что бы помочь тем, кто только начинает программировать. Вы сами увидите, что на самом деле тут все просто.
Прежде чем приступить к уроку, хочу сказать пару слов о языке программирования qlua, который мы будем изучать. На сегодняшний день этот язык – самый удобный и доступный способ что-либо автоматизировать для начинающих программистов. Язык qlua гораздо лучше и удобнее его предшественника – qpile, он содержит больше возможностей, и роботов, написанных на нем, можно сделать гораздо боле гибкими. Что особо радует, так это, например, наличие так называемых CALLBACK функций (функций обратного вызова), благодаря которым появилась возможность легко писать роботов, реагирующих на разные события: изменение статуса заявки, приход сделки и т. д. (см.  статью  robostroy.ru/community/article.aspx?id=765).

Итак, начнем. Для начала мы просто возьмем и создадим программу, которая просто выведет на экран сообщение «Hello, World!». Очень многие начинали именно с этого. Вот текст этой очень и очень простой программы:

message(«Hello, World!»,1)

Текст программы можно набрать в блокноте:
 
Но лучше, конечно, воспользоваться специализированной программой типа «Notepad++», там есть даже подсветка синтаксиса:
 
Обратите внимание, что сохранять файл нужно обязательно с расширением lua.
Итак, программа набрана, запускаем ее. Для этого идем в меню «Таблицы» -> «Lua» -> «Доступные скрипты».
 
У нас откроется вот такое окошко:
 
Жмем кнопочку добавить, выбираем там наш файл:
 
Он появился в списке доступных скриптов:
 
Выделяем его, жмем на кнопочку «Запустить» и видим результат:
 
Поздравляю, вы написали свою первую программу. Просто, не правда ли?
Но слышу разочарованные вздохи. Несмотря на просто изумительную простоту, наша программа абсолютно бесполезна. Ну что я могу сказать? Наберитесь терпения! Сейчас мы научится делать более сложные вещи.
Итак, давайте попробуем ввести заявку. Создаем новый скрипт (файл lua) вот с таким текстом:

t = {

            [«CLASSCODE»]=«TQBR»,

            [«SECCODE»]=«LKOH»,

            [«ACTION»]=«NEW_ORDER»,

            [«ACCOUNT»]=«L01-00000F00»,

            [«CLIENT_CODE»]=«52134»,

            [«TYPE»]=«L»,

            [«OPERATION»]=«B»,

            [«QUANTITY»]=«1»,

            [«PRICE»]=«1950»,

            [«TRANS_ID»]=«1»

      }

res=sendTransaction(t)

message(res,1)

Это программа чуть-чуть сложнее, поэтому я подробно сейчас разберу ее. Итак, сначала у нас идет строка t={…
t – это переменная. Она хранит в себе какое-то значение (число, строку, массив, таблицу, какой либо специальный объект или ничего не хранит, если ничего ей не присваиваем). В данном примере мы переменной t присваиваем целую структуру. У этой структуры есть поля. Они указываются в квадратных скобках, после них идет знак «=» и то, чему они равны. Такие пары перечисляются через запятую. Первое поле CLASSCODE. Это код класса. Его можно посмотреть, например, в текущей таблице параметров:
 
В нашем случае мы используем код класса акций ЛУКОЙЛ.
Саму текущую таблицу параметров можно открыть через меню «Таблица» -> «Текущая таблица».
 
В этой таблице необходимо настроить колонки, которые мы хотим видеть:
 
Следующее поле SECCODE – это код бумаги, в данном случае код ЛУКОЙЛа, так же смотрим его в текущей таблице параметров:
 
Поле ACTION – это действие, которое мы производим. В нашем случае это NEW_ORDER – новая заявка.
Поле ACCOUNT – это номер брокерского счета, можно посмотреть в таблице счетов, колонка «Счет»:
 
Эта таблица находиться в меню «Торговля» -> «Торговые счета»:
 
Далее идет поле CLIENT_CODE – это код клиента, можно посмотреть в таблице «Клиентский портфель»:
 
Открывается данная таблица через «Лимиты» -> «Клиентский портфель»:
 
Поле TYPE – тип заявки. «L» — лимитированная, «M» — рыночная.
OPERATION – тип операции, «B» если покупаем, «S» если продаем.
QUANTITY – количество, как правило, в лотах. Но у разных брокеров может быть по-разному (в лотах или в штуках акций).
PRICE – цена.
TRANS_ID – идентификатор транзакции. Иногда он бывает нужен, например, в случае, описанном в одной из моих предыдущих статей: http://robostroy.ru/community/article.aspx?id=765. Но чаще всего безразлично, что вы зададите в этом поле, например, можно просто поставить единичку.
После заполнения полей переменной t мы вызываем функцию sendTransaction, она вернет нам сообщение, которое мы выведем на экран функцией message, которую мы ранее использовали для вывода сообщения “Hello, World!”. Обратите внимание, что res идет без кавычек, это переменная, а не жестко заданный текст, как в предыдущем примере.
Итак, поставим в текст программы те параметры, которые правильные для вашего случая (номер счета, код клиента, параметры бумаги, цену и количество) и запускаем скрипт. Если все правильно, то вы увидите примерно такое сообщение:
 
Иначе может вылезти сообщение с ошибкой. Проверьте, действительно ли выставилась заявка.
 
И так, мы уже научились писать скрипт, выставляющий заявки. Но опять слышу разочарованные вздохи. По-прежнему мы не написали ни одной полезной программы.  Ну что ж, для начала давайте напишем простенький скрипт, который выставит серию заявок на покупку и на продажу с шагом от заданной цены.

Полная версия саться на robostroy.ru

QLua

Тема сегодняшней публикации — скриптовый язык QLUA. QLUA — мощнейший инструмент для написания торговых роботов. И сегодня мы обсудим его плюсы и минусы. Посмотрим как написать простой индикатор и первого робота на нём. В начале своего пути долго выбирал среду разработки, искал эффективное и в тоже время простое решение для написания торговых роботов и советников. Этот путь занял несколько лет, и что я только не перепробовал в то время. Excel, Metastock, TsLab. Но в итоге остановился на QLua, справедливо решив, что это то, что мне нужно.

Оглавление

1) Почему стоит выбрать QLua.

2) Немного истории и о преимуществах QLua в сравнении с предшественником QPile.

3) Написание индикаторов на QLua.

4) Написание робота на QLua под Quik

5) Заключение

1. Почему стоит выбрать QLua.

Постараюсь коротенько описать плюсы и минусы. Начать стоит с того, что в рамках РФ самый распространенный терминал для торговли акциями и фьючерсами является Quik. Если отталкиваться от того, что наш терминал Quik, то выбор будет между: программами для тестирования, языками высокого уровня и встроенными языками в терминал Qlua , QPile.

Если сравнивать с системами, где алгоритм выстраивается путем построения блок-схем, то преимуществом Qlua является отсутствие платы за использование торговой системы как в TsLab и нет необходимости в использовании доп. «прокладок» как Wealth-lab. В системах построения из блоков таких как: TsLab, Wealth-lab и т.д. проблематично выстраивать сложные системы, а для уменьшения количества блоков и получения доп. функций требуется знание высокоуровневых языков типа: C#, Pascal для написания кубиков вручную.

Если рассматривать написание роботов на таких языках как: C#, Delphi , то здесь однозначным минусом является сложность написания кода и его размер для создания простейшего робота. Скриптовые же язык QLua или Qpile позволяют реализовать идею в более короткие сроки.

Сценарный язык (язык сценариев, жарг. скриптовый язык, от англ. scripting language) — высокоуровневый язык сценариев (англ. script) — кратких описаний действий, выполняемых системой. Сценарий — это программа, имеющая дело с готовыми программными компонентами, что очень сильно упрощает написание кода торгового робота. То есть для получения данных по значению закрытия свечи достаточно написать строчку кода типа: ds:C(20) все, и мы получаем значение закрытия двадцатой свечи инструмента. Нет необходимости писать «километры» кода. При этом доступен весь функционал как в полноценном языке программирования.

Из минусов можно отметить, что QLua используется только в рамках терминала Quik и данный язык не доступен для работы с другими терминалами и торговыми системами. Так же учитывая, что Quik является только терминалом и не позволяет производить тестирование торговых алгоритмов. В QLua нет простого решения для тестирования роботов, как это можно сделать в рамках таких платформ как: TsLab и Wealth-Lab.

2. Немного истории и о преимуществах QLua в сравнении с предшественником QPile.

До QLua был QPile, в общем–то он и сейчас есть. Интерпретатор скриптового языка QPile был разработан ARQA Technologies в 2002г. и развивался до 2012г., позже в терминал Quik был добавлен Lua интерпретатор. Так же есть вероятность, что компания ARQA Technologies возможно в ближайшем будущем откажется от дальнейшей поддержки QPile. Qpile как и Qlua является скриптовым языком и обладает рядом возможностей. По праву он является первым языком для написания роботов и советников для терминала Quik. Является простым для изучения и функциональным инструментом, но обладает рядом минусов.

И так, какими плюсами обладает QLua в сравнении с QPile:

— у QLua нет задержки на обработку торговой логики робота в 1сек. Это конечно не критично для среднесрочных стратегий, но для написания скальперских роботов может стать критичным.

— у QLua есть многопоточность. Реализовано это в виде основного потока торговой логики и функций обратного вызова(«колбэков»).

— есть возможность писать и подключать библиотеки на других языках, сам Lua кстати написан на Си

— появилась возможность писать пользовательские индикаторы и использовать их как стандартные.

— синтаксис языка немного похож на JavaScript и C#, отсюда удобство работы с операторами переменными и т.д.

— скрипты обычно интерпретируются, а не компилируются. QLua обладает JIT-компиляторами так как в его основе лежит язык Lua. Что позволяет прятать исходный код, в то время как у Qpile он всегда открыт. Ссылка как компилятор для скрытия исходного кода Qlua

3. Написание индикаторов на QLua.

(1) Пользовательский индикатор

Как уже упоменалось выше в рамках терминала Quik существует два скриптовых языка это: Qpile и QLua. Qpile являестя более ранним языком, который появился в Quik и на нем нельзя было писать индикаторы. Позже разработчики расширили функционал и добавили QLua, в рамках которого стало возможным писать индикаторы. В данной части статье пойдет речь о создании индикатора под Quik.

Индикатор на QLua представляет из себя файл с расширением *.lua или *.luac и визуально ничем не отличается от робота. Исключением является его месторасположение. Для того чтобы Quik увидел индикатор его надо разместить в папке LuaIndicators. Папка LuaIndicators должна храниться в корне папки Квика , если ее там нет , то ее надо создать. Для того чтобы быстро открыть папку Квика надо нажать на его ярлык на рабочем столе правой кнопкой мыши и выбрать «Расположение файла».

И так перейдем к созданию индикатора. Для этого нам понадобится любой текстовый редактор типа Notepade.

Индикатор на QLua для Quik состоит из трех основных частей.

Первая часть это объявление и заполнение глобального массива Settings , который содержит в себе переменные параметров индикатора, тип линии для отображения, толщину, цвет. В массиве Settings располагаются пользовательские переменные для изменения параметров индикатора из пользовательского интерфейса Квика.

Вторая часть это функция Init , она запускается один раз при инициализации индикатора. Возвращает количество линий индикатора.

Третья часть функция OnCalculate(index) получает на вход номер свечи. Она запускается интерпретатором столько раз сколько свечей на графике и возвращает численное значение индикатора. Если линий несколько в индикаторе , то несколько численных значений. Для удобства понимания кода там будут комментарии. Для комментирования строки в QLua используется «—». Все содержимое после двух дефисов интерпретатором кода на QLua не воспринимается.

--[[  Многострочные комментарии располагаются между символами двух дефисов и квадратных скобок  ]]--      
Settings=              
        {                          
            Name = "Channel",           -- название индикатора
            period=5,                   -- параметр индикатора                          
            line=                                     
                {                               
                    {  
                        Name = "High",
                        Type =TYPE_LINE,
                        Width = 1,
                        Color = RGB(120,90, 140)
                    },
                    {
                        Name = "Low",
                        Type =TYPE_LINE,
                        Width = 1,
                        Color = RGB(120,90,140)
                    }
                }
       }

Здесь мы описали массив настроек, ввели название индикатора, параметры описали параметры двух линий индикатора Именно эти параметры будут доступны в пользовательском индикаторе для изменения при загрузке индикатора на Qlua в Quik

  • (1)Название индикатора
  • (2)Установка значения для переменной period
  • (3)Установка цвета по умолчанию для линии High
  • (4)Название линии индикатора , которое мы прописали в ячейке «line» нашего листа настроек
  • (5)Тип линии который мы установили для использования по умолчанию Type =TYPE_LINE
  • (6)Толщина линии индикатора Width = 1
function
Init()
            return 2
end
-- выводить на график будем две линии
 
--[[
В функции OnCalculate
мы рассчитаем индикатор Price Channel – это две линии построенные по
экстремумам значений свечей за определенное количество баров. То есть первое
значение, которое будем рассчитывать это максимальное значение за period в
нашем случае он равен пяти, а второе значение, которое будет возвращать функция
это минимальное значение за period. Итак приступим к расчету.
]]--

function OnCalculate(index)
    local high=0
    local low=0
    Period = math.floor(Settings.period)

    if index<=Period then
       high=H(index)
       low=L(index)
       for i=index , 1 , -1 do
           if H(i)>high then high=H(i) end
           if low>L(i) then low=L(i) end
       end
    else
       high=H(index)
       low=L(index)
       for i=index , (index+1)-Period , -1 do
           if H(i)>high then high=H(i) end
           if low>L(i) then low=L(i) end
       end
    end
    return high , low
end

Создаем в редакторе файл с расширением lua записываем в него
код и сохраняем его в папке LuaIndicators , после этого у нас появится новый
индикатор и его можно будет добавить к себе на график как стандартный индикатор
Quik (1)

Ссылка для скачивания исходного кода индикатора на QLua

4. Написание робота на QLua под Quik

Написание торгового робота на QLua ведется в обычном текстовом редакторе, так же как и для написания индикатора. Отличие будет в структуре кода и в том, что располагать робот можно в любом удобном для вас месте на компьютере. В роботе является обязательной только одна функция main.

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

-- переменная для прырывания цикла при срабатывании функции обратного вызова OnStop

is_run = true

-- присванивание переменным начальных базовых значений торгового алгоритма

Account = "NL0011100043"     -- торговый счет
Class_Code = "QJSIM"         -- класс торгуемого инструмента
Sec_Code = "SBER"            -- код торгуемого инструмента
TF = INTERVAL_M1             -- торговый таймфрейм
g_lots = 1                   -- количество торгуемых лот

function main()
    -- подписываемся на получение данных свечей по инструменту в массив ds
    ds = CreateDataSource(Class_Code, Sec_Code, TF)
    while is_run do
          sleep(1000)            -- обрабатываем цикл с задержкой 1сек.
          ds:SetEmptyCallback()  -- обновляем данные по инструменту в массиве ds
          local serv_time=tonumber(timeformat(getInfoParam("SERVERTIME"))) -- помещене в переменную времени сервера в формате HHMMSS                  
          if isConnected()==1 and serv_time>=10000 and serv_time<235000 then -- проверка наличия соеденения с сервером и поподания в торговое окно
             -- место для размещения торговой логики
             -- расчет значения скользящей средней
             local SMA = 0
             local period = 20
             local count_candle = ds:size()
             if count_candle>20 then
                local sum = 0
                for i=0 , period-1 do                                                  
                    sum = sum + ds:C(count_candle-i)
                end
                SMA = sum / period
                local lots = get_lots()             

                -- получение количества лот в клиентском портфеле по инструменту
                if ds:C(count_candle)>SMA and lots<g_lots then
                    -- получение минимального шага цены для организации величины проскальзываня в ордере
                    local step=tonumber(getParamEx(Class_Code, Sec_Code, "SEC_PRICE_STEP").param_value)
                    local price_order = ds:C(count_candle)+(step*20)
                    -- цена для ордера будет = цена закрытия + 20-ть минимальных шагов инст.
                    send_order("B", math.abs(g_lots-lots) , price_order)
                end
                if ds:C(count_candle)<SMA and lots>(g_lots*(-1)) then
                    -- получение минимального шага цены для организации величины проскальзываня в ордере
                    local step=tonumber(getParamEx(Class_Code, Sec_Code, "SEC_PRICE_STEP").param_value)
                    local price_order = ds:C(count_candle)-(step*20)    
                    -- цена для ордера будет = цена закрытия - 20-ть минимальных шагов инст.
                    send_order("S", math.abs(g_lots+lots) , price_order)
                end
             end                  
           end
    end
end 

-- функция возвращает количество лот в клиентском портфеле по заданному инструменту
function get_lots()
    local lots = 0
    local n = getNumberOf("futures_client_holding")
    local futures_client_holding={}                    
    for i=0,n-1 do             
       futures_client_holding = getItem("futures_client_holding", i)
       if tostring(futures_client_holding["sec_code"])==Sec_Code then
          lots=tonumber(futures_client_holding["totalnet"])
       end
    end      
    return lots
end
----------------------

-- отправка транзакции
function send_order(operation, quantity, price)       
    -- получение минимального шага цены для округления цены отправляемого ордера
    local step=tonumber(getParamEx(Class_Code, Sec_Code, "SEC_PRICE_STEP").param_value)
    local trans_params = 
          {
            CLIENT_CODE = Account,
            CLASSCODE = Class_Code,
            SECCODE = Sec_Code,
            ACCOUNT = Account,
            TYPE = "L",
            TRANS_ID = tostring(1),
            OPERATION = tostring(operation),
            QUANTITY = tostring(math.abs(quantity)),
            PRICE = tostring(math.floor(tonumber(price)/step)*step),  -- округление цены при отправлении транзакции
            ACTION = "NEW_ORDER" 
          }
    local res = sendTransaction(trans_params)
    if string.len(res) ~= 0 then
        message('Error: '..res,3)
        return 0
    else
        return trans_id
    end      
end

function OnStop(stop_flag)              
     is_run=false
     stop_flag=1
     ds:Close() 
end


function timeformat(time_unf)
     local in1, in2=0,0
     local time_form=0      
     in1=string.find(time_unf,":" , 0)
     if in1~=nil and in1~=0 then
        in2=string.find(time_unf,":" , in1+1) 
        time_form=string.sub(time_unf, 0 ,in1-1)..string.sub(time_unf, in1+1 ,in2-1)..string.sub(time_unf, in2+1 ,string.len(time_unf))
     end
     return time_form
end

После редактирования кода сохраняем его в удобном для вас
месте с расширением lua. Для запуска робота надо зайти в Сервисы ->Lua
скрипты

  • (1)Добавляем скрипт из сохраненнго места
  • (2)Проверяем его появление в таблице запущенных скриптов, после запуска появится зеленая стрелка индицирующая работу скрипта
  • (3)Запускаем его в работу
  • (4)Проверяем в поле отсутствие ошибок при работе

Ссылка для скачивания исходного кода робота на QLua

5. Заключение

Подводя итоги хочется сказать, что если используется для торговли терминал Quik, то одним из самых простых способов написания автоматизированных торговых систем является скриптовый язык QLua. И надеюсь, сегодня Вы в этом сами убедились.

В рамках торгового робота написанного как пример выше, мы получили готовую механическую торговую систему в сто строк кода. Что является очень хорошим результатом.

Для написания индикаторов в Квик, Qlua является единственно возможным вариантом.

В общем — торгуйте алгоритмами. Используйте хорошие технологии!

Введение в QUIK (Квик) и LUA | K

В этой части мы будем с вами говорить о таком направлении как программирование на языке QLUA. Что же это за язык такой? — Обыкновенный язык программирования, каких существует множество, но с небольшой оговоркой. Вообще говоря существует язык программирования LUA, а первая буква Q в названии, говорит нам о том, что мы применяем данный язык программирования в платформе QUIK (Квик). Ещё этот язык иногда называют QuikLua, что в принципе тоже верно. Ну да ладно, как бы его не называли суть остается неизменной.

Если вы начинаете с самого начала и ещё ни разу не слышали о том как писать индикаторы или скрипты в платформе QUIK, то этот сайт как раз то что вам нужно.

 

Рекомендую добавить сайт в закладки, так как он вам ещё не один раз пригодится, будет для вас настольной книгой, справочником, где вы всегда сможете найти ответ на свой вопрос

Итак начнем пожалуй с самого главного вопроса который сейчас перед вами стоит это — С чего же начать? Когда-то я сам столкнулся с этим вопросом и перекопал огромное количество информации прежде чем разобрался что это такое и как тут всё устроено. Вам же я предлагаю пройти путь намного короче, так как вся информация будет излагаться последовательно и находиться на одном сайте, как раз на том на котором вы сейчас и находитесь, с чем я вас и поздравляю.

Ну что же, поехали. QUIK это платформа в которой нам позволяют писать на языке программирования lua, а конкретнее мы можем писать индикаторы и скрипты, чем они друг от друга отличаются мы поговорим позже, а сейчас займемся ответом на вопрос где мы будем писать наши собственные индикаторы или скрипты.

Где писать код?

Индикатор или скрипт это обыкновенный текстовый документ который имеет специальное расширение. Поэтому писать мы можем используя любой текстовый редактор, даже самый простой блокнот встроенный в операционную систему Windows. Открываем блокнот, пишем необходимый код сохраняем и всё наш индикатор или скрипт готов, можем использовать его в платформе QUIK, всё просто. Просто, да неудобно. Вы видели как выглядит текст в блокноте? Сплошной черный текст на белом фоне, писать можно, читать тоже можно, но программировать просто ужасно трудно. Поэтому я вам предлагаю использовать расширенную версию блокнота, называется эта программа notepad++. Я никоим образом ни кого не заставляю использовать именно ее, можете использовать любую другую программу. Я же предпочитаю пользоваться именно notepad++.

Если Вы решили как и я использовать для написания кода программу notepad++, то рекомендую перейти в раздел «QLUA (Квик) -> Рабочее Место» изучить все статьи начиниая с первой «Редактор кода notepad++» и настроить свое рабочее место.

 

Индикатор или скрипт? Что выбрать?

Теперь ответим на второй главный вопрос — Что мы будем писать? Выбор у нас конечно невелик, либо это будет индикатор, либо это будет скрипт. Настало время разобраться чем же отличается скрипт от индикатора. Для простоты понимания и чтобы не загружать вас огромным количеством всякой разной информации на начальном этапе, определимся со следующим. Если то что мы задумали сделать, необходимо отображать на графике, в этом случае выбираем для написания индикатор. В остальных случаях можно выбирать скрипт. Конечно же это очень грубое разграничение, но для начала будет достаточным. Когда вы в процессе изучения получите больше информации, что пишется в индикаторах, а что пишется в скриптах, вы сможете сами определить где вам лучше реализовать то что вы задумали.

в заключении

Это небольшая глава была посвящена введению в lua. Мы не затронули ни грамма кода, но зато мы ответили на главные вопросы где писать и что писать, а также подготовили рабочее место. Если вы действительно выполнили всё что тут написано, а не просто пролистали страницу сверху вниз, уверяю вас, вы сделали большой первый шаг, вам это очень поможет в будущем при освоении языка программирования lua. Вы только что сохранили как минимум пару часов своего драгоценного времени, которое бы потратили на поиски всей информации в интернете на различных сайтах.

Если у вас всё готово, а главное вы сами готовы, то переходим к следующему шагу.

QUIK + QLua | QUIKBOT . EVOLUTION …

Функции сохранения и загрузки параметров с примером использования

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
function main()
   local FPath = getScriptPath()..'//.params'
 
   -- Создание таблицы для примера
   local Params = {}
   Params.a = 10
   Params.b = 'qwerty'
   Params.c = true
   Params.d = {}
   Params.d[1] = 100
   Params.d[2] = 'asdfg'
   Params.d[3] = false
   Params.d[4] = {
      ['a'] = 10,
      ['b'] = 'qwerty',
      ['c'] = true
   }
 
   -- Сохраняет таблицу в файл
   SaveTable(Params, FPath)
 
   -- Загружает таблицу из файла
   local NewParams = LoadTable(FPath)
 
   if NewParams ~= nil then message(NewParams.d[4].b) end -- выведет "qwerty"   
end
 
-- Сохраняет таблицу в файл
SaveTable = function(Table, FilePath)
 
   local Lines = {}
   local level = 0
 
   function Rec(a)
      local first = true 
      level = level + 1  
      local s = '' for i=1,level do s = '   '..s end
      for key, val in pairs(a) do         
         if not first then Lines[#Lines] = Lines[#Lines]..',' end
         local k = '[\''..key..'\']'
         if type(key) == 'number' then k = '['..key..']' end
         if type(val) ~= 'table' then 
            if type(val) == 'string' then
               val = '\''..val..'\''
            else
               val = tostring(val)
            end
            table.insert(Lines, s..k..'='..val)
            first = false
         else            
            table.insert(Lines, s..k..'={')
            first = false
            Rec(val)            
            table.insert(Lines, s..'}')
            level = level - 1
         end
      end      
   end   
 
   table.insert(Lines, 'local a = {')
   Rec(Table)   
   table.insert(Lines, '}')
   table.insert(Lines, 'return a')
 
   local f = io.open(FilePath, 'w')   
   for i=1,#Lines do
      f:write(Lines[i]..'\n') 
      f:flush() 
   end
   f:close()
end
 
-- Загружает таблицу из файла
LoadTable = function(FilePath)
   local func, err = loadfile(FilePath)
   if not func then
      message('Ошибка загрузки таблицы из файла: '..err)
      return nil
   else
      return func()
   end
end

Данный пример создаст файл «.params» (можно открыть Блокнотом, это обычный текстовый файл, можете назвать его как угодно) со следующим содержимым:


local a = {
   ['a']=10,
   ['d']={
      [1]=100,
      [2]='asdfg',
      [3]=false,
      [4]={
         ['a']=10,
         ['c']=true,
         ['b']='qwerty'
      }
   },
   ['c']=true,
   ['b']='qwerty'
}
return a


Если у Вас появились какие-то вопросы, задайте их в комментариях под статьей !!!

Данный движок не предоставляет полный функционал для разработки скриптов на QLua(Lua), но показывает на сколько проще и эффективней становится разработка при таком подходе.

В примере движка реализован следующий функционал:Смотреть полностью…

Блок кода QLua

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
-- ПРОВЕРКА ВЫСТАВЛЕНИЯ ЗАЯВКИ ПО ОТПРАВЛЕННОЙ ТРАНЗАКЦИИ
-- для примера отправляется транзакция на выставление лимитированной заявки на покупку по определенной цене
 
ACCOUNT       = "SPBFUT00k59" -- Код счета
CLASS_CODE    = "SPBFUT"      -- Код класса
SEC_CODE      = "RIH6"        -- Код инструмента
 
OpenPrice     = 73000         -- Цена выставления заявки
 
run           = true          -- Флаг работы цикла while в функции main
 
trans_id      = os.time()     -- Текущие дата и время в секундах хорошо подходят для уникальных номеров транзакций
 
LastStatus    = nil           -- Последний статус транзакции, который был выведен в сообщении
 
-- Основная функция скрипта, пока работает эта функция, работает скрипт
function main()
  -- Отправляет транзакцию на открытие позиции
  TransOpenPos() 
  -- Пока работает данный цикл, работает скрипт
  while run do sleep(1) end
end
-- Срабатывает при остановке скрипта
function OnStop() run = false end
 
-- Отправляет транзакцию на открытие позиции
function TransOpenPos()
  -- Выставляет заявку на открытие позиции
  -- Получает ID для следующей транзакции
  trans_id = trans_id + 1
  -- Заполняет структуру для отправки транзакции
  local Transaction={
    ['TRANS_ID']  = tostring(trans_id),   -- Номер транзакции
    ['ACCOUNT']   = ACCOUNT,              -- Код счета
    ['CLASSCODE'] = CLASS_CODE,           -- Код класса
    ['SECCODE']   = SEC_CODE,             -- Код инструмента
    ['ACTION']    = 'NEW_ORDER',          -- Тип транзакции ('NEW_ORDER' - новая заявка)
    ['OPERATION'] = 'B',                  -- Операция ('B' - buy, или 'S' - sell)
    ['TYPE']      = 'L',                  -- Тип ('L' - лимитированная, 'M' - рыночная)
    ['QUANTITY']  = '1',                  -- Количество
    ['PRICE']     = tostring(OpenPrice)   -- Цена
  }
  -- Отправляет транзакцию
  local Res = sendTransaction(Transaction)
  if Res ~= '' then message('TransOpenPos(): Ошибка отправки транзакции: '..Res) else message('TransOpenPos(): Транзакция отправлена') end
end
 
-- Функция вызывается терминалом, когда с сервера приходит новая информация о транзакциях
function OnTransReply(trans_reply)
   -- Если пришла информация по нашей транзакции
   if trans_reply.trans_id == trans_id then
      -- Если данный статус уже был обработан, выходит из функции, иначе запоминает статус, чтобы не обрабатывать его повторно
      if trans_reply.status == LastStatus then return else LastStatus = trans_reply.status end
      -- Выводит в сообщении статусы выполнения транзакции
      if       trans_reply.status <  2    then 
         -- Статусы меньше 2 являются промежуточными (0 - транзакция отправлена серверу, 1 - транзакция получена на сервер QUIK от клиента),
         -- при появлении такого статуса делать ничего не нужно, а ждать появления значащего статуса
         -- Выходит из функции
         return
      elseif   trans_reply.status == 3    then -- транзакция выполнена
         message('OnTransReply(): По транзакции №'..trans_reply.trans_id..' УСПЕШНО ВЫСТАВЛЕНА заявка №'..trans_reply.order_num..' по цене '..trans_reply.price..' объемом '..trans_reply.quantity) 
      elseif   trans_reply.status >  3    then -- произошла ошибка
         message('OnTransReply(): ОШИБКА выставления заявки по транзакции №'..trans_reply.trans_id..', текст ошибки: '..trans_reply.result_msg) 
      end
   end
end

Если у Вас появились какие-то вопросы, задайте их в комментариях под статьей !!!

Эта статья начинает серию статей с примерами блоков кода, которые применяются при написании скриптов на QLua(Lua), каждый блок выполняет свою определенную задачу.

С каждой новой статьей блок кода будет усложняться своей функциональностью.

Эти блоки удобно брать и вставлять в свои скрипты, где нужно решить задачу, реализованную в блоке.

Блок кода QLua

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
-- ПОЛУЧЕНИЕ РЕЗУЛЬТАТОВ ВЫПОЛНЕНИЯ ОТПРАВЛЕННОЙ ТРАНЗАКЦИИ
-- для примера отправляется транзакция на выставление лимитированной заявки на покупку по определенной цене
 
ACCOUNT       = "SPBFUT00k59" -- Код счета
CLASS_CODE    = "SPBFUT"      -- Код класса
SEC_CODE      = "RIH6"        -- Код инструмента
 
OpenPrice     = 73000         -- Цена выставления заявки
 
run           = true          -- Флаг работы цикла while в функции main
 
trans_id      = os.time()     -- Текущие дата и время в секундах хорошо подходят для уникальных номеров транзакций
 
LastStatus    = nil           -- Последний статус транзакции, который был выведен в сообщении
 
-- Основная функция скрипта, пока работает эта функция, работает скрипт
function main()
  -- Отправляет транзакцию на открытие позиции
  TransOpenPos() 
  -- Пока работает данный цикл, работает скрипт
  while run do sleep(1) end
end
-- Срабатывает при остановке скрипта
function OnStop() run = false end
 
-- Отправляет транзакцию на открытие позиции
function TransOpenPos()
  -- Выставляет заявку на открытие позиции
  -- Получает ID для следующей транзакции
  trans_id = trans_id + 1
  -- Заполняет структуру для отправки транзакции
  local Transaction={
    ['TRANS_ID']  = tostring(trans_id),   -- Номер транзакции
    ['ACCOUNT']   = ACCOUNT,              -- Код счета
    ['CLASSCODE'] = CLASS_CODE,           -- Код класса
    ['SECCODE']   = SEC_CODE,             -- Код инструмента
    ['ACTION']    = 'NEW_ORDER',          -- Тип транзакции ('NEW_ORDER' - новая заявка)
    ['OPERATION'] = 'B',                  -- Операция ('B' - buy, или 'S' - sell)
    ['TYPE']      = 'L',                  -- Тип ('L' - лимитированная, 'M' - рыночная)
    ['QUANTITY']  = '1',                  -- Количество
    ['PRICE']     = tostring(OpenPrice)   -- Цена
  }
  -- Отправляет транзакцию
  local Res = sendTransaction(Transaction)
  if Res ~= '' then message('TransOpenPos(): Ошибка отправки транзакции: '..Res) else message('TransOpenPos(): Транзакция отправлена') end
end
 
-- Функция вызывается терминалом, когда с сервера приходит новая информация о транзакциях
function OnTransReply(trans_reply)
   -- Если пришла информация по нашей транзакции
   if trans_reply.trans_id == trans_id then
      -- Если данный статус уже был обработан, выходит из функции, иначе запоминает статус, чтобы не обрабатывать его повторно
      if trans_reply.status == LastStatus then return else LastStatus = trans_reply.status end
      -- Выводит в сообщении статусы выполнения транзакции
      if       trans_reply.status == 0    then message('OnTransReply(): Транзакция отправлена серверу') 
      elseif   trans_reply.status == 1    then message('OnTransReply(): Транзакция получена на сервер QUIK от клиента') 
      elseif   trans_reply.status == 2    then message('OnTransReply(): Ошибка при передаче транзакции в торговую систему. Так как отсутствует подключение шлюза Московской Биржи, повторно транзакция не отправляется') 
      elseif   trans_reply.status == 3    then message('OnTransReply(): ТРАНЗАКЦИЯ ВЫПОЛНЕНА !!!') 
      elseif   trans_reply.status == 4    then message('OnTransReply(): Транзакция не выполнена торговой системой. Более подробное описание ошибки отображается в поле «Сообщение» (trans_reply.result_msg)') 
      elseif   trans_reply.status == 5    then message('OnTransReply(): Транзакция не прошла проверку сервера QUIK по каким-либо критериям. Например, проверку на наличие прав у пользователя на отправку транзакции данного типа') 
      elseif   trans_reply.status == 6    then message('OnTransReply(): Транзакция не прошла проверку лимитов сервера QUIK') 
      elseif   trans_reply.status == 10   then message('OnTransReply(): Транзакция не поддерживается торговой системой') 
      elseif   trans_reply.status == 11   then message('OnTransReply(): Транзакция не прошла проверку правильности электронной цифровой подписи') 
      elseif   trans_reply.status == 12   then message('OnTransReply(): Не удалось дождаться ответа на транзакцию, т.к. истек таймаут ожидания. Может возникнуть при подаче транзакций из QPILE') 
      elseif   trans_reply.status == 13   then message('OnTransReply(): Транзакция отвергнута, так как ее выполнение могло привести к кросс-сделке (т.е. сделке с тем же самым клиентским счетом)')
      end
   end
end

Если у Вас появились какие-то вопросы, задайте их в комментариях под статьей !!!

Чтобы получить доступ к графику(не индикатору) какого-либо инструмента нужно создать источник данных при помощи функции CreateDataSource().
ВАЖНО!!! Для получения новых данных, кроме тех, что уже есть в открытом графике на текущий момент (тем более, если он не открыт), требуется использовать одну из следующих функций: SetUpdateCallback(), или SetEmptyCallback(), о которых будет написано ниже.

Описание функции CreateDataSource()

-- Функция предназначена для создания таблицы Lua и позволяет работать со свечами, полученными с сервера QUIK, а также реагировать на их изменение.
ds, Error = CreateDataSource (class_code, sec_code, interval [, param]);
   -- Параметры:
      -- class_code - (STRING) код класса, например "SPBFUT"
      -- sec_code   - (STRING) код бумаги, например "RIZ5"
      -- interval   - (NUMBER) константа, обозначающая тайм-фрейм графика, например INTERVAL_M5 (полный список: https://quikluacsharp.ru/qlua-osnovy/spisok-konstant-tajm-frejmov-grafikov/)
      -- param      - (STRING) необязательный параметр. Если параметр не задан, то заказываются данные на основании таблицы всех сделок, если задан – данные по этому параметру, например "BID" (возможные параметры смотрите ниже)
   -- Возвращаемые значения:
      -- ds         - (TABLE) таблица с данными по свечам графика
      -- Error      - (STRING) строка ошибки в случае неудачной попытки получить доступ к данным (тогда ds будет nil)
 
-- Если график, к которому нужно подключиться не открыт в терминале, то данные заказываются с сервера, на их получение нужно время,
-- по этому, рекомендуется добавлять вот такое ожидание, прежде, чем обращаться к ds:
-- Ждет, пока данные будут получены с сервера (на случай, если такой график не открыт)
while (Error == "" or Error == nil) and ds:Size() == 0 do sleep(1) end
if Error ~= "" and Error ~= nil then message("Ошибка подключения к графику: "..Error) end
 
-- Примеры (одновременно можно подключаться к нескольким источникам данных):
ds1 = CreateDataSource("SPBFUT", "RIU3", INTERVAL_M1, "last");
ds2 = CreateDataSource("QJSIM", "SBER", INTERVAL_M1);
ds3, Error = CreateDataSource("SPBFUT", "RIU3", INTERVAL_M1, "bid");
if ds3 == nil then message('Ошибка подключения: '..Error); end;

Смотреть полностью…

Скрипт позволяет открывать и закрывать позиции следующего типа:
— покупается 2, выбранных при помощи кнопок, колл-опциона на фьючерс на индекс РТС,
— продается 1, выбранный при помощи кнопок, фьючерс на индекс РТС.

Когда есть открытая данным скриптом позиция, в таблице отображается информация о ней (профит, баланс, ср.цена, дата открытия).

Профит вычисляется по формуле: «Текущая цена, по которой можно закрыть позицию»«Цена открытия позиции»«Комиссия 8 р. на каждый лот».

Так же, выполняется запись в лог-файл («Log.txt») выполняемых скриптом операций и в файле состояния («State.txt») хранится информация о текущих выбранных инструментах и о текущей, открытой скриптом позиции.Смотреть полностью…

Для получения данных из таблиц терминала QUIK удобно пользоваться 3-мя функциями: getItem(), getNumberOf() и getParamEx().

Пример:

-- Перебирает строки таблицы "Позиции по клиентским счетам (фьючерсы)", ищет Текущие чистые позиции по инструменту "RIH5"
for i = 0,getNumberOf("FUTURES_CLIENT_HOLDING") - 1 do
   -- ЕСЛИ строка по нужному инструменту И чистая позиция не равна нулю ТО
   if getItem("FUTURES_CLIENT_HOLDING",i).sec_code == "RIH5" and getItem("FUTURES_CLIENT_HOLDING",i).totalnet ~= 0 then
      -- ЕСЛИ текущая чистая позиция > 0, ТО открыта длинная позиция (BUY)
      if getItem("FUTURES_CLIENT_HOLDING",i).totalnet > 0 then 
         IsBuy = true;
         BuyVol = getItem("FUTURES_CLIENT_HOLDING",i).totalnet;	-- Количество лотов в позиции BUY				
      else   -- ИНАЧЕ открыта короткая позиция (SELL)
         IsSell = true;
         SellVol = math.abs(getItem("FUTURES_CLIENT_HOLDING",i).totalnet); -- Количество лотов в позиции SELL
      end;
   end;
end;

Далее перечислены таблицы, их идентификаторы и поля, к которым можно обращаться:Смотреть полностью…

Для получения стакана в QLua(Lua) служит функция обратного вызова OnQuote(). Эта функция вызывается терминалом QUIK при получении изменения стакана котировок. Для получения данных самого стакана служит функция getQuoteLevel2().

В терминале должен быть открыт стакан по нужному инструменту!!!

 

Пример:Смотреть полностью…

Основы КВИК (QUIK) и языка QLUA

28 августа 2019      Дмитрий Высоцкий      Главная страница » Блог      Просмотров:  

В данной статье начнем рассматривать такую интересную тему как написание скриптов на языке программирования QLUA. Существует язык программирования LUA, а если в названии указан символ Q, то значит, этот язык относится к торговому терминалу QUIK. Пользователи еще говорят, что это Квик_Луа (QUIK LUA). Но суть остается одна, это встроенный язык программирования для КВИК.

Если вы только начинаете изучение разных платформ и языков программирования для написания скриптов для них, торговых роботов или индикаторов, то Вам должно быть интересно узнать подробнее о языке QLUA.

Приступим с самого интересного момента, а с чего надо начать все это осваивать? Все сталкиваются с таким вопросом и начинают копать тонну информации по разным источникам, чтобы разобраться что же это такое и из чего все состоит. Мы же Вам попытаемся немного помочь и ускорить процесс ознакомления с QLUA.

На языке LUA можно запрограммировать скрипты для торговли в терминале КВИК, все возможные индикаторы и торговые роботы, это все понятно, но как и где это делать, в каком редакторе необходимо все это программировать?

Где будем создавать код LUA?

Все скрипты или индикаторы, написанные на LUA представляют собой простой текстовый файл, просто имеет другое специальное расширение. Из этого становится ясно, что написать индикатор/скрипт возможно даже в простом текстовом редакторе, например в программе Блокнот, что есть у всех по умолчанию в Виндоуз. Запускаем текстовый редактор, пишем в нем код скрипта, далее сохраняем файл. Вот в принципе и все, наш скрипт для применения в торговой платформе КВИК готов. Как видите, оказывается очень просто. Да, все просто, но не очень удобно, т.к. текст в блокноте не имеет никакого обозначения, просто сплошной текст без разделений, если вы программировали, то поймете о чем речь идет. Именно поэтому обычно программисты используют подобие блокнота — это программа Notepad++. Повторюсь, что можно код писать в любом редакторе, но, на наш взгляд, программа Notepad++ очень удобна для программировании на LUA. В Notepad++ есть подсветка синтаксиса Lua и это очень большое преимущество в удобстве написания Lua кода.

Что лучше создать Скрипт или Индикатор?

И вот, когда мы поняли, где мы будем создавать наши творения для терминала КВИК, у нас возникает еще один вопрос, а что лучше написать Скрипт или может Индикатор?! Да, выбирать особо не приходится, но необходимо четко понимать в чем отличия между скриптом и индикатором. Тут можно не вдаваться в глубокие подробности структуры того и другого, а можно рассуждать как простой пользователь, если нужно просто видеть нужную информацию на графике в виде линий, точек и прочих обозначений, то значит нужен Индикатора. Если, что-то другое нужно, то значит скрипт. Да, это очень поверхностные различия, но для общего понимания хватит! Далее, когда вы углубитесь в данную тему и начнете понимать из чего состоит структура скрипта, а из чего структура индикатора, то сами легко сможете понять, что нужно сделать, чтобы осуществить задуманную идею.

Заключение

Мы начали с малого, подготовились к написанию кода на LUA и разобрались, что писать код будем в текстовом редакторе Notepad+, а также знаем, что нам выбрать для реализации индикатор или скрипт. Да, пока не коснулись самого кода LUA и структуры, но постараемся сделать цикл статей, чтобы это все постепенно разобрать и понять. Это был Первый и очень важный шаг к изучению языка QLUA. А тем самым даже на этой стадии мы помогли сэкономить Вам немного немало несколько часов рабочего времени!

Продолжение следует, следите за серией статей по языку программирования QLUA для торгового терминала КВИК.
 
 
 
 
 
Вы уже сейчас можете записаться на Видео курс и научиться самому делать зарабатывающих торговых роботов!

Можно записаться на следующий поток ОнЛайн курса, информацию по которому можно посмотреть тут:

Если же вам не хочется тратить время на обучение, то вы просто можете выбрать уже готовые роботы из тех, что представлены у нас!

Также можете посмотреть совершенно бесплатные наработки для МТ4, Квика, МТ5. Данный раздел также постоянно пополняется.

Не откладывайте свой шанс заработать на бирже уже сегодня!

Читайте также:

    

Получение в QLua(Lua) данных из графиков и индикаторов

Чтобы получить доступ к графику(не индикатору) какого-либо инструмента нужно создать источник данных при помощи функции CreateDataSource().
ВАЖНО!!! Для получения новых данных, кроме тех, что уже есть в открытом графике на текущий момент (тем более, если он не открыт), требуется использовать одну из следующих функций: SetUpdateCallback(), или SetEmptyCallback(), о которых будет написано ниже.

Описание функции CreateDataSource()

-- Функция предназначена для создания таблицы Lua и позволяет работать со свечами, полученными с сервера QUIK, а также реагировать на их изменение.
ds, Error = CreateDataSource (class_code, sec_code, interval [, param]);
   -- Параметры:
      -- class_code - (STRING) код класса, например "SPBFUT"
      -- sec_code   - (STRING) код бумаги, например "RIZ5"
      -- interval   - (NUMBER) константа, обозначающая тайм-фрейм графика, например INTERVAL_M5 (полный список: https://quikluacsharp.ru/qlua-osnovy/spisok-konstant-tajm-frejmov-grafikov/)
      -- param      - (STRING) необязательный параметр. Если параметр не задан, то заказываются данные на основании таблицы всех сделок, если задан – данные по этому параметру, например "BID" (возможные параметры смотрите ниже)
   -- Возвращаемые значения:
      -- ds         - (TABLE) таблица с данными по свечам графика
      -- Error      - (STRING) строка ошибки в случае неудачной попытки получить доступ к данным (тогда ds будет nil)
 
-- Если график, к которому нужно подключиться не открыт в терминале, то данные заказываются с сервера, на их получение нужно время,
-- по этому, рекомендуется добавлять вот такое ожидание, прежде, чем обращаться к ds:
-- Ждет, пока данные будут получены с сервера (на случай, если такой график не открыт)
while (Error == "" or Error == nil) and ds:Size() == 0 do sleep(1) end
if Error ~= "" and Error ~= nil then message("Ошибка подключения к графику: "..Error) end
 
-- Примеры (одновременно можно подключаться к нескольким источникам данных):
ds1 = CreateDataSource("SPBFUT", "RIU3", INTERVAL_M1, "last");
ds2 = CreateDataSource("QJSIM", "SBER", INTERVAL_M1);
ds3, Error = CreateDataSource("SPBFUT", "RIU3", INTERVAL_M1, "bid");
if ds3 == nil then message('Ошибка подключения: '..Error); end;

Функция CreateDataSource возвращает таблицу QLua с параметрами, получать значения которых можно следующим образом:

local O = ds:O(i); -- Получить значение Open для указанной свечи (цена открытия свечи)
local H = ds:H(i); -- Получить значение High для указанной свечи (наибольшая цена свечи)
local L = ds:L(i); -- Получить значение Low для указанной свечи (наименьшая цена свечи)
local C = ds:C(i); -- Получить значение Close для указанной свечи (цена закрытия свечи)
local V = ds:V(i); -- Получить значение Volume для указанной свечи (объем сделок в свече)
local T = ds:T(i); -- Получить значение Time для указанной свечи (время открытия свечи (таблица datetime))
   -- Где i - индекс свечи (от 1 до ds:Size())
 
local Size = ds:Size(); -- Возвращает текущий размер (количество свечей в источнике данных) 
ds:Close(); -- Удаляет источник данных, отписывается от получения данных
 
ds:SetUpdateCallback(MyFuncName); -- Позволяет задать пользователю функцию обратного вызова для обработки изменившихся свечей, т.е. когда по выбранному в CreateDataSource параметру в терминал поступит новое значение (возможно такое же), автоматически будет вызвана данная функция, в которую будут передан индекс последней свечи графика, а так же добавятся новые данные в таблицу ds
-- Пример функции:
function MyFuncName(index)
   message('На '..index..'-й свече объем вырос до '..ds:V(index));
end;
 
-- Чтобы получать новые данные без использования функции обратного вызова, а просто получать новые данные в ds и брать их оттуда по необходимости существует функция:
ds:SetEmptyCallback(); -- Которая подписывается на получение новых данных

Списки возможных параметров, используемых в функции CreateDataSource():

Список для АКЦИЙ

"LOTSIZE"            -- Размер лота 
"BID"                -- Лучшая цена спроса 
"BIDDEPTH"           -- Спрос по лучшей цене 
"BIDDEPTHT"          -- Суммарный спрос 
"NUMBIDS"            -- Количество заявок на покупку 
"OFFER"              -- Лучшая цена предложения 
"OFFERDEPTH"         -- Предложение по лучшей цене 
"OFFERDEPTHT"        -- Суммарное предложение 
"NUMOFFERS"          -- Количество заявок на продажу 
"OPEN"               -- Цена открытия 
"HIGH"               -- Максимальная цена сделки 
"LOW"                -- Минимальная цена сделки 
"LAST"               -- Цена последней сделки 
"CHANGE"             -- Разница цены последней к предыдущей сессии 
"QTY"                -- Количество бумаг в последней сделке 
"VOLTODAY"           -- Количество бумаг в обезличенных сделках 
"VALTODAY"           -- Оборот в деньгах 
"VALUE"              -- Оборот в деньгах последней сделки 
"WAPRICE"            -- Средневзвешенная цена 
"HIGHBID"            -- Лучшая цена спроса сегодня 
"LOWOFFER"           -- Лучшая цена предложения сегодня 
"NUMTRADES"          -- Количество сделок за сегодня 
"PREVPRICE"          -- Цена закрытия 
"PREVWAPRICE"        -- Предыдущая оценка 
"LASTCHANGE"         -- % изменения от закрытия 
"LASTTOPREVSTLPRC"   -- Разница цены последней к предыдущей сессии 
"MARKETPRICETODAY"   -- Рыночная цена 
"SEC_FACE_VALUE"     -- Номинал бумаги 
"SEC_SCALE"          -- Точность цены

Список для ВАЛЮТЫ

"LOTSIZE"               -- Размер лота 
"BID"                   -- Лучшая цена спроса 
"BIDDEPTH"              -- Спрос по лучшей цене 
"BIDDEPTHT"             -- Суммарный спрос 
"NUMBIDS"               -- Количество заявок на покупку 
"OFFER"                 -- Лучшая цена предложения 
"OFFERDEPTH"            -- Предложение по лучшей цене 
"OFFERDEPTHT"           -- Суммарное предложение 
"NUMOFFERS"             -- Количество заявок на продажу 
"OPEN"                  -- Цена открытия 
"HIGH"                  -- Максимальная цена сделки 
"LOW"                   -- Минимальная цена сделки 
"LAST"                  -- Цена последней сделки 
"CHANGE"                -- Разница цены последней к предыдущей сессии 
"QTY"                   -- Количество бумаг в последней сделке
"VOLTODAY"              -- Количество бумаг в обезличенных сделках 
"VALTODAY"              -- Оборот в деньгах  
"VALUE"                 -- Оборот в деньгах последней сделки 
"WAPRICE"               -- Средневзвешенная цена 
"HIGHBID"               -- Лучшая цена спроса сегодня 
"LOWOFFER"              -- Лучшая цена предложения сегодня 
"NUMTRADES"             -- Количество сделок за сегодня 
"PREVPRICE"             -- Цена закрытия 
"PREVWAPRICE"           -- Предыдущая оценка 
"CLOSEPRICE"            -- Цена периода закрытия 
"LASTCHANGE"            -- % изменения от закрытия
"PRICEMINUSPREVWAPRICE" -- Разница цены последней к предыдущей оценке 
"LASTTOPREVSTLPRC"      -- Разница цены последней к предыдущей сессии 
"PRICEMAX"              -- Максимально возможная цена 
"PRICEMIN"              -- Минимально возможная цена 
"BASEPRICE"             -- Базовый курс 
"SEC_FACE_VALUE"        -- Номинал бумаги 
"SEC_SCALE"             -- Точность цены

Список для ОПЦИОНОВ

"LOTSIZE"               -- Размер лота 
"BID"                   -- Лучшая цена спроса 
"BIDDEPTH"              -- Спрос по лучшей цене 
"BIDDEPTHT"             -- Суммарный спрос 
"NUMBIDS"               -- Количество заявок на покупку 
"OFFER"                 -- Лучшая цена предложения 
"OFFERDEPTH"            -- Предложение по лучшей цене 
"OFFERDEPTHT"           -- Суммарное предложение 
"NUMOFFERS"             -- Количество заявок на продажу 
"HIGH"                  -- Максимальная цена сделки 
"LOW"                   -- Минимальная цена сделки 
"LAST"                  -- Цена последней сделки 
"CHANGE"                -- Разница цены последней к предыдущей сессии 
"QTY"                   -- Количество бумаг в последней сделке 
"VOLTODAY"              -- Количество бумаг в обезличенных сделках 
"VALTODAY"              -- Оборот в деньгах 
"VALUE"                 -- Оборот в деньгах последней сделки 
"WAPRICE"               -- Средневзвешенная цена 
"NUMTRADES"             -- Количество сделок за сегодня 
"PREVPRICE"             -- Цена закрытия 
"PREVWAPRICE"           -- Предыдущая оценка 
"LASTCHANGE"            -- % изменения от закрытия 
"PRICEMINUSPREVWAPRICE" -- Разница цены последней к предыдущей оценке 
"PREVSETTLEPRICE"       -- Предыдущая расчетная цена 
"NUMCONTRACTS"          -- Количество открытых позиций 
"BUYDEPO"               -- Гарантийное обеспечение продавца 
"SELLDEPO"              -- Гарантийное обеспечение покупателя 
"BGOP"                  -- БГО по покрытым позициям 
"BGONP"                 -- БГО по непокрытым позициям 
"STRIKE"                -- Цена страйк 
"STEPPRICET"            -- Стоимость шага цены 
"STEPPRICE"             -- Стоимость шага цены (для новых контрактов FORTS и RTS Standard)
"VOLATILITY"            -- Волатильность опциона 
"THEORPRICE"            -- Теоретическая цена 
"CLPRICE"               -- Котировка последнего клиринга 
"SEC_FACE_VALUE"        -- Номинал бумаги 
"SEC_SCALE"             -- Точность цены

Список для ФЬЮЧЕРСОВ

"LOTSIZE"               -- Размер лота 
"BID"                   -- Лучшая цена спроса 
"BIDDEPTH"              -- Спрос по лучшей цене 
"BIDDEPTHT"             -- Суммарный спрос 
"NUMBIDS"               -- Количество заявок на покупку 
"OFFER"                 -- Лучшая цена предложения 
"OFFERDEPTH"            -- Предложение по лучшей цене 
"OFFERDEPTHT"           -- Суммарное предложение 
"NUMOFFERS"             -- Количество заявок на продажу 
"HIGH"                  -- Максимальная цена сделки 
"LOW"                   -- Минимальная цена сделки 
"LAST"                  -- Цена последней сделки 
"CHANGE"                -- Разница цены последней к предыдущей сессии 
"QTY"                   -- Количество бумаг в последней сделке 
"VOLTODAY"              -- Количество бумаг в обезличенных сделках 
"VALTODAY"              -- Оборот в деньгах 
"VALUE"                 -- Оборот в деньгах последней сделки 
"WAPRICE"               -- Средневзвешенная цена 
"NUMTRADES"             -- Количество сделок за сегодня 
"PREVPRICE"             -- Цена закрытия 
"PREVWAPRICE"           -- Предыдущая оценка 
"LASTCHANGE"            -- % изменения от закрытия 
"PRICEMINUSPREVWAPRICE" -- Разница цены последней к предыдущей оценке 
"PREVSETTLEPRICE"       -- Предыдущая расчетная цена 
"PRICEMAX"              -- Максимально возможная цена 
"PRICEMIN"              -- Минимально возможная цена 
"NUMCONTRACTS"          -- Количество открытых позиций 
"BUYDEPO"               -- Гарантийное обеспечение продавца 
"SELLDEPO"              -- Гарантийное обеспечение покупателя 
"STEPPRICET"            -- Стоимость шага цены 
"STEPPRICE"             -- Стоимость шага цены (для новых контрактов FORTS и RTS Standard) 
"SETTLEPRICE"           -- Расчетная цена 
"PERCENTRATE"           -- Агрегированная ставка 
"CLPRICE"               -- Котировка последнего клиринга 
"REALVMPRICE"           -- Текущая рыночная котировка 
"STEPPRICECL"           -- Стоимость шага цены для клиринга 
"STEPPRICEPRCL"         -- Стоимость шага цены для промклиринга 
"SEC_FACE_VALUE"        -- Номинал бумаги 
"SEC_SCALE"             -- Точность цены

Так же, в QLua есть функции для получения данных как графиков, так и индикаторов по их уникальным идентификаторам(тэгам), для этого необходимо нужному графику(индикатору) назначить уникальный идентификатор, о том как это делается можете ознакомиться в самом начале «Инструкции по использованию» Индикатора «Мои Сделки». Идентификатор для индикатора добавляется аналогичным способом.

После этого, можно использовать следующие функции для доступа к данным:

-- Функция предназначена для получения КОЛИЧЕСТВА ЛИНИЙ в графике (индикаторе) по выбранному идентификатору
getLinesCount(tag); -- Возвращает число
   -- tag - (STRING) идентификатор графика (индикатора), о котором писалось выше
 
-- Функция предназначена для получения информации о КОЛИЧЕСТВЕ СВЕЧЕЙ по выбранному идентификатору
getNumCandles(tag); -- Возвращает число
   -- tag - (STRING) идентификатор графика (индикатора), о котором писалось выше
 
-- Функция предназначена для получения информации о свечах по идентификатору (заказ данных для построения графика функция не осуществляет, поэтому для успешного доступа нужный график должен быть открыт)
t, n, l = getCandlesByIndex (tag, line, first_candle, count);
   -- Параметры:
      -- tag          – (STRING) строковый идентификатор графика или индикатора 
      -- line         – (NUMBER) номер линии графика или индикатора. Первая линия имеет номер 0 
      -- first_candle – (NUMBER) индекс первой свечи. !!! ПЕРВАЯ (САМАЯ ЛЕВАЯ) СВЕЧКА ИМЕЕТ ИНДЕКС 0 !!!
      -- count        – (NUMBER) количество запрашиваемых свечей
   -- Возвращаемые значения:
      -- t – таблица, содержащая запрашиваемые свечи, пример работы: 
         local O = t[i].open; -- Получить значение Open для указанной свечи (цена открытия свечи)
         local H = t[i].high; -- Получить значение High для указанной свечи (наибольшая цена свечи)
         local L = t[i].low; -- Получить значение Low для указанной свечи (наименьшая цена свечи)
         local C = t[i].close; -- Получить значение Close для указанной свечи (цена закрытия свечи)
         local V = t[i].volume; -- Получить значение Volume для указанной свечи (объем сделок в свече)
         local T = t[i].datetime; -- Получить значение datetime для указанной свечи
            -- Где i - индекс свечи от 0 до n-1
      -- n – количество свечей в таблице t
      -- l – легенда (подпись) графика

Если у Вас появились какие-то вопросы, задайте их в комментариях под статьей !!!

Программирование на Lua: 1

Программирование на Lua: 1

Это первое издание было написано для Lua 5.0. Хотя все еще актуально для более поздних версий, есть некоторые отличия.
Четвертое издание предназначено для Lua 5.3 и доступно в Amazon и других книжных магазинах.
Покупая книгу, вы также помогаете поддерживать проект Lua.


По традиции,
наша первая программа на Lua просто выводит «Hello World» :

    print ("Привет, мир")
 

Если вы используете автономный интерпретатор Lua,
все, что вам нужно сделать для запуска вашей первой программы, — это вызвать интерпретатор
(обычно называется lua ) с именем текстового файла, содержащего
ваша программа.Например,
если вы запишете вышеуказанную программу в файл hello.lua ,
следующая команда должна запустить его:

    подсказка> lua hello.lua
 

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

    - определяет факториальную функцию
    функция fact (n)
      если n == 0, то
        возврат 1
      еще
        вернуть n * факт (n-1)
      конец
    конец
    
    print ("введите число:")
    а = io.read ("* число") - прочитать число
    печать (факт (а))
 

Если вы используете Lua, встроенный в приложение,
такие как CGILua или IUPLua,
вам может потребоваться обратиться к руководству по применению (или к «местному гуру»)
чтобы узнать, как запускать ваши программы.
Тем не менее, Lua остается тем же языком;
большинство вещей, которые мы здесь увидим, действительны независимо от того, как
вы используете Lua.
Для начала рекомендуем использовать автономный интерпретатор.
(то есть исполняемый файл lua )
для запуска ваших первых примеров и экспериментов.



Copyright © 2003–2004 Роберто Иерусалимши. Все права защищены.

.

Lua — Начало работы с Lua

Lua — это минималистичный, легкий и встраиваемый язык сценариев. Он разрабатывается, внедряется и поддерживается командой PUC-Rio, Папского католического университета Рио-де-Жанейро в Бразилии. Список рассылки открыт для участия.

Общие варианты использования Lua включают создание сценариев видеоигр, расширение приложений с помощью плагинов и конфигураций, обертывание некоторой высокоуровневой бизнес-логики или просто встраивание в такие устройства, как телевизоры, автомобили и т. Д.

Для высокопроизводительных задач существует независимая реализация с использованием JIT-компилятора под названием LuaJIT.

Версии

Версия Примечания Дата выпуска
1.0 Начальный непубличный выпуск. 28.07.1993
1,1 Первый публичный выпуск.Документ конференции, описывающий это. 08.07.1994
2.1 Начиная с Lua 2.1, Lua стал свободно доступным для всех целей, включая коммерческое использование. Журнал с описанием этого. 1995-02-07
2.2 Длинные строки, интерфейс отладки, улучшенная трассировка стека 1995-11-28
2,4 Внешний компилятор luac 1996-05-14
2.5 Сопоставление с образцом и функции vararg. 1996-11-19
3,0 Введен auxlib, библиотека для помощи в написании библиотек Lua 1997-07-01
3,1 Анонимные функции и закрытие функций через «повышающие значения». 1998-07-11
3.2 Библиотека отладки и новые табличные функции 1999-07-08
3.2.2 2000-02-22
4.0 Множественные состояния, операторы «для», обновление API. 2000-11-06
4.0.1 2002-07-04
5.0 Сопрограммы, метатаблицы, полная лексическая область видимости, хвостовые вызовы, логические значения перемещаются в лицензию MIT. 11.04.2003
5.0.3 2006-06-26
5.1 Модернизация системы модулей, инкрементный сборщик мусора, метатаблицы для всех типов, luaconf.h переработка, полностью реентерабельный синтаксический анализатор, вариативные аргументы. 21.02.2006
5.1.5 2012-02-17
5.2 Аварийный сборщик мусора, goto, финализаторы для таблиц. 2011-12-16
5.2.4 2015-03-07
5,3 Базовая поддержка UTF-8, побитовые операции, 32/64-битные целые числа. 12.01.2015
5.3.4 Последняя версия. 12.01.2017

Однострочные комментарии в Lua начинаются с - и продолжаются до конца строки:

  - это однострочный комментарий
- нужна еще одна строка
- а?
  

Комментарии блока начинаются с - [[ и заканчиваются на ]] :

  - [[
    Это комментарий блока.
    Итак, это может продолжаться ...
    и дальше...
    и дальше ....
]]
  

Блочные комментарии используют тот же стиль разделителей, что и длинные строки; в скобках можно добавить любое количество знаков равенства, чтобы ограничить комментарий:

  - [= [
    Это тоже комментарий блока
    Мы можем включить "]]" в этот комментарий
знак равно

- [== [
    Это тоже комментарий блока
    Мы можем включить "] =]" в этот комментарий
-] ==]
  

Изящный трюк, чтобы закомментировать фрагменты кода, состоит в том, чтобы окружить его - [[ и -]] :

  - [[
    print'Lua прекрасна '
-]]
  

Чтобы повторно активировать блок, просто добавьте - к последовательности открытия комментария:

  --- [[
    print'Lua прекрасна '
-]]
  

Таким образом, последовательность - в первой строке начинает однострочный комментарий, как и последняя строка, а оператор print не закомментирован.

Идя дальше, два блока кода могут быть настроены таким образом, что если первый блок закомментирован, второй не будет, и наоборот:

  --- [[
  print 'Lua - это любовь'
знак равно
  print 'Lua - это жизнь'
знак равно
  

Чтобы активировать второй фрагмент при отключении первого фрагмента, удалите ведущие - в первой строке:

  - [[
  print 'Lua - это любовь'
знак равно
  print 'Lua - это жизнь'
знак равно
  

Выполнение программ Lua

Обычно Lua поставляется с двумя двоичными файлами:

  • lua — автономный интерпретатор и интерактивная оболочка
  • luac — компилятор байт-кода

Допустим, у нас есть пример программы ( bottle_of_mate.lua ) вот так:

  локальная строка = требуется "строка"

функция bottle_take (bottle_available)

    local count_str = "% d бутылок мате на стене."
    local take_str = "Взять один, передать," .. count_str
    local end_str = "О нет," .. count_str
    local buy_str = "Купи немного в магазине" .. count_str
    местные бутылки_left = 0

    если bottle_available> 0, тогда
         print (string.format (count_str, bottle_available))
         bottle_left = bottle_available - 1
         печать (строка.формат (take_str, bottle_left))
    еще
        print (string.format (end_str, bottle_available))
        Bottle_left = 99
        print (string.format (buy_str, bottle_left))
    конец

    возврат бутылок
конец

local bottle_count = 99

в то время как правда
    bottle_count = бутылка_взято (кол-во бутылок)
конец
  

Саму программу можно запустить, выполнив в вашей оболочке следующее:

  $ lua bottle_of_mate.lua
  

Вывод должен выглядеть так, работая в бесконечном цикле:

  Достань в магазине, 99 бутылок мате на стене.
99 бутылок мате на стене.
Сними одну, разнеси, 98 бутылок мате на стене.
98 бутылок мате на стене.
Возьми одну, разнеси, 97 бутылок мате на стене.
97 бутылок мате на стене.
...
...
3 бутылки мате на стене.
Возьми одну, разнеси, 2 бутылки мате на стене.2 бутылки мате на стене.
Возьми одну, разнеси, 1 бутылка мате на стене.
1 бутылка мате на стене.
Возьми одну, разнеси, 0 бутылок мате на стене.
О нет, 0 бутылок мате на стене.
Купи в магазине, 99 бутылок мате на стене.
99 бутылок мате на стене.
Сними одну, разнеси, 98 бутылок мате на стене.
...
  

Вы можете скомпилировать программу в байт-код Lua, выполнив в вашей оболочке следующее:

  $ luac bottle_of_mate.lua -o bottle_of_mate.luac
  

Также доступен список байт-кода, выполнив следующее:

  $ luac -l bottle_of_mate.lua


main <./ Bottle.lua: 0,0> (13 инструкций, 52 байта на 0x101d530)
0+ параметров, 4 слота, 0 повышающих значений, 2 локальных параметра, 4 константы, 1 функция
    1 [1] GETGLOBAL 0 -1; требовать
    2 [1] LOADK 1-2; "строка"
    3 [1] ЗВОНИТЕ 0 2 2
    4 [22] ЗАКРЫТИЕ 1 0; 0x101d710
    5 [22] ПЕРЕМЕЩЕНИЕ 0 0
    6 [3] SETGLOBAL 1 -3; bottle_take
    7 [24] НАГРУЗКА 1 -4; 99
    8 [27] GETGLOBAL 2–3; bottle_take
    9 [27] ПЕРЕМЕЩЕНИЕ 3 1
    10 [27] ЗВОНИТЕ 2 2 2
    11 [27] ПЕРЕМЕЩЕНИЕ 1 2
    12 [27] JMP -5; до 8
    13 [28] ВОЗВРАТ 0 1

функция <./bottles.lua:3,22> (46 инструкций, 184 байта на 0x101d710)
1 параметр, 10 слотов, 1 повышающее значение, 6 локальных переменных, 9 констант, 0 функций
    1 [5] LOADK 1 -1; "% d бутылок мате на стене".
    2 [6] LOADK 2 -2; «Сними один, разнеси»
    3 [6] ПЕРЕМЕЩЕНИЕ 3 1
    4 [6] СЦЕПИТЬ 2 2 3
    5 [7] НАГРУЗКА 3 -3; "О нет,"
    6 [7] ПЕРЕМЕЩЕНИЕ 4 1
    7 [7] СЦЕПИТЬ 3 3 4
    8 [8] НАГРУЗКА 4 -4; "Купи немного в магазине"
    9 [8] ПЕРЕМЕЩЕНИЕ 5 1
    10 [8] CONCAT 4 4 5
    11 [9] НАГРУЗКА 5 -5; 0
    12 [11] EQ 1 0 -5; - 0
    13 [11] JMP 16; до 30
    14 [12] GETGLOBAL 6 -6; Распечатать
    15 [12] GETUPVAL 7 0; строка
    16 [12] ТАБЛИЦА 7 7 -7; "формат"
    17 [12] ПЕРЕМЕЩЕНИЕ 8 1
    18 [12] ПЕРЕМЕЩЕНИЕ 9 0
    19 [12] ЗВОНИТЕ 7 3 0
    20 [12] ЗВОНИТЕ 6 0 1
    21 [13] SUB 5 0 -8; - 1
    22 [14] GETGLOBAL 6 -6; Распечатать
    23 [14] GETUPVAL 7 0; строка
    24 [14] ТАБЛИЦА 7 7 -7; "формат"
    25 [14] ПЕРЕМЕЩЕНИЕ 8 2
    26 [14] ПЕРЕМЕЩЕНИЕ 9 5
    27 [14] ЗВОНИТЕ 7 3 0
    28 [14] ЗВОНИТЕ 6 0 1
    29 [14] JMP 15; до 45
    30 [16] GETGLOBAL 6 -6; Распечатать
    31 [16] GETUPVAL 7 0; строка
    32 [16] ТАБЛИЦА 7 7 -7; "формат"
    33 [16] ПЕРЕМЕЩЕНИЕ 8 3
    34 [16] ПЕРЕМЕЩЕНИЕ 9 0
    35 [16] ЗВОНИТЕ 7 3 0
    36 [16] ЗВОНИТЕ 6 0 1
    37 [17] НАГРУЗКА 5 -9; 99
    38 [18] GETGLOBAL 6 -6; Распечатать
    39 [18] GETUPVAL 7 0; строка
    40 [18] ТАБЛИЦА 7 7 -7; "формат"
    41 [18] ПЕРЕМЕЩЕНИЕ 8 4
    42 [18] ПЕРЕМЕЩЕНИЕ 9 5
    43 [18] ЗВОНИТЕ 7 3 0
    44 [18] ЗВОНИТЕ 6 0 1
    45 [21] ВОЗВРАТ 5 2
    46 [22] ВОЗВРАТ 0 1
  

Начало работы

переменных

  var = 50 - глобальная переменная
print (var) -> 50
делать
  local var = 100 - локальная переменная
  print (var) -> 100
конец
print (var) -> 50
- Глобальный var (50) все еще существует
- Локальная переменная (100) вышла из области видимости и больше не доступна. 

типов

  num = 20 - число
num = 20.001 - по-прежнему число
str = "zaldrizes buzdari iksos daor" - строка
tab = {1, 2, 3} - таблица (у них своя категория)
bool = true - логическое значение
bool = false - единственное другое логическое значение
print (type (num)) -> 'число'
print (type (str)) -> 'строка'
print (type (bool)) -> 'логическое'
тип (тип (число)) -> 'строка'

- Функции - это тоже тип, и первоклассные значения в Lua.print (type (print)) -> печатает 'функцию'
old_print = печать
print = function (x) old_print "Я игнорирую переданный вами параметр!" конец
old_print (type (print)) -> По-прежнему печатает «функцию», так как это все еще функция.
- Но мы (бесполезно) пересмотрели поведение печати.
print ("Hello, world!") -> выводит "Я игнорирую параметр, который вы мне передали!"
  

Особый тип нет

Другой тип в Lua — nil .Единственное значение для типа nil nil . nil существует, чтобы отличаться от всех других значений в Lua. Это своего рода неценностная ценность.

  print (foo) - выводит nil, поскольку в переменной 'foo' ничего не хранится.
foo = 20
print (foo) - теперь выводится 20, поскольку мы присвоили 'foo' значение 20.

- Мы также можем использовать `nil` для отмены определения переменной
foo = nil - здесь мы устанавливаем 'foo' равным nil, чтобы его можно было собрать сборщиком мусора.если nil, то выведите "nil" конец -> (ничего не печатает)
- Только false и nil считаются ложными; все остальные значения верны.
если 0, то выведите "0" конец -> 0
если "", то выведите "Пустая строка!" -> Пустая строка!
  

выражений

  а = 3
b = a + 20 a = 2 print (b, a) - трудно читать, также может быть записано как
б = а + 20; а = 2; print (a, b) - легче читать,; не являются обязательными, хотя
истина и истина -> возвращает истину
верно и 20 -> 20
ложь и 20 -> ложь
ложь или 20 -> 20
истина или 20 -> истина
вкладка или {}
  -> возвращает вкладку, если она определена
  -> возвращает {}, если вкладка не определена
  - Это полезно, когда мы не знаем, существует ли переменная
tab = tab или {} - вкладка остается неизменной, если она существует; вкладка становится {}, если ранее она была равна нулю.a, b = 20, 30 - это тоже работает
a, b = b, a - переключает значения
  

Определение функций

  имя функции (параметр)
    возвращаемый параметр
конец
печать (имя (20)) -> 20
- см. категорию функций для получения дополнительной информации
name = function (parameter) return parameter end - То же, что и выше
  

логические

Только false и nil оцениваются как false, все остальное, включая 0 и пустую строку, оценивается как true.

сборщик мусора

  tab = {"лоты", "из", "данные"}
tab = nil; сбор мусора ()
- вкладка больше не существует и больше не занимает память.
  

столов

  tab1 = {"a", "b", "c"}
tab2 = tab1
tab2 [1] = "d"
print (tab1 [1]) -> 'd' - значения таблицы хранят только ссылки.
-> присвоение таблиц не копирует их содержимое, только ссылку.

tab2 = ноль; сбор мусора ()
print (tab1) -> (выводит адрес таблицы) - tab1 все еще существует; он не собирался сборщиком мусора.tab1 = ноль; сбор мусора ()
- Больше никаких ссылок. Теперь это действительно должно быть стерто из памяти.
  

Это основы, но есть раздел о таблицах с дополнительной информацией.

условия

  если (условие), то
    -- сделай что-нибудь
elseif (другое_условие) тогда
    - сделай что-нибудь еще
еще
    -- сделай что-нибудь
конец
  

для петель

В Lua существует два типа для цикла : числовой для цикла и общий для цикла .

  • Числовой для цикла имеет следующий вид:

      для a = 1, 10, 2 do - для начала 1, заканчивая 10, с шагом 2
      печать (а) -> 1, 3, 5, 7, 9
    конец
      

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

      для a = 10, 1, -1 сделать
       print (a) -> 10, 9, 8, 7, 6 и т. д.конец
      

    Если выражение step не указано, Lua принимает значение по умолчанию 1.

      для a = 1, 10 do
       print (a) -> 1, 2, 3, 4, 5 и т. д.
     конец
      

    Также обратите внимание, что переменная цикла является локальной для цикла для . Он не будет существовать после завершения цикла.

  • Общий для циклов обрабатывает все значения, возвращаемые функцией итератора:

      для ключа, значения в парах ({"некоторые", "таблица"}) делать
      печать (ключ, значение)
      -> 1 немного
      -> 2 стола
    конец
      

    Lua предоставляет несколько встроенных итераторов (например,g., пар , ipairs ), и пользователи могут определять свои собственные итераторы, а также использовать их с общим для циклов .

до блоков

  местный а = 10
делать
    печать (а) -> 10
    местный а = 20
    печать (а) -> 20
конец
печать (а) -> 10
  

Привет, мир

Это привет, мировой код:

  print («Hello World!»)
  

Как это работает? Это просто!
Lua выполняет функцию print () и использует строку «Hello World» в качестве аргумента.

Установка

Двоичные файлы

двоичные файлы Lua предоставляются большинством дистрибутивов GNU / Linux в виде пакета.

Например, в Debian, Ubuntu и их производных его можно получить, выполнив следующее:

  sudo apt-get install lua50
  
  sudo apt-get install lua51
  
  sudo apt-get install lua52
  

Есть несколько полуофициальных сборок для Windows, MacOS и некоторых других операционных систем, размещенных на SourceForge.

Пользователи Apple также могут легко установить Lua с помощью Homebrew:

  brew установить lua
  

(В настоящее время Homebrew имеет 5.2.4, для 5.3 см. Homebrew / версии.)

Источник

Источник доступен на официальной странице. Получение исходников и сборка должны быть тривиальными. В системах Linux должно быть достаточно:

  $ wget http://lua.org/ftp/lua-5.3.3.tar.gz
$ echo "a0341bc3d1415b814cc738b2ec01ae56045d64ef./lua-5.3.3.tar.gz "| sha1sum -c -
$ tar -xvf ./lua-5.3.3.tar.gz
$ make -C ./lua-5.3.3/ linux
  

В приведенном выше примере мы в основном загружаем исходный архив tarball с официального сайта, проверяем его контрольную сумму, а также извлекаем и выполняем make . (Дважды проверьте контрольную сумму на официальной странице.)

Примечание: вы должны указать, какую цель сборки вы хотите. В этом примере мы указали linux . Другие доступные цели сборки включают solaris , aix , bsd , freebsd , macosx , mingw и т. Д.Дополнительные сведения см. В документе doc / readme.html , включенном в исходный код. (Вы также можете найти последнюю версию README в Интернете.)

Модули

Стандартные библиотеки ограничены примитивами:

  • coroutine — функциональность управления сопрограммами
  • отладка — отладочные хуки и инструменты
  • io — базовые примитивы ввода-вывода
  • пакет — функции управления модулями
  • string — специфичная для строки и Lua функция сопоставления шаблонов
  • table — примитивы для работы с важным, но сложным типом Lua — таблицы
  • os — основные операции ОС
  • utf8 — базовые примитивы UTF-8 (начиная с Lua 5.3)

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

Сторонние библиотеки Lua и инфраструктура для распространения модулей немногочисленны, но улучшаются. Такие проекты, как LuaRocks, Lua Toolbox и LuaDist, улучшают ситуацию. Много информации и много предложений можно найти в старой Lua Wiki, но имейте в виду, что часть этой информации довольно устарела и устарела.

Некоторые хитрости

Иногда Lua ведет себя не так, как можно было бы подумать после прочтения документации.Вот некоторые из этих случаев:

Как и ожидалось, table.insert (my_table, 20) добавляет значение 20 в таблицу, а table.insert (my_table, 5, 20) добавляет значение 20 в 5-ю позицию.
Что же делает table.insert (my_table, 5, nil) ? Можно было бы ожидать, что он будет рассматривать nil как отсутствие аргумента и вставлять значение 5 в конец таблицы, но на самом деле он добавляет значение nil в 5-ю позицию таблицы.Когда это проблема?

  (функция (вкладка, значение, позиция)
    table.insert (табуляция, позиция или значение, позиция и значение)
конец) ({}, 20)
- Это заканчивается вызовом table.insert ({}, 20, nil)
- и это не делает того, что должно (вставить 20 в конце)
  

То же самое происходит с tostring () :

  print (tostring (nil)) - выводит "nil"
table.insert ({}, 20) - ничего не возвращает
- (не ноль, но на самом деле ничего (да, я знаю, в lua эти два ДОЛЖНЫ
- то же самое, но их нет))

-- неправильно:
print (tostring (table.вставить ({}, 20)))
- выдает ошибку, потому что ничего не ~ = nil

--право:
local _tmp = table.insert ({}, 20) - после этого _tmp содержит ноль
print (tostring (_tmp)) - выводит "nil", потому что внезапно ничего не == nil
  

Это также может привести к ошибкам при использовании стороннего кода. Если, например, в документации по какой-то функции указано «возвращает пончики, если повезет, в противном случае — ноль», реализация может выглядеть как примерно так:

  function func (повезло)
    если повезет тогда
        вернуть "пончики"
    конец
конец
  

, эта реализация сначала может показаться разумной; он возвращает пончики, когда это необходимо, и когда вы набираете result = func (false) result будет содержать значение nil .

Однако, если написать print (tostring (func (false))) lua выдаст ошибку, которая выглядит примерно так: stdin: 1: плохой аргумент # 1 для 'tostring' (ожидаемое значение)

Почему? tostring явно вызывает аргумент, хотя это nil . Неправильно. func вообще ничего не возвращает, поэтому tostring (func (false)) совпадает с tostring () и НЕ совпадает с tostring (nil) .

Ошибки с сообщением «ожидаемое значение» являются убедительным признаком того, что это может быть источником проблемы.

Это огромная ловушка, если вы новичок в lua, и в таблицах категории

много информации.

.

Lua: начало работы

Lua — мощный и быстрый язык программирования
это легко изучить, использовать и встроить в ваше приложение.

Lua разработан как легкий встраиваемый язык сценариев.
Он используется для
всевозможные приложения,
от игр до веб-приложений и обработки изображений.

Увидеть
о странице
для подробностей
и некоторые причины, по которым вам следует выбрать Lua.

Посмотрите, как выглядят и работают программы Lua в
живая демонстрация.

Хорошее место для начала изучения Lua — книга
Программирование на Lua,
доступно в
в мягкой обложке и как
электронная книга.
Первое издание находится в свободном доступе в Интернете.
Смотрите также
примечания к курсу
на основе этой книги.

Официальное определение языка Lua дается в
справочное руководство.

Увидеть
страница документации
и
вики
для большего.

Наши
сообщество
дружелюбен и, скорее всего, поможет вам, если вам нужно.
Просто посетите
список рассылки,
чат,
а также
переполнение стека.

Если вам нужна помощь на португальском языке,
Присоединяйся к
Список рассылки Lua BR
и посетить
pt.stackoverflow.

Смотрите также
в
ВОПРОСЫ-ОТВЕТЫ,
поддерживаемый сообществом
вики
а также
LuaFaq,
и намного дольше
uFAQ.

Если вам нужно
дополняют стандартные библиотеки Lua для решения более сложных задач,
визит
LuaRocks,
основной репозиторий модулей Lua.
Смотрите также
Потрясающий Lua,
тщательно подобранный список качественных пакетов и ресурсов Lua.
В
lua-users вики
перечисляет многие
дополнения, созданные пользователями
для Lua.

Вы можете помочь
поддержать проект Lua
по
покупка книги
опубликовано Lua.org
и по
делать пожертвование.

Вы также можете помочь распространить информацию о Lua, купив продукты Lua.
в
Zazzle.

Использовать
живая демонстрация
играть с Lua
если вы не хотите ничего устанавливать на свой компьютер.

Чтобы запускать программы Lua на вашем компьютере,
вам понадобится автономный интерпретатор Lua
и, возможно, некоторые дополнительные библиотеки Lua.
Используйте свой любимый текстовый редактор для написания программ Lua.
Убедитесь, что вы сохранили свои программы в виде обычного текста.Если вам нужна IDE, попробуйте
Студия ZeroBrane.

Если вы используете Windows,
пытаться
LuaDist,
многоплатформенный дистрибутив Lua, включающий батареи.

Если вы используете Linux или Mac OS X,
Lua либо уже установлен в вашей системе, либо для него есть пакет Lua.
Убедитесь, что у вас установлена ​​последняя версия Lua.
(в настоящее время 5.4.0).

Lua также довольно легко собрать из исходного кода,
как объяснено ниже.

Строительство из источника

Lua очень легко собрать и установить.Просто скачайте и
следовать
инструкции
в пакете.

Вот простой сеанс терминала, который
скачивает текущий выпуск Lua и собирает его в системе Linux:

curl -R -O http://www.lua.org/ftp/lua-5.4.0.tar.gz
tar zxf lua-5.4.0.tar.gz
cd lua-5.4.0
сделать все испытания
 

Если у вас нет curl, попробуйте wget.

Если вы используете Windows и хотите собрать Lua из исходного кода,
есть
подробные инструкции
в
вики.

Заготовка

Чтобы встроить Lua в вашу программу C или C ++,
вам понадобятся заголовки Lua для компиляции вашей программы и
библиотека Lua для связи с ней.Если вы получаете готовый пакет Lua для своей платформы,
вам, вероятно, также понадобится пакет для разработки.
В противном случае просто
скачать Lua и
добавьте его исходный каталог в свой проект.

.

Lua: документация

Официальное определение языка Lua — это его
справочное руководство,
который описывает синтаксис и семантику Lua,
стандартные библиотеки и C API.

В
справочное руководство для Lua 5.4
доступно онлайн
по-английски
только.

В
справочное руководство для Lua 5.3
доступно онлайн
по-английски
а также
Русский.

В
справочное руководство для Lua 5.2
доступно онлайн
по-английски,
Португальский,
и польский.

В
справочное руководство для Lua 5.1
доступно онлайн
по-английски,
Португальский,
Испанский язык,
Немецкий,
а также
Польский.
Он также доступен в виде книги на английском языке.

Техническая документация

Для получения дополнительной технической информации,
см. Часто задаваемые вопросы (FAQ)
и некоторые старые
слайды семинаров.
Для получения подробной технической информации по конкретным темам,
увидеть нашу старую серию
Технические примечания Lua
и
вики
в
lua-users.org,
особенно
руководство.
Вы также можете просмотреть
исходный код.

Здесь очень много
статьи и тезисы
связанные с Lua.Вот основные из них, написанные Lua
команда.
См. Также
Публикации LabLua.

Основная научная статья о Lua
обсуждает философию его дизайна:

Lua — расширяемый язык расширений

Р. Иерусалимский, Л. Х. де Фигейредо, В. Селес,

Программное обеспечение: практика и опыт 26 № 6 (1996) 635–652.
[doi]

Эта статья была удостоена
первая премия (технологическая категория)
в
II награда Compaq за исследования и разработки в области компьютерных наук в 1997 году.Эта награда была совместным предприятием
Compaq Computer в Бразилии,
в
Министерство науки и технологий Бразилии,
и
Бразильская академия наук.

Для обзора того, как разработан Lua, см.

Взглянем на дизайн Lua

Р. Иерусалимский, Л. Х. де Фигейредо, В. Селес,

Связь с ACM 61 № 11 (2018) 114–123.
[doi & middot
видео]

Краткое описание дизайна API см.

Прохождение языка через игольное ушко

автор R.Иерусалимский, Л. Х. де Фигейредо, В. Селес,

Очередь ACM 9 № 5 (май 2011 г.) 20–29.
[doi
·
acm]

Связь с ACM 54 № 7 (июль 2011 г.) 38–43.
[doi
·
acm]

Он также доступен на португальском:

Passando uma linguagem pelo buraco de uma agulha

por Р. Иерусалимский, Л. Х. де Фигейредо, В. Селес,

Очередь ACM 9 № 5 (май 2011 г.) 20–29.

Подробнее о реализации Lua см.

Реализация Lua 5.0

Р. Иерусалимский, Л. Х. де Фигейредо, В. Селес,

Журнал универсальных компьютерных наук 11 № 7 (2005) 1159–1176.
[doi
·
слайды]

Подробнее о роли функций первого класса в Lua см.

Первоклассные функции в императивном мире

Р. Иерусалимский,

Журнал универсальных компьютерных наук 23 № 1 (2017) 112–126.
[doi
·
слайды]

Для обсуждения сопрограмм в Lua см.

Корутины в Lua

автор А.Л. де Моура, Н. Родригес, Р. Иерусалимский,

Журнал универсальных компьютерных наук 10 № 7 (2004) 910–925.
[doi
·
слайды]

Полную историю Lua до 2006 г. см.

Эволюция Lua

Р. Иерусалимский, Л. Х. де Фигейредо, В. Селес,

Труды
ACM HOPL III (2007) 2-1–2-26.
[doi
·
слайды]

Историю Lua до 2001 года см.

Эволюция языка расширения:
история Lua

автор R.Иерусалимский, Л. Х. де Фигейредо, В. Селес,

Труды V Бразильского симпозиума по языкам программирования
(2001) Б-14 – Б-28.
[пс]

Первая статья, описывающая Lua, имеет исторический интерес:

Дизайн и реализация языка для расширения приложений

Л. Х. де Фигейредо, Р. Иерусалимский, В. Селес,

Труды XXI бразильского семинара по программному и аппаратному обеспечению (1994) 273–283.
[пс]

Для ранней пояснительной статьи см.

Lua: расширяемый встроенный язык

автор Л.Х. де Фигейредо, Р. Иерусалимский, В. Селес,

Журнал доктора Добба 21 № 12 (декабрь 1996 г.) 26–33.
[ddj]

Вводный текст (на португальском языке) см.

Uma Introductiono Programao Em Lua

Р. Иерусалимский,
JAI 2009 (июль 2009 г.).

Книги Lua доступны в основных интернет-магазинах.
а также в виде электронных книг на
Злющая утка.
Когда вы покупаете копию книги, изданной Lua.org,
вы помогаете поддерживать проект Lua.

Справочное руководство

Официальное определение языка Lua:

Справочное руководство по Lua 5.1

Р. Иерусалимский, Л. Х. де Фигейредо, В. Селес,

Lua.org, август 2006 г.

ISBN 8590379833


Справочные руководства для более поздних версий Lua доступны
онлайн.

Программирование на Lua

Подробное и авторитетное введение в
все аспекты программирования на Lua,
от главного архитектора Lua:

Программирование на Lua

автор R.Иерусалимский

Lua.org, четвертое издание, август 2016 г.

ISBN 8590379868

(также доступен как
электронная книга)


Четвертое издание ориентировано на Lua 5.3.
и знаменует собой полную реорганизацию текста.

Первое издание
доступно онлайн.
Он был нацелен на Lua 5.0 и по-прежнему актуален.

Третья редакция была нацелена на Lua 5.2 и остается весьма актуальной.
Он доступен в
Английский,
Португальский,
и русский:

Программирование на Lua

Роберто Иерусалимский

Lua.org, третье издание, январь 2013 г.

ISBN 859037985X

(также доступен как
электронная книга)


Программа на языке Lua

Пор Роберто Иерусалимский

LTC, январь 2015 г.

ISBN 9788521626992


Программирование на языке Lua

Роберто Иерусалимский

ДМК-пресс, 2014 г.

ISBN 5940747671


Второе издание остается актуальным и доступно в
Немецкий,
Корейский,
Китайский язык,
и японский:

Программа с Lua

фон Роберто Иерусалимский

Open Source Press, сентябрь 2006 г.

ISBN 3937514228


Программирование на Lua

Роберто Иерусалимский

Insight, июнь 2007 г.

ISBN 9788991268302


Программирование на Lua

Роберто Иерусалимский

Издательство электронной промышленности, май 2008 г.

ISBN 9787121061875


Программирование на Lua

Роберто Иерусалимский

ASCII Media Works, август 2009 г.

ISBN 9784048677974


Самоцветы программирования Lua

Сборник статей, в которых записаны некоторые из существующих знаний и практик о том, как хорошо программировать на Lua:

Жемчужины программирования Lua

под редакцией Л.Х. де Фигейредо, В. Селес, Р. Иерусалимский,
Lua.org, декабрь 2008 г.

ISBN 9788590379843

(также доступен как
электронная книга)


Книги другие

Есть также книги о Lua, написанные другими авторами:

  • Разработка игр на Raspberry Pi:
    Программирование приложений с помощью Lua и LVE

    пользователя Seth Kenlon.
    Апресс, 2019, ISBN 9781484241707.

  • Введение в linguagem Lua

    Хосе Аугусто Н. Г. Манзано.
    Новатэк, 2018, ISBN 9788575226681.

  • Краткое руководство по Lua

    Габор Зауэр,
    Packt Publishing, 2018, ISBN 9781789343229.

  • Создание твердых API-интерфейсов с помощью Lua

    пользователя Tyler Neylon.
    O’Reilly Media, 2017, ISBN 9781491986301.

  • Краткое руководство по Lua

    пользователя Mitchell.
    foicica.com, 2017, ISBN 9780991237937.

  • Le guide de Lua et ses applications — Manuel d’apprentissage (2e dition)

    Пьера Шапюи, Этьена Дальколя, Сирила Дуайона, Сильвена Фабра, Филиппа Лосте, Хишама Мухаммеда и Патрика Рапена.
    ditions D-BookeR, 2016, ISBN 9782822704076.

  • Le guide de Lua et ses applications — Manuel de rfrence (2-е место)

    Пьера Шапюи, Сирила Дуайона, Сильвена Фабра, Филиппа Лоста и Патрика Рапена.Ditions D-BookeR, 2016, ISBN 9782822704083.

  • Поваренная книга разработки игр на Lua

    пользователя Mario Kasuba.
    Packt Publishing, 2015, ISBN 1849515506.

  • Еще семь языков за семь недель: языки, формирующие будущее

    Брюс Тейт, Ян Дис, Фредерик Дауд, Джек Моффитт.
    Прагматическая книжная полка, 2014, ISBN 1941222153.

  • Обучение программированию ИИ в игре с помощью Lua

    пользователя Дэвид Янг.
    Packt Publishing, 2014 г., ISBN 1783281332.

  • Программирование на Lua

    Марк Отарис и другие, Викиучебники, 2014.

  • Введение в программирование с помощью Lua и Corona Game Lab

    пользователя Роберт Кук.
    Кулинарные книги, 2014.
    ASIN B00IQGAC8A.

  • Создание мобильных игр с Corona: сборка с Lua на iOS и Android

    пользователя Сильвия Доменек.
    Прагматическая книжная полка, 2013, ISBN 1937785572.

  • CryENGINE Программирование игр с помощью C ++, C # и Lua

    Филиппа Лундгрена и Руана Пирса.
    Packt Publishing, 2013, ISBN 1849695903.

  • LVE для программирования игр Lua

    пользователя Дарми Акинлая.
    Packt Publishing, 2013, ISBN 1782161600.

  • ComputerCraft: Программирование на Lua в Minecraft

    Мэтью Монк и Саймон Монк.
    CreateSpace, 2013 г., ISBN 1481927655.

  • Изучите Lua для разработки игр для iOS

    пользователя Jayant Varma.
    Апресс, 2012, ISBN 1430246626.

  • Le guide de Lua et ses applications

    Сирила Дуайона, Сильвена Фабра, Филиппа Лоста и Патрика Рапена.
    ditions D-BookeR, 2012, ISBN 9782822700054.

  • Lua — Программа вычислений

    Хосе Аугусто Н. Г. Манзано.
    самоиздан, 2012, ISBN 9788591311576.

  • Lua: Einsatz von Lua во встроенных системах

    Клауса Хнеля и Даниэля Цвирнера.
    Скрипт Verlag Kuehnel, 2012, ISBN 3907857151.

  • Базовое программирование ROBLOX Lua

    Брэндона Джона Ларуша.
    CreateSpace, 2012 г., ISBN 1475026048.

  • Численные методы для нелинейных инженерных моделей

    Джона Р. Хаузера.
    Springer, 2009 г., ISBN 9781402099199.

  • Lua: Einsatz von Lua zur Messwerterfassung

    Клауса Хнеля и Даниэля Цвирнера.
    Скрипт Verlag Kuehnel, 2009, ISBN 3907857127.

  • Начало Lua с надстройками World of Warcraft

    пользователя Paul Emmerich.
    Апресс, 2009, ISBN 1430223715.

  • First Lua Programming, самый популярный легкий сценарий разработки приложений!

    пользователя Miki Shimizu.
    Softbank Creative, 2008, ISBN 4777514137.

  • Язык сценариев для разработки игр и эффективный C / C ++ для реализации встроенного Lua

    пользователя Макото Хаманака.
    Softbank Creative, 2008, ISBN 4797348550.

  • Программирование World of Warcraft

    Джеймсом Уайтхедом II, Брайаном Маклемором и Мэтью Орландо.Wiley, 2008 г., ISBN 0470229810.

  • Введение в программирование на Lua

    пользователя Ютака Уэно.
    Softbank Creative, 2007, ISBN 4797342722.

  • Начало программирования на Lua

    Курта Юнга и Аарона Брауна.
    Wrox, 2007, ISBN 0470069171.

  • Программирование ИИ игры на примере

    пользователя Mat Buckland.
    Jones & Bartlett Learning, 2005, ISBN 9781556220784.

  • Разработка игр с помощью Lua

    Пол Шуйтема и Марк Манайен.
    Чарльз Ривер Медиа, 2005, ISBN 1584504048.

  • Программирование игр с помощью Python, Lua и Ruby

    пользователя Tom Gutschmidt.Технологический курс PTR, 2003, ISBN 1592000770.

.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *