Использование части данных другого индикатора в коде

Страницы: 1
RSS
Использование части данных другого индикатора в коде, Работа с типовым шаблоном индикатора
 
Код
function CMOExtremum()
  local CMOlenght = 20
  local FCMO = CMO()
  
  return function (I, Fsettings, ds)

    local CMOValues = {}
    
    CMOValues[1] = FCMO(I, Fsettings, ds)
    CMOValues[2] = FCMO(I+1, Fsettings, ds)
    
    return CMOValues[2]
  end
end

Добрый день!
Для расчета индикатора мне нужны пара десятков последних значений индикатора CMO, который я рассчитываю в этом же файле.

Я предположил, что для этого мне нужно создать массив, в который вызвать функцию СМО для значений индекса от I до I-20
Но получается какая-то ерунда.
Т.е. если смотреть код выше: если возвращать CMOValues[1], то выход индикатора совпадает с СМО
Ожидается, что возврат CMOValues[2] даст ту же картину, но смещенную на один бар назад.
Но нет. Получается совсем другая кривая.

Предположу, что нужно задействовать Squeeze и GetValueEX, не предположу как.
Подскажите, пожалуйста, как решить задачу эффективно?

Для понимания опишу постановку. При возникновении экстремума на CMO
Код
    if CMOValues[2] > CMOValues[1] and CMOValues[2] > CMOValues[3] then
      maxCMO1 = CMOValues[2]
    end  
    if CMOValues[2] < CMOValues[1] and CMOValues[2] < CMOValues[3] then
      minCMO1 = CMOValues[2]
    end  
найти ближайший того же типа (мин, макс) и сравнить их значения.
В зависимости от их соотношения выдать сигнал
 
Цитата
Kaavan написал:
Я предположил, что для этого мне нужно создать массив, в который вызвать функцию СМО для значений индекса от I до I-20
В readme_LuaIndicators.txt четко сказано:
Цитата
Все функции требуют предварительного расчета начиная с индекса 1.
Т.е. даже если нужен только последний индекс, все равно требуется провести цикл расчета начиная с самого первого индекса.

настоятельно рекомендуем читать инструкции прежде чем что-то делать
 
Читал, но не в полной мере осознал.
Спасибо за ответ.
Т.е. в моем случае нужно будет циклом от 1 до I просчитать CMO, поместить результаты в массив и работать далее с ним как с источником данных?  
 
в этом смысле никак не могу осознать расчет SMA.
Получается таблица sum накапливает данные с каждым вызовом?
Код
--[[Simple Moving Average (SMA)
SMA = sum(Pi) / n]]
function F_SMA()
   local sum = {}
   local it = {p=0, l=0}
return function (I, P, VT, ds)
   if I == 1 then
      sum = {}
      it = {p=0, l=0}
   end
   if CandleExist(I,ds) then
      if I~=it.p then it={p=I, l=it.l+1} end
      local Ip,Ipp,Ippp = Squeeze(it.l,P),Squeeze(it.l-1,P),Squeeze(it.l-P,P)
      sum[Ip] = (sum[Ipp] or 0) + GetValueEX(it.p,VT,ds)
      if it.l >= P then
         return (sum[Ip] - (sum[Ippp] or 0)) / P
      end
   end
return nil
end
end
 
Цитата
Kaavan написал:
Т.е. в моем случае нужно будет циклом от 1 до I просчитать CMO, поместить результаты в массив и работать далее с ним как с источником данных?
да

Цитата
Kaavan написал:
Получается таблица sum накапливает данные с каждым вызовом?
да
 
Всё получилось красиво. Спасибо!
 
Код
function CMO_trends()
  local FCMO = CMO()
  local dsCMO = {Val = {}, Min = {}, Max = {}}
  
  return function (I, Fsettings, ds)
    local CMO_upTrend, CMO_downTrend
    
    local mn = #dsCMO.Min
    local mx = #dsCMO.Max
    
    dsCMO.Val[I] = FCMO(I, Fsettings, ds)                                       -- считаем CMO
    
    if I > Settings.CMO_Period and dsCMO.Val[I] ~= nil and dsCMO.Val[I-1] ~= nil and dsCMO.Val[I-2] ~= nil then
      if dsCMO.Val[I-1] > dsCMO.Val[I] and dsCMO.Val[I-1] > dsCMO.Val[I-2] then
        dsCMO.Max[mx+1] = dsCMO.Val[I-1]                                        -- определяем очередной максимум CMO
        CMO_downTrend =  mx>0 and dsCMO.Max[mx+1] < dsCMO.Max[mx]               -- если максимум ниже предыдущего - нисходящий тренд
      end  
      
      if dsCMO.Val[I-1] < dsCMO.Val[I] and dsCMO.Val[I-1] < dsCMO.Val[I-2] then
        dsCMO.Min[mn+1] = dsCMO.Val[I-1]                                        -- определяем очередной минимум CMO
        CMO_upTrend =  mn>0 and dsCMO.Max[mn+1] < dsCMO.Max[mn]                 -- если минимум ниже предыдущего - восходящий тренд
        end 
    end 
    
    return CMO_upTrend and 10 or nil, CMO_downTrend and -10 or nil
  end
end
может этот фрагмент кому-то поможет
 
Извините, в коде выше опечатки.
Вот работающий:
Код
function CMO_trends()
  local FCMO = CMO()
  local dsCMO = {Val = {}, Min = {}, Max = {}}
  
  return function (I, Fsettings, ds)
    local CMO_upTrend, CMO_downTrend
    
    local mn = #dsCMO.Min
    local mx = #dsCMO.Max
    
    dsCMO.Val[I] = FCMO(I, Fsettings, ds)                                       -- считаем CMO
    
    if I > Settings.CMO_Period and dsCMO.Val[I] ~= nil and dsCMO.Val[I-1] ~= nil and dsCMO.Val[I-2] ~= nil then
      if dsCMO.Val[I-1] > dsCMO.Val[I] and dsCMO.Val[I-1] > dsCMO.Val[I-2] then
        dsCMO.Max[mx+1] = dsCMO.Val[I-1]                                        -- определяем очередной максимум CMO
        CMO_downTrend =  mx>0 and dsCMO.Max[mx+1] < dsCMO.Max[mx]               -- если максимум ниже предыдущего - нисходящий тренд
      end  
      
      if dsCMO.Val[I-1] < dsCMO.Val[I] and dsCMO.Val[I-1] < dsCMO.Val[I-2] then
        dsCMO.Min[mn+1] = dsCMO.Val[I-1]                                        -- определяем очередной минимум CMO
        CMO_upTrend =  mn>0 and dsCMO.Min[mn+1] > dsCMO.Min[mn]                 -- если минимум выше предыдущего - восходящий тренд
        end 
    end 
    
    return CMO_upTrend and 10 or nil, CMO_downTrend and -10 or nil
  end
end
Страницы: 1
Читают тему
Наверх