ВАЖНО! Для создания торговых роботов необходимо хорошо знать и четко понимать, как работают логические операторы, операторы сравнения, конструкция if then else end, и функции в языке программирования Lua.

Возьмем, для примера код скрипта «003 Арифметические действия.lua».

В данном скрипте после каждого арифметического действия на экран выводится строка с названием действия и результатом операции. Допустим, нам будет необходимо многократно выполнять арифметические действия и выводить на экран их результат, тогда нам придется многократно писать строку кода с выводом на экран результата, это не самая лучшая идея, поскольку таких операций может быть и 100 и 1000. Лучшим решением будет написать функцию, которая будет выполнять арифметические действия и выводить на экран результат. В процессе написания функции станет понятна вся мощь их использования.

Приступим. Создадим новый файл скрипта под названием «006 Пример функции.lua». В нашей функции будем использовать арифметические операции сложение, вычитание, умножение, деление и возведение в степень.

Объявим числовые переменные, которые будут содержать аргументы арифметических действий, назовем их «x» и «z» и строковую переменную, которая будет содержать вид арифметического действия, назовем ее «Act» (от английского слова Action – действие).

Переменной «x» присвоим значение 10. Переменной «z» присвоим значение 5. Переменную «Act» оставим пустой, ей будут присваиваться символ арифметического действия например «+», «-«, «*», «/», «^».

Перейдем к созданию самой функции. Мы одновременно будем писать основной код программы и код функции, шаг за шагом создадим то, что запланировали. Запишем, в первой строке скрипта, пустую функцию с именем PrintCalc. Как уже говорилось ранее коды функций должны располагаться выше основного кода скрипта.

На данном этапе функция ничего не принимает на вход, ничего не делает и ничего не возвращает. Для выполнения арифметических действий, нам необходимо передать в функцию переменные, над которыми мы будем совершать арифметические действия и само действие, которое нужно совершить. Следовательно, все три переменные, которые у нас объявлены. В скобках функции добавляем, через запятую PrintCalc(x, z, Act).

Для выполнения расчетов в функции объявим пустую переменную «y», в которую будет записываться результат арифметического действия.

Наша функция должна выводить на экран результат действия и его название. Следовательно, нам понадобится еще одна переменная, которая будет содержать название действия. Объявим строковую переменную с именем «NameAct».

Рассмотрим первое арифметическое действие в нашей функции, пусть это будет сложение. Нам нужно сложить значения двух переменных «x», «z» и результат записать в переменную «y».

y = x + z

Сложение будет выполняться, если на входе в функцию, переменная Act будет равна «+», следовательно, данное условие нужно прописать. Если Act == «+» , тогда операция выполняется. Тут нам помощь придет конструкция if then else end. Также присвоим переменной NameAct значение «сложение».

Поскольку мы будем выводить на экран название операции, то нам нужно добавить еще одну строку, в которой будет присваиваться название действия в переменную «NameAct». В данном случае запишем NameAct = «сложение».

В конце функции выведем результат на экран в читаемом виде.

print(NameAct, «\n»..x..» «..Act..» «..z..» «..»=»..» «..y, «\n»)

Расшифруем запись:

NameAct – название операции,
«\n» – переход на новую строку,
.. – конкатенация строк т.е. склейка,
x – значение переменной «x»,
» » – пробел,
Act – символ арифметического действия,
z – значение переменной «z»,
» » – пробел,
«=» – знак равенства,
» » – пробел,
y – значение переменной «y»,
«\n» – переход на новую строку.

На данном этапе наша функция уже может принимать на вход значения, обрабатывает их и выводит на экран строку.Попробуем ее в действии. В коде основной программы присвоим переменной «Act» значение «+» и вызовем функцию PrintCalc, передав в нее значения переменных «x», «z», «Act».

Act = «+»

PrintCalc(x, z, Act)

Выполним код.

Далее пропишем в функции остальные арифметические действия.

