Kaavan (Автор тем)

Выбрать дату в календареВыбрать дату в календаре

Страницы: 1
Ошибка в индикаторе при увеличении таймфрейма
 
Добрый день!
Столкнулся с такой проблемой, которую не могу обойти никакими условиями.
Скорее всего каких-то нюансов не учитываю.

Имеется индикатор, используемый поставляемый вами CMO()
Код
Settings = {
  Name = "*Kaavan Signals TEST", 
  CMO_Period = 14, 
  line = {
      {
        Name = "CMO",
        Color = RGB(0, 255, 0),
        Type = TYPE_POINT,
        Width = 3      
      }
    }
}

function Init()
   func = GetSignals()
   return #Settings.line
end

function OnCalculate(Index) 
   return func(Index, Settings)
end

function GetSignals()
  local FCMO = CMO()                                --Chande Momentum Oscillator ("CMO")
  local dsCMO = {Val = {}, Min = {}, Max = {}}      
  
  return function (I, Fsettings, ds)
    if I < Fsettings.CMO_Period then
      return nil
    else  
      dsCMO.Val[I] = FCMO(I, Fsettings, ds)                                       -- считаем CMO
    end
  end  
end

------------------------------
function CMO() --Chande Momentum Oscillator ("CMO")
   local sum={}
   local sum2={}
   local it = {pp=0, p=0, l=0}
return function (I, Fsettings, ds)
local Fsettings=(Fsettings or {})
local P = (Fsettings.CMO_Period or 14)
local VT = (Fsettings.CMO_VType or CLOSE)
if (P>0) then
   if I == 1 then
      sum={}
      sum2={}
      it = {pp=0, p=0, l=0}
   end
   if CandleExist(I,ds) then
      if I~=it.p then it={pp=it.p, 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)
      if it.l > 1 then
         local diff = GetValueEX(it.p,VT,ds) - GetValueEX(it.pp,VT,ds)
         if diff > 0 then
            sum[Ip] = (sum[Ipp] or 0) + diff
            sum2[Ip] = (sum2[Ipp] or 0)
         elseif diff < 0 then
            sum[Ip] = (sum[Ipp] or 0)
            sum2[Ip] = (sum2[Ipp] or 0) - diff
         elseif diff == 0 then 
            sum[Ip] = (sum[Ipp] or 0)
            sum2[Ip] = (sum2[Ipp] or 0)
         end
      end
      if it.l > P then
         local CMO1 = sum[Ip]-(sum[Ippp] or 0)
         local CMO2 = sum2[Ip]-(sum2[Ippp] or 0)
         return (CMO1 - CMO2) / (CMO1 + CMO2) * 100
      end
   end
end
return nil
end
end

Отрабатывает без ошибок, но при увеличении таймфрейма выдает следующую ошибку:attempt to perform arithmetic on a nil value
на строке 55:
Код
local diff = GetValueEX(it.p,VT,ds) - GetValueEX(it.pp,VT,ds)
Аналогично и с другими используемыми индиктаорами.
В чем может быть проблема и как от неё уйти?
Использование части данных другого индикатора в коде, Работа с типовым шаблоном индикатора
 
Код
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 
 найти ближайший того же типа (мин, макс) и сравнить их значения.
В зависимости от их соотношения выдать сигнал
Использование части данных другого индикатора в коде, Работа с типовым шаблоном индикатора
 
Код
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  
найти ближайший того же типа (мин, макс) и сравнить их значения.
В зависимости от их соотношения выдать сигнал
Страницы: 1
Наверх