Найти тему

Доступ к ценам при написании собственного индикатора на QLUA (на примере скользящей средней)

Всем привет!

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

Итак, поехали.

Я сразу же привожу код такого индикатора:

Settings=
{
Name="Скользящая средняя",
N = 5,
line = {
{
Color = RGB(255,0,0),
Type = TYPE_LINE,
Width = 2
}
}
}
function Init()
return 1
end
function OnCalculate(index)
if (index < Settings.N) then
return nil
end
local start_ave = index - Settings.N + 1 -- номер свечи для начала расчета
local summ = 0
for i = start_ave, index do
summ = summ + C(i)
end
return summ/Settings.N
end

🧐 Посмотреть код

💾 Скачать код

И давайте подробно разберем этот код.

Таблица Settings. В ней мы указываем название индикатора, добавим свойство N – это количество свечей по умолчанию, по которым будет строиться средняя. Ну и также в таблице Settings есть стандартная таблица line, в которой мы описываем свойства линии, которая будет отображать индикатор.

Функция Init() у нас тоже без изысков – просто указываем, что у нас будет одна линия.

А вот функция OnCalculate будет уже интереснее. Во-первых, напомню, что данная функция срабатывает для каждой свечи. Причем, переменная index – это номер свечи на графике начиная с крайней левой свечи (самой ранней). И эта первая свеча имеет индекс 1.

Собственно, зная это понять код достаточно просто.

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

if (index < Settings.N) then
return nil
end

Этим кодом мы указываем, что не нужно делать расчеты, если номер свечи у нас меньше, чем количество свечей, по которым мы хотим построить среднюю. А это значение у нас лежит в свойстве Settings.N

Далее мы вычисляем номер свечи с которой нужно начать расчет:

local start_ave = index - Settings.N + 1 -- номер свечи для начала расчета

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

И тут нужно отдельно остановиться. Если Вы помните, то в обычном скрипте, что бы получить данные свечей, нужно было использовать специальные команды (CreateDataSource). Результат выполнения данной команды выкладывался в переменную. И потом функциями O(), C(), L(), H() можно было получать данные открытия, закрытия, максимума, минимума конкретной свечи.

Это рассматривалось в отдельном выпуске (https://dzen.ru/a/Y80A0AlxWCadxQUd)

Но, при написании индикатора все проще. Команда CreateDataSource не нужна. Дело в том, что при построении индикатора подразумевается, что нам нужны данные по тому, графику, который открыт в настоящее время. И нет необходимости данные гонять по переменным. Просто нужны данные закрытия свечи – указываем C(i), где i – номер свечи. И так далее.

Я думаю, что теперь вам понятен сакральный смысл этого кода:

summ = summ + C(i)

Мы просто суммируем цены закрытия свечей.

Ну и наконец, с помощью команды return мы указываем значение, которое нужно отобразить на индикаторе по текущей свече:

return summ/Settings.N

Если мы нарисуем этот индикатор, то получим такую кривую:

-2

Через позицию «Редактировать…» меню правой клавиши мы можем изменить значение N которое мы использовали в качестве среднего значения.

-3

Давайте немного модифицируем скрипт и нарисуем сразу две скользящих средних – по умолчанию возьмем период 5 свечей и 20 свечей (примерно одна неделя и один месяц, если мы смотрим график дневных свечей).

Код такого индикатора будет выглядеть так:

Settings=
{
Name="Скользащая средняя+",
N1 = 5,
N2 = 20,
line = {
{
Color = RGB(255,0,0),
Type = TYPE_LINE,
Width = 2
},
{
Color = RGB(0,255,0),
Type = TYPE_LINE,
Width = 2
}
}
}
function Init()
return 2
end
function OnCalculate(index)
local result1 = nil
local result2 = nil
if (index < Settings.N1) then
result1 = nil
else
local start_ave = index - Settings.N1 + 1 -- номер свечи для начала расчета длЯ первой средней
local summ = 0
for i = start_ave, index do
summ = summ + C(i)
end
result1 = summ/Settings.N1
end
if (index < Settings.N2) then
result2 = nil
else
start_ave = index - Settings.N2 + 1 -- номер свечи для начала расчета длЯ второй средней
summ = 0
for i = start_ave, index do
summ = summ + C(i)
end
result2 = summ/Settings.N2
end
return result1, result2
end

💾 Скачать данный код

🧐 Посмотреть данный код

Итак, давайте рассмотрим данный код.

В таблице Settings в поле line добавилось описание второй линии. Также добавилась переменная N2 – указывающая по умолчанию, что будет построена скользящая средняя по 20 предыдущим свечам. А переменную N из предыдущего примера переименовали в N1.

В функции Init() указываем, что у нас будет две линии.

А в функции OnCalculate инициализируем две переменные – result1 и result2 для последующего вывода в них значений индикаторов скользящих средних.

И последовательно вычисляем значения средних – сначала для первого интервала, длина которого определена в переменной Settings.N1, затем среднюю для второго интервала, длина которого определена в переменной Settings.N2.

Командой return возвращаем вычисленные значения

return result1, result2

Если построить такой индикатор, то получится что-то такое:

-4

Также через пункт «Редактировать…» можно поменять длину интервалов, по которым будут вычисляться средние (N1, N2).

-5

💥 В заключении я расскажу еще об одном приеме, который может быть очень полезен при отрисовке большого количества линий индикатора. Особенно, если вы захотите заштриховать какую-то область (в последующих выпусках я покажу как это можно сделать).

Так вот, если вам нужно нарисовать много линий, то не обязательно под значение каждой в функции OnCalculate() отводить отдельную переменную. Все значения можно складывать в отдельную таблицу, например, results. А в команде return применить команду unpack, которая разложит все данные. То есть так:

return unpack(results)

На сегодня у меня всё.

Задавайте вопросы, если что-то не понятно. Обязательно подписывайтесь на канал, чтобы не пропустить новые выпуски. Ставьте лайки, проявляйте прочую активность, за что я буду вам премного благодарен.

Всем счастливо, всем пока.🖐

⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇

📃 Краткое содержание данного канала.

➖➖➖➖➖➖➖➖➖➖➖➖➖

Landingcentr.ru - разработка сайтов для малого и среднего бизнеса.

⬆⬆⬆⬆⬆⬆⬆⬆⬆⬆⬆⬆⬆⬆⬆⬆⬆⬆⬆⬆⬆⬆⬆⬆⬆⬆⬆⬆⬆⬆⬆⬆⬆⬆⬆⬆