Циклы FOR, WHILE, REPEAT в QLua (lua)

Автор записи: Дмитрий (Admin)
1 звезда2 звезды3 звезды4 звезды5 звезд (Голосов 5, среднее: 5,00 из 5)
Загрузка...

Qlua-основы
В скриптовом языке QLua есть 3 вида циклов (for, while и repeat):

1. FOR - DO - END имеет 2 типа:

-- 1-й тип:
 
   -- Цикл сделает 10 итераций, увеличивая каждый раз переменную i на 1, т.е. i будет меняться от 0 до 9,
   -- переменная i является локальной для цикла, т.е. видна только внутри него
   for i = 0, 9, 1 do
      A = A*2;
   end;
   -- Данный цикл можно было записать и без 3-го аргумента, потому что по умолчанию он равен 1
   for i = 0, 9 do
      A = A*2;
   end;
   -- Но вместо 1 можно использовать любое другое число, или выражение, результат которого является числом
   -- Например так, цикл сделает только 5 итераций и остановится, потому что в 6-й итерации i будет равна 10 (0,2,4,6,8,10), а 10 > 9
   for i = 0, 9, 2 do
      A = A*2;
   end;
   -- Здесь используется выражение, т.е. каждая итерация увеличивает переменную i на 2
   for i = 0, 9, 1+1 do
      A = A*2;
   end;
   -- Можно сделать цикл на убывание
   for i = 9, 0, -1 do
      A = A*2;
   end;
 
-- 2-й тип:
 
-- Такой вариант при каждой итерации записывает в i индекс, а в value значение элемента из массива Array, 
-- перебирая, таким образом, все элементы в массиве типа {[1] = 10, [2] = "Текст", [3] = 50}
for i,value in ipairs(Array) do
   -- здесь какой-то блок кода
end;
 
-- Такой вариант при каждой итерации записывает в key ключ, а в value значение элемента из массива Array, 
-- перебирая, таким образом, все элементы в массиве типа {red = "Красный", green = "Зеленый", blue = "синий"}
for key,value in pairs(Array) do
   -- здесь какой-то блок кода
end;

2.WHILE - DO - END

while A < 10 do
   -- здесь какой-то блок кода 
end;
-- Читается так: ПОКА выполняется условие A меньше 10 ВЫПОЛНЯТЬ(делать) блок кода КОНЕЦ

3.REPEAT - UNTIL

repeat
   -- здесь какой-то блок код
until A < 10
-- Читается так: ПОВТОРЯТЬ блок кода ДО ТОГО, пока не выполняется условие A меньше 10

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

for i = 0, 9, 1 do
   if i >= 2 then break; end; -- цикл завершится на 3-й итерации (0,1,2)
end;

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

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