Воспользуемся оператором elseif. Звучать это будет так. Если Act == «+», тогда выполняем сложение, иначе, (если Act ~= «+»), проверяем следующее условие если. Если Act == «-«, тогда выполняем вычитание, иначе, (если Act ~= «-«), тогда проверяем следующее условие если. Если Act == «*», то выполняем умножение, иначе (если Act ~=»*»), тогда проверяем следующее условие если. Если Act == «/», то выполняем деление, иначе (если Act ~=»/»), тогда проверяем следующее условие если. Если Act == «^», то выполняем возведение в степень, иначе (если Act ~=»^»), тогда переходим в конец конструкции if then else end, поскольку все условия на этом закончились. В результате получается следующий код функции:

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

Ниже добавим операции вычитание, умножение, деление и возведение в степень. Снабдим каждый вызов функции комментарием.

Как видим, функция сработала, как и планировалось, на экране отобразились все прописанные действия. Но есть одно но! Что произойдет, если переменная Act будет равна символу, не прописанному в нашей функции. Проверим. Добавим еще один вызов функции, перед этим присвоив переменной Act знак нижнее подчеркивание «_». Назовем этот вызов функции «проверка недопустимого символа», добавим соответствующий комментарий. (строки кода 42-44).

Произошла ошибка и весь скрипт остановил свою работу. Это не хорошо, надо разбираться. В окошке вывода результатов на экран подробно описано, что пошло не так. Смотрим на строку выделенную цветом.

lua: 006 Пример функции.lua:20: attempt to concatenate local ‘y’ (a nil value)

Разберем эту строку по частям.

006 Пример функции.lua – это имя файла в котором произошла ошибка.

:20: — это строка в которой произошла ошибка.

attempt to concatenate local ‘y’ (a nil value) – это описание ошибки «попытка склеить локальную переменную «y» имеющую значение nil». (Напомню, склейка с пустыми переменными не допускается.)

Отследим возникновение ошибки. С начала переменная «y» была объявлена как пустая переменная в строке номер 2. Программа прошла по всем строкам функции и не присвоила переменной «y» никакого значения. Программа не присвоила переменной «y» никакого значения поскольку, переменная «Act» имеет значение непредусмотренное в функции, а именно знак нижнее подчеркивание «_». Для исключения возникновения ошибки, при передаче в функцию недопустимого арифметического действия, необходимо программно обработать данную ситуацию.

Добавим условие, выводить строку на экран, только в том случае, если переменная y ~= nil, иначе выводить строку, сообщающую, что переменная y == nil. В данном случае переменная «y» может равняться nil, когда введено недопустимое арифметическое действие, значит так и напишем «ОШИБКА! Недопустимое арифметическое действие» и обозначим, какое именно, добавив на вывод переменную Act. (строки кода 20-24)

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

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

Проверим, что произойдет, если переменная «z», будет иметь значение ноль. Для этого присвоим переменной «z» значение ноль, вставим в строку номер 40 код z = 0, строки ниже сместятся на одну вниз.

Выполним код.

Программа выполнит код и не остановиться по ошибке, но под строкой «деление» будет следующая запись:

10 / 0 = 1.#INF#INF – в языке Lua обозначает бесконечность.

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

elseif Act == «/» then

добавим еще условие, и z ~= 0.

elseif Act == «/» and z ~= 0 then

Данная строка выполниться, если оба условия Act == «/» и z ~= 0 будут иметь значение true. Если Act == «/», и z == 0, то строка не выполнится и переменная «y» останется пустой, и будет иметь значение nil.

В функции уже есть условие обрабатывающее ситуацию, когда y == nil, следовательно, в него мы можем добавить еще одно условие обрабатывающее ситуацию, когда выполняется деление и переменная z == 0.

Сейчас переменная «y» может иметь значение nil в двух случаях. Первое, когда введена неверная арифметическая операция и второе, когда выполняется деление и переменная z == 0. Добавим в условие (строка номер 32):

if y ~= nil then

еще одно условие:

if Act == «/» and z == 0 then

print(«деление\n».. «ОШИБКА! Деление на ноль», «\n»)

else

print(«ОШИБКА! Недопустимое арифметическое действие:», Act, «\n»)

end

У нас добавилось условие, проверяющее, по какой из двух причин переменная «y» равна nil. Если переменная «y» равна nil, то сначала идет проверка, является ли заданное действие «делением» и равен ли делитель нулю, если да то выдается соответствующее сообщение, иначе выдается сообщение, что задано недопустимое арифметическое действие.

Выполним скрипт.­

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

