Блог им. autotrade
--[[ SMA list template v1 --]] Settings= { Name = "SMA_list_magic_template_v1", -- indicator name sign=0, ln1=10, -- period ln2=20, -- period ln3=30, -- period ln4=40, -- period ln5=50, -- period ln6=60, -- period line= { { Name = "SMA_TEMPL", Type =TYPE_LINE, Width = 1, Color = RGB(0,0,0) }, { Name = "SMA_TEMPL", Type =TYPE_LINE, Width = 1, Color = RGB(255,0,0) }, { Name = "cur3", Type =TYPE_TRIANGLE_DOWN, Width = 5, Color = RGB(255, 0, 0) }, { Name = "cur4", Type =TYPE_TRIANGLE_UP, Width = 5, Color = RGB(0, 0, 255) } } } function Init() sma = {{},{}} sum = {{},{}} ln = {} n = {} sumln = 0 m = {} return 4 end function GetSMA(index, num) if index == 1 then if num == 1 then ln[num] = Settings.ln1 end if num == 2 then ln[num] = Settings.ln2 end if num == 3 then ln[num] = Settings.ln3 end if num == 4 then ln[num] = Settings.ln4 end if num == 5 then ln[num] = Settings.ln5 end if num == 6 then ln[num] = Settings.ln6 end sumln = sumln + ln[num] sum[num] = {} sum[num][index] = O(index) n[num]=1 else if index > ln[num] then sum[num][index] = sum[num][index-1] + O(index) sum[num][index] = sum[num][index] - O(index-ln[num]) else sum[num][index] = sum[num][index-1] + O(index) n[num] = n[num] + 1 end end if n[num] ~= 0 then if num == 1 then sma[index] = {} end sma[index][num] = sum[num][index]/n[num] end return sma[index][num] end function GetMagic(index, num) res = 0 val = 0 cnt = 3+num if index > ln[num] then val = sma[index][num] for i = 1, cnt do val = val + (O(index) - O(index-ln[num]+i))/ln[num] if O(index) >= val or val >= sma[index][num] then res = res + (ln[num]/sumln)*(i/cnt) end if O(index) < val or val < sma[index][num] then res = res - (ln[num]/sumln)*(i/cnt) end end end return res end function OnCalculate(index) GetSMA(index, 1) GetSMA(index, 2) GetSMA(index, 3) GetSMA(index, 4) GetSMA(index, 5) GetSMA(index, 6) m[index] = GetMagic(index, 1) m[index] = m[index] + GetMagic(index, 2) m[index] = m[index] + GetMagic(index, 3) m[index] = m[index] + GetMagic(index, 4) m[index] = m[index] + GetMagic(index, 5) m[index] = m[index] + GetMagic(index, 6) if index == Size() then if Settings.sign == 1 then for i = 2, Size() do if m[i] ~= nil and m[i-1] ~= nil then if 0 < m[i] and 0 >= m[i-1] then SetValue(i, 4, O(i)) else if 0 > m[i] and 0 <= m[i-1] then SetValue(i, 3, O(i)) else SetValue(i, 3, nil) SetValue(i, 4, nil) end end end end end; end; if Settings.sign == 0 then return 0, m[index] end end
В который раз я вижу в Ваших индикаторах, что для каждого нового бара происходит цикл перебора от начала до конца. Есть такая зависимость?
Представьте, что на графике 60 тыс. бар.
autotrade, Нет, т.к. при инициализации индикатора минимум два (иногда три) раза происходит проход от 1-ого до последнего индекса. Зачем — вопрос разработчикам. Т.е. if index == Size() будет два раза при инициализации. Это раз.
Два — функция OnCalculate вызывается на каждый тик (почти) для текущего бара, который как раз является последним. Т.е. после построения графика на истории, идет вызов на текущих данных, и каждый раз будет бегать от начала.
autotrade, Не очень понятно зачем мне это, если только меня еще раз не попросят сделать скрипт на базе Вашего индикатора. Тогда да, придется переделывать. Подход очень простой — если Вы уже один раз установили данные линии через SetValue на каком-то индексе и они не изменяются при приходе нового индекса, то их не надо заново устанавливать, а надо обновить (установить) данные линий текущего индекса.
Если Вы рассчитываете, для примера, простейшую SMA, то на истории данные вывели, а далее только для каждого нового индекса. Зачем выводить данные, которые уже выведены и не могут измениться.