В языке программирования Lua, массивы данных представлены в виде таблиц. Под массивом данных подразумевается совокупность данных объединенных по какому-то признаку. Например, график цены инструмента, это массив данных в котором содержаться данные Open, High, Low, Close расположенные в столбцы, а строки соответствуют времени. Таблицы в Lua – это обычная таблица, например, как в Excel, имеющая нумерацию столбцов и нумерацию строк, вместо номеров, столбцам и строкам могут быть присвоены имена.
Таблицы нам потребуются, когда мы будем работать с графиком цены инструментов. Все цены инструментов и значения индикаторов в торговом терминале QUIK, хранятся в таблицах. Создадим новый файл скрипта и именем «008 Таблицы цикл for.lua»Создадим пустую таблицу.
Таблица создается, так же как и переменная, за исключением того, что после имени следует знак присвоения и фигурные скобки.

Теперь у нас есть пустая таблица с именем «Table», не имеющая строк и столбцов, если обратиться к любой строке таблицы, получим результат nil.

Заполнить таблицу значениями, можно несколькими способами.

Первый способ. Объявим новую таблицу с именем «TableNum» и при объявлении таблицы поместить в ее ячейки нужные значения, например:

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

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

Второй способ. При объявлении таблицы записать в ее ячейки значения переменных, например, добавим в наш код пять локальных переменных с именами «a»,»b», «c», «d», «e» и запишем значения переменных в таблицу TableVar.

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

Третий способ. Присвоить каждой строке таблицы определенные значения используя цикл for.

Числовой цикл for.

Числовой цикл for имеет вид:

for i = exp1, exp2, exp3 do

<код>

end

Переменная «i» в цикле for является управляющей переменной. Цикл будет выполнен от значения exp1 до значения exp2 с шагом значения exp3. Например, значение exp1 = 1, exp2 = 10, exp3 = 1, т.е. начальное значение i = 1, максимальное значение i = 10, после каждой итерации переменная «i» увеличивается на значение 1.

Создадим таблицу с именем TableFor и заполним ее строки значениями от 1 до 10, используя цикл for. Чтобы обратиться к определенной строке таблицы, необходимо обратиться к самой таблице и далее указать номер строки, к которой обращаемся, номер строки указывается в квадратных скобках [] после имени таблицы. Например, чтобы обратиться к строке 3 таблицы TableFor, следует записать код TableFor[3].

Разберем работу примера по шагам:

1.Строка for i = 1, 10, 1 do, переменная «i» имеет значение 1.

2.Выполнение кода переходит на строку TableFor[i] = i. В строку таблицы TableFor под номером «i» (TableFor[i]), присваивается значение переменной «i» (TableFor[i] = i, i = 1).

3.В цикле только одна строка и получается, что код в теле цикла for закончился, и цикл переходит снова на строку for i = 1, 10, 1 do, для увеличения переменной «i» на заданный шаг. После увеличения переменной «i» на шаг равный 1 переменная i = 2. Далее проверяется условие, меньше ли значение переменной «i», чем максимальное установленное значение 10. Условие выполняется 2 < 10 и цикл продолжает свою работу выполняя код в теле цикла.

4.Далее снова выполнение кода переходит на строку TableFor[i] = i. В строку таблицы TableFor под номером «i» (TableFor[i]), присваивается значение переменной «i» (TableFor[i] = i, i = 2).

5.Выполнение цикла прекращается, когда переменная «i» становиться равна 11, поскольку по условию в строке for i = 1, 10, 1 do переменная «i» не должна быть более 10.

В результате выполнения данного цикла, в таблице TableFor появятся десять строк содержащие значения от 1 до 10. Один проход цикла от начала до конца называется итерацией, в нашем примере было 10 итераций.