Можно было бы подумать, что это все, но нет, есть еще один нюанс. А что произойдет, если переменные «x» или «z» не будут числами, а например, будут строкой.

Проверим, присвоим переменной «x» строковое значение «string», добавив новую строку кода.

x = «string» (строка номер 48)

Выполним код.

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

Разберем строку сообщающую об ошибке.

lua: 006 Пример функции.lua:17: attempt to perform arithmetic on local ‘x’ (a string value)

006 Пример функции.lua – это файл в котором произошла ошибка

:17: — это строка в которой произошла ошибка

attempt to perform arithmetic on local ‘x’ (a string value) – это описание ошибки «попытка выполнить арифметическое действие над переменной x имеющей строковое значение».

Невозможно выполнить арифметическое действие с переменной имеющей строковый тип.

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

Закомментируем строку, в которой мы присвоили переменной «x» строку «string», и ниже запишем следующий код

print(type(x))

Выполним код.

В окне вывода над сообщением «возведение в степень» появилась строка с текстом «number», это означает, что наша переменная «x» имеет числовой тип.

Перейдем к коду функции.

Добавим в начале функции две логические переменные и присвоим им значение true в строки номер 3 и 4.

local xType = true
local zType = true

В эти переменные будем записывать, являются ли переменные «x» и «z» числовыми. Значение true – является числовой, false – не является числовой. Изначально установим, что переменные «x» и «z» являются числовыми. Введем условие проверки типа переменных «x» и «z». Если переменная «x» не будет являться числовой, то запишем в переменную xType значение false, и выведем на экран предупреждение, что «x» не является числом.

if type(x) ~= «number» then

print(«x не является числом»)
xType = false

end

Выполним те же действия для переменной z.

Далее нам необходимо добавить условие проверки, если одна или обе переменные не являются числом, то дальнейший код функции выполнять не нужно. Нам необходимо сообщить программе функции, что переменная не является числом. Введем проверку состояния логических переменных xType и zType. Выполнять дальнейший код функции будем только в том случае, если обе переменные имеют состояние true. Добавим соответствующую строку кода после проверки типа переменных. (Строка 14)

if xType == true and zType == true then

Выход из данной конструкции (end) поместим в конец (строка номер 40) кода перед оператором (end) всей функции. Если одна из переменных будет равна false, то код функции закончит выполняться.

Код будет должен выглядеть следующим образом.

«Раскомментируем» ранее закомментированную строку, в которой переменной «х» присваивается значение «string». (Напомню, это в основной части кода, в операции возведение в степень строка номер 60) Удалим строку номер 61 print(type(x)) она нам больше не понадобится.

Выполним скрипт.

В результате выполнения программы, на экране отображаются все возможные варианты развития событий с функцией PrintCalc(). С помощью простых операторов мы создали сложную функцию, учитывающую все возможные варианты развития событий с переменными. Функция однозначно не вызовет ошибку и не остановит работу нашего скрипта. Хочу добавить, что чем больше вариантов возможных ошибок, вы рассмотрите, тем меньше вероятность непредвиденной остановки выполнения скрипта.

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

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

Вернем из функции значения двух переменных «y» и «NameAct». Строка кода будет выглядеть следующим образом

return y, NameAct

Добавим эту строку в самый конец функции перед последним оператором end (строка номер 41).Для того чтобы принять значения из функции необходимо записать эти значения в определенные переменные в теле основного кода.

Для демонстрации возврата значений из функции, объявим еще две переменные в основном коде программы local y = 0 (в строку номер 47) local NameAct = » » (в строку номер 48)

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

y, NameAct = PrintCalc(x, z, Act)

Данную запись вызова функции с возвратом значений будем использовать для операции «сложение» строка кода номер 51.

Эта запись означает первое возвращаемое значение поместить в переменную «y» второе значение в переменную «NameAct». Последовательность записи очень важна. Какие переменные запишем, в те переменные и получим возвращаемые значения, и не имеет разницы, как они именуются.

Для демонстрации возврата значений из функции добавим строку с выводом на экран возвращенных переменных.

print(«Функция вернула значения переменных y и NameAct:» , «y = «..y, «NameAct = «..NameAct,»\n»)Данную строку кода добавим сразу после вызова функции для сложения в строку номер 52.

Выполним скрипт.

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

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