Циклы FOR, WHILE, REPEAT в QLua (lua): 51 комментарий

  1. Если поставить условие if (indx == Size()) then end , то ошибка attempt to compare number with nil пропадает, но расчёт тогда производится только в указанное время, а надо, чтобы при загрузке или смене инструмента в любое время

  2. Всем привет! Подскажите причину происхождения ошибки в теле цикла for "attempt to compare number with nil" при осуществлении индикатором расчётов .

    LUA
    if tt.hour == h and tt.min == m then
    t_table = tt
    HIGH = H(indx)
    LOW = L(indx)

    for i = 0, inter-1 do
    if H(indx-i) > HIGH then
    HIGH = H(indx-i);
    end
    if L(indx-i) < LOW then
    LOW = L(indx-i);
    end
    end

    /LUA

    1. В данном куске кода многие переменные не описаны, так что буду догадываться.
      Когда indx = 1 Запускается цикл for
      В первой итерации переменная i = 0, значит indx-i ( где 1-0 ) Дает в условии H(1) то есть high первого бара.
      Во второй итерации переменная i уже равна 1, а значит indx-i ( где 1-1 ) дает в условии H(0), то есть high нулевого бара, такого бара на графике нет, вот тут то и появляется nil
      Далее во всех итерациях запрашивается high не существующих баров -1 -2 -3 ... Сколько итераций в цикле не известно, потому что в этом коде не указано значение переменной inter

      1. Добрый день, Павел! Тогда скажите, как же тогда индикатор работает, если баров не существует, ведь рассчитывается значение правильно Если же добавить условие if (indx == Size()) then end , то ошибка пропадает. Период для М5 для нахождение экстремумов вчерашнего дня и созерцания их в дне сегодняшнем от начала времён.

        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
        
        Settings= {
        Name = "*HIGH-LOW_YESTERDAY",
        period = 162,
        line =
         
        {
        	{
        		Name = "HIGH",
        		Color = RGB(255, 255, 255),
        		Type = TYPE_LINE,
        		Width = 3,
         
        	},
        	{
        		Name = "LOW",
        		Color = RGB(255, 255, 255),
        		Type = TYPE_LINE,
        		Width = 3,
         
        	},
        }
         
        }
         
        function Init()
        return #Settings.line
        end
         
        		local inter = Settings.period
        		local t_table = {}
        		local HIGH
        		local LOW
         
         
        function OnCalculate(indx)
         
        	local tt = T(indx)
         
          if (indx == Size()) then
         
        	if tt.hour == 23
        	and	tt.min == 45
        	then
        		t_table = tt
         
        		HIGH = H(indx)
        		LOW = L(indx)
         
        					for i = 0, inter-1 do
        						if H(indx-i) &gt; HIGH then
        						HIGH = H(indx-i);
        						end
        						if L(indx-i) &lt; LOW then
        						LOW = L(indx-i);
        						end
        					end
        						for i = 1, indx do
        						SetValue(i, 1, HIGH);
        						SetValue(i, 2, LOW);
        						end
         
        	end
         
           end
         
        	return HIGH, LOW
        end
      2. Предыдущий не работает всё время,а только в указанное, а вот этот работает всегда, но выдаёт ошибку

        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
        
        Settings= {
        Name = "*HIGH-LOW_RGB",
        period = 162,
        line =
         
        {
        	{
        		Name = "HIGH",
        		Color = RGB(255, 255, 255),
        		Type = TYPE_LINE,
        		Width = 3,
         
        	},
        	{
        		Name = "LOW",
        		Color = RGB(255, 255, 255),
        		Type = TYPE_LINE,
        		Width = 3,
         
        	},
        }
         
        }
         
        function Init()
        return #Settings.line
        end
         
        		local inter = Settings.period
        		local t_table = {}
        		local HIGH
        		local LOW
         
         
        function OnCalculate(indx)
         
         
         
        	local tt = T(indx)
         
         
         
        		if tt.hour == 23 and tt.min == 45 then
        			t_table = tt
        			HIGH = H(indx)
        			LOW = L(indx)
         
         
        					for i = 0, inter-1 do
        						if H(indx-i) &gt; HIGH then
        						HIGH = H(indx-i);
        						end
        						if L(indx-i) &lt; LOW then
        						LOW = L(indx-i);
        						end
        					end
        						for i = 1, indx do
        						SetValue(i, 1, HIGH);
        						SetValue(i, 2, LOW);
        						end
        		end
         
        	return HIGH, LOW
        end
        1. Вот Вы и отвечаете на свой вопрос. Потому что он работает не все время.
          В варианте где есть if (indx == Size()) then вычисления идут только тогда, когда indx = Size(), а это значит что indx равен количеству баров на графике. У Вас график содержит 1 бар или тысячи? скорее всего тысячи.
          Предположим что на графике 3000 баров, значит когда indx равен 3000, только в этом случае выполняется вычисления, а дальше...
          Запускается цикл for
          первая итерация, переменная i = 0 переменная indx = 3000 Вы запрашиваете H(3000-0)
          вторая итерация, переменная i = 1 переменная indx = 3000 Вы запрашиваете H(3000-1)
          третья итерация, переменная i = 2 переменная indx = 3000 Вы запрашиваете H(3000-2)
          Вот и работает Ваш код нормально, потому что бары с индексами 3000, 2999, 2998 реально существуют на графике, по этому и ошибки нет.
          Но у Вас еще условие стоит что вычисления нужно выполнять только тогда, когда последний бар имеет время 23:45, в остальное время вычисления не выполняются.