Проверим, как заполнилась таблица TableFor и выведем на экран значение в ячейках таблицы. В данном примере мы знаем количество строк в таблице, но чаще всего происходит так, что нам неизвестно точное количество строк, для того чтобы узнать количество строк в таблице используем оператор # (решетка), и далее имя таблицы.Выведем на экран количество строк в таблице TableFor. Запишем, в наш код строку с выводом количества строк в таблице.

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

Далее выведем на экран строки таблицы TableFor, используя цикл for, и оператор определения длинны таблицы #. Добавим в наш скрипт еще один цикл for, который проходит по всем строкам таблицы и выводит значение из каждой на экран.

for i = 1, #TableFor, 1 do

print(«Значение в строке под номером «..i..» = «..TableFor[i])

end

Разберем, как работает этот код. Первая строка for i = 1, #TableFor, 1 do это условие цикла. Начальное значение переменной «i» равно 1, поскольку нам необходимо вывести значения, из таблицы начиная с первой строки. Далее идет оператор # и название таблицы TableFor, с помощью оператора # мы определяем количество строк в таблице TableFor, после идет цифра 1, которая указывает, что после каждой итерации необходимо увеличить переменную «i» на единицу, переменная «i», в данном примере, означает номер строки, из которой мы хотим взять значение. Если будет необходимо можно установить любое значение шага, например, взять значение через одну строку, тогда шаг цикла нужно установить равным 2 и на экран выведется следующий порядок строк 1, 3, 5, 7, 9.

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

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

Далее поэкспериментируем с таблицами и циклами.

Создадим программу, которая считает скользящее среднее значение с интервалом 10.

Создадим новый проект и назовем его «009 SMATest.lua», в проекте создадим две пустые таблицы. Первая будет называться Table и содержать исходные значения и вторая TableSMA будет содержать скользящее среднее значение таблицы Table.

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

Создадим переменную «x», значение которой будет присваиваться в строку таблицы. Присвоим переменной «х» начальное значение 20.

Заполним в таблице 100 строк значениями переменной «x». Переменная «х» будет увеличиваться на 1 при каждой итерации цикла for. В результате заполнения, таблица Table будет содержать 100 значений, начиная от значения 21 и заканчивая значением 120. Запишем цикл.

На данном этапе у нас есть заполненная таблица Table имеющая 100 строк и заполненная значениями от 21 до 120, для которой мы будем считать скользящее среднее значение. Для расчета скользящего среднего, нам необходимо для каждой ячейки из таблицы Table почитать среднее значение из 10 предыдущих значений.

Считать скользящее среднее мы будем используя основной цикл перебора значений и вложенный цикл считающий сумму предыдущих 10 значений.

Основным циклом будет цикл for, запишем

for i = 1, #Table, 1 do

Этот цикл будет перебирать по порядку значения таблицы Table.

Для правильного расчета средних значений нам понадобится проверка. Если индекс строки меньше значения «n» (n – период скользящего среднего), то мы не сможем посчитать среднее значение для «n». Например, нельзя посчитать среднее значение за 10 строк имея только 5. Поэтому нам потребуется прописать ограничивающее условие. Расчет скользящего среднего будет начинаться только со строки с индексом n + 1 или по-другому «i» должна быть больше «n» (i > n). С другой стороны когда «i» меньше «n» необходимо все равно чем-то заполнить строки в таблице TableSMA. Это необходимо для того чтобы таблицы Table и TableSMA имели одинаковое количество строк. Добавим условие.

if i < n then

TableSMA[i] = Table[i]

если значение индекса меньше необходимого «n», то в таблицу TableSMA запишется соответствующее значение из таблицы Table, иначе будет выполняться расчет скользящего значения.

На данном этапе у нас получится следующий код:

Еще раз рассмотрим работу строк кода с 11 по 14. В строке 11 мы прописываем цикл, который будет присваивать переменной «i» значения от 1 до #Table (#Table – количество строк в таблице Table), шаг изменения переменной «i» равен 1. Значение переменной «i» мы будем использовать в качестве индекса строки для и таблиц Table и TableSMA. В строке 12 мы проверяем меньше ли «i», индекс строки, чем «n», период скользящего среднего. Если условие верно, то скрипт переходит к строке номер 13, в этой строке мы присваиваем в строку с индексом «i», таблицы TableSMA, значение из строки с индексом «i», таблицы Table. В результате получается, что значения в первых «n» строках, таблиц Table и TableSMA, равны. Если условие в строке 12 не выполняется скрипт переходит к строке 14 иначе. В строках 15 и ниже до оператора end прописывается код расчета среднего значения.

Для расчета среднего значения с периодом 10 нам необходимо сложить 10 предыдущих значений из таблицы Table и разделить их на 10. Используя цикл while, сложим предыдущие значения. Цикл while будет считывать значения в обратном порядке, т.е. от большего значения индекса к меньшему, от текущей строки в таблице «i», до «i» – 10. Добавим переменную, которая будет являться счетчиком обратного хода по таблице Table. Объявим новую переменную «j» и присвоим ей значение из переменной «i», это необходимо, чтобы указать циклу с какой строки начинать обратный ход сложения переменных.

local j = i

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

local Sum = 0

Переменные «j» и «Sum» необходимо объявить в теле условия if i < n then после оператора else поскольку они должны приходить в первоначальное состояние для каждой строки таблицы Table.

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

while j > i — n do

Sum = Sum + Table[j]
j = j – 1

end

Работает этот цикл следующим образом, например: значение «i» = 20, поскольку выше в строке кода 15, мы присваиваем переменной «j» значение переменной «i», то и переменная «j» = 20. Получается нам необходимо начать суммировать значения из таблицы Table со строки 20 и до строки 11 включительно, чтобы получить сумму последних десяти значений. Вычитая из переменной «i» переменную «n», в условии цикла, получаем значение 10, следовательно, пока переменная «j» больше 10, то цикл выполняется. В конце тела цикла (строка кода 19) мы уменьшаем значение переменной «j» на 1, чтобы перейти выше на одну строку таблицы Table.

После того, как цикл выполнится десять раз переменная «j» станет равной 10 и тогда цикл разорвется, программа перейдет на оператор end.

После того как мы нашли сумму последних 10 значений, необходимо разделить сумму на 10 для расчета среднего значения. Среднее значение необходимо записать в соответствующую строку таблицы TableSMA. Соответствующей строкой будет строка с индексом «i».

TableSMA[i] = Sum/n

Код для расчета скользящей средней закончен.Для наглядности выведем на экран значения из таблиц Table и TableSMA в виде двух столбцов. Вывод будем осуществлять, используя цикл for. (Строки кода 25 – 27)

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

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

Количество строк в обеих таблицах одинаковое, поскольку строки в таблице TableSMA мы создавали исходя из строк в таблице Table. В результате выполнения кода мы видим три столбца. Первый столбец это индекс строки таблиц Table и TableSMA, второй столбец это значения из таблицы Table, третий столбец это значения из таблицы TableSMA.

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

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

function SMA(Table, n)

Закроем функцию оператором end.

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

return TableSMA

Вырежем код, начиная со строки кода 17 и по строку 29 включительно. Вставим, вырезанный код в строку кода номер 3. Функция для расчета скользящего среднего готова.

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

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

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

Теперь у нас есть универсальная функция, которая может рассчитать скользящее среднее для любой таблицы и с любым интервалом.Проверим это. Поменяем значение переменной «n» (срока кода 21) на 20 и количество строк, сгенерированное в цикле for (строка кода 24) на 200.

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

В результате выполнения нашего кода, на экране появилось три столбца содержащие 200 строк. В первом столбце индекс строки таблиц Table и TableSMA, во второй строке сгенерированные значения таблицы Table в третьем столбце скользящее среднее с интервалом 20 для сгенерированной таблицы.

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

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