Ошибка при расчёте стохастика

Страницы: 1
RSS
Ошибка при расчёте стохастика, Выдаёт ошибку при обращении к SO.lua
 
Здравствуйте.
При попытке расчёта стохастика квик выдаёт ошибку:
SO.lua:311:attempt to call a number value (global 'C').
Подскажите, пожалуйста, что может быть.
 
Цитата
Евгений написал:
Здравствуйте.
При попытке расчёта стохастика квик выдаёт ошибку:
SO.lua:311:attempt to call a number value (global 'C').
Подскажите, пожалуйста, что может быть.
Возможно неправильно указали параметр.
покажите как вызываете.
 
в 311 строке SO.lua
 
Индикатор я не правил, 311 строка:
return (C and C(I)) or (ds and ds:C(I))
 
Весь код индикатора:
Код
Settings = {
Name = "*SO (Stochastic Oscillator)", 
Period = 5, 
Metod = "SMA", --(SMA, MMA, EMA, WMA, SMMA, VMA)
Shift = 3, 
Period_D = 3, 
Metod_D = "SMA", --(SMA, MMA, EMA, WMA, SMMA, VMA)
line = {{
      Name = "Horizontal line (top)",
      Type = TYPE_LINE, 
      Color = RGB(140, 140, 140)
      },
      {
      Name = "Horizontal line (bottom)",
      Type = TYPE_LINE, 
      Color = RGB(140, 140, 140)
      },
      {
      Name = "SO", 
      Type = TYPE_LINE, 
      Color = RGB(221, 44, 44)
      },
      {
      Name = "SO - %D", 
      Type = TYPE_LINE, 
      Color = RGB(0, 206, 0)
      }
      },
Round = "off",
Multiply = 1,
Horizontal_line="30"
}
         
function Init()
   func = SO()
   return #Settings.line
end

function OnCalculate(Index) 
local Out1,Out2 = ConvertValue(Settings, func(Index, Settings))
local HL = tonumber(Settings.Horizontal_line)
   if HL then
      return 50+HL,50-HL,Out1,Out2
   else
      return nil,nil,Out1,Out2
   end
end

function SO() --Stochastic Oscillator ("SO")
   local K_MA1=MA()
   local K_MA2=MA()
   local D_MA=MA()
   local H_tmp={}
   local L_tmp={}
   local it = {p=0, l=0}
return function (I, Fsettings, ds)
local Fsettings=(Fsettings or {})
local P = (Fsettings.Period or 5)
local S = (Fsettings.Shift or 3)
local M = (Fsettings.Metod or SMA)
local PD = (Fsettings.Period_D or 3)
local MD = (Fsettings.Metod_D or SMA)
if (P>0) and (PD>0) then
if I == 1 then 
      H_tmp={}
      L_tmp={}
      it = {p=0, l=0}
   end
   if CandleExist(I,ds) then
      if I~=it.p then it={p=I, l=it.l+1} end
      H_tmp[Squeeze(it.l,P-1)+1] = GetValueEX(it.p,HIGH,ds)
      L_tmp[Squeeze(it.l,P-1)+1] = GetValueEX(it.p,LOW,ds)
      if it.l>=P then
         local val_h=math.max(table.unpack(H_tmp))
         local val_l=math.min(table.unpack(L_tmp))
         local v_K_MA1 = K_MA1(it.l-P+1, {Period=S, Metod = M, VType=ANY},{[it.l-P+1] = GetValueEX(it.p,CLOSE,ds) - val_l})
         local v_K_MA2 = K_MA2(it.l-P+1, {Period=S, Metod = M, VType=ANY},{[it.l-P+1] = val_h - val_l})
         if it.l>=P+S-1 and v_K_MA2~=0 then
            local t_K = 100 * v_K_MA1 / v_K_MA2
            return t_K, D_MA(it.l-(P+S-2), {Period=PD, Metod = MD, VType=ANY}, {[it.l-(P+S-2)] = t_K})
         end
      end
   end
end
return nil,nil
end
end

function MA() --Moving Average ("MA")
   local T_MA = {[SMA]=F_SMA(),[MMA]=F_MMA(),[EMA]=F_EMA(),[VMA]=F_VMA(),[SMMA]=F_SMMA(),[WMA]=F_WMA()}
return function (I, Fsettings, ds)
   local Fsettings=(Fsettings or {})
   local P = (Fsettings.Period or 14)
   if (P > 0) then
      return T_MA[string.upper(Fsettings.Metod or EMA)](I, P, (Fsettings.VType or CLOSE), ds)
   end
return nil
end
end

------------------------------------------------------------------
----Moving Average SMA, MMA, EMA, WMA, SMMA, VMA
------------------------------------------------------------------
--[[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

--[[Modified Moving Average (MMA)
MMA = (MMAi-1*(n-1) + Pi) / n]]
function F_MMA() 
   local sum = {}
   local tmp = {pp=nil, p=nil}
   local it = {p=0, l=0}
return function(I, P, VT, ds)
   if I == 1 then
      sum = {}
      tmp = {pp=nil, p=nil}
      it = {p=0, l=0}
   end
   if CandleExist(I,ds) then
      if I~=it.p then 
         it = {p=I, l=it.l+1} 
         tmp.pp = tmp.p
      end
      local Ip,Ipp,Ippp = Squeeze(it.l,P),Squeeze(it.l-1,P),Squeeze(it.l-P,P)
      if it.l <= P + 1 then
         sum[Ip] = (sum[Ipp] or 0) + GetValueEX(it.p,VT,ds)
         if (it.l == P) or (it.l == P + 1) then
            tmp.p = (sum[Ip] - (sum[Ippp] or 0)) / P
         end
      else
         tmp.p = (tmp.pp*(P-1) + GetValueEX(it.p,VT,ds)) / P
      end
      if it.l >= P then
         return tmp.p
      end
   end
return nil
end
end

--[[Exponential Moving Average (EMA)
EMAi = (EMAi-1*(n-1)+2*Pi) / (n+1)]]
function F_EMA() 
   local tmp = {pp=nil, p=nil}
   local it = {p=0, l=0}
return function(I, P, VT, ds)
   if I == 1 then
      tmp = {pp=nil, p=nil}
      it = {p=0, l=0}
   end
   if CandleExist(I,ds) then
      if I~=it.p then 
         it = {p=I, l=it.l+1} 
         tmp.pp = tmp.p
      end
      if it.l == 1 then
         tmp.p = GetValueEX(it.p,VT,ds)
      else
         tmp.p = (tmp.pp*(P-1) + 2*GetValueEX(it.p,VT,ds)) / (P+1)
      end
      if it.l >= P then
         return tmp.p
      end
   end
return nil
end
end

--[[
William Moving Average (WMA)
( Previous WILLMA * ( Period - 1 ) + Data ) / Period]]
function F_WMA()
   local tmp = {pp=nil, p=nil}
   local it = {p=0, l=0}
return function(I, P, VT, ds)
   if I == 1 then
      tmp = {pp=nil, p=nil}
      it = {p=0, l=0}
   end
   if CandleExist(I,ds) then
      if I~=it.p then 
         it={p=I, l=it.l+1}
         tmp.pp = tmp.p
      end
      if it.l == 1 then
         tmp.p = GetValueEX(it.p,VT,ds)
      else
         tmp.p = (tmp.pp * (P-1) + GetValueEX(it.p,VT,ds)) / P
      end
      if it.l >= P then
         return tmp.p
      end
   end
return nil
end
end

--[[Volume Adjusted Moving Average (VMA)
VMA = sum(Pi*Vi) / sum(Vi)]]
function F_VMA()
   local sum = {}
   local sum2 = {}
   local it = {p=0, l=0}
return function(I, P, VT, ds)
   if I == 1 then
      sum = {}
      sum2 = {}
      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) * GetValueEX(it.p,VOLUME,ds)
      sum2[Ip] = (sum2[Ipp] or 0) + GetValueEX(it.p,VOLUME,ds)
      if it.l >= P then
         return (sum[Ip] - (sum[Ippp] or 0)) / (sum2[Ip] - (sum2[Ippp] or 0))
      end
   end
return nil
end
end

--[[Smoothed Moving Average (SMMA)
SMMAi = (sum(Pi) - SMMAi-1 + Pi) / n]]
function F_SMMA()
   local sum = {}
   local sum2 = {}
   local it = {p=0, l=0}
return function(I, P, VT, ds)
   if I == 1 then
      sum = {}
      sum2 = {}
      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
         if it.l == P then
            sum2[Ip] = (sum[Ip] - (sum[Ippp] or 0)) / P
         else
            sum2[Ip] = ((sum[Ip] - (sum[Ippp] or 0)) - (sum2[Ipp] or 0)+ GetValueEX(it.p,VT,ds)) / P
         end
         return sum2[Ip]
      end
   end
return nil
end
end


SMA,MMA,EMA,WMA,SMMA,VMA = "SMA","MMA","EMA","WMA","SMMA","VMA"
OPEN,HIGH,LOW,CLOSE,VOLUME,MEDIAN,TYPICAL,WEIGHTED,DIFFERENCE,ANY = "O","H","L","C","V","M","T","W","D","A"

function CandleExist(I,ds)
return (type(C)=="function" and C(I)~=nil) or
   (type(ds)=="table" and (ds[I]~=nil or (type(ds.Size)=="function" and (I>0) and (I<=ds:Size()))))
end

function Squeeze(I,P)
   return math.fmod(I-1,P+1)
end

function ConvertValue(T,...)
local function r(V, R) 
   if R and string.upper(R)== "ON" then R=0 end
   if V and tonumber(R) then
      if V >= 0 then return math.floor(V * 10^R + 0.5) / 10^R
      else return math.ceil(V * 10^R - 0.5) / 10^R end
   else return V end
end
local arg = {...}
arg.n = select('#', ...)
   if arg.n > 0 then
      for i = 1, arg.n do
         arg[i]=arg[i] and r(arg[i] * ((T and T.Multiply) or 1), (T and T.Round) or "off")
      end
      return table.unpack(arg)
   else return nil end
end

function GetValueEX(I,VT,ds) 
VT=(VT and string.upper(string.sub(VT,1,1))) or ANY
   if VT == OPEN then         --Open
      return (O and O(I)) or (ds and ds:O(I))
   elseif VT == HIGH then       --High
      return (H and H(I)) or (ds and ds:H(I))
   elseif VT == LOW then      --Low
      return (L and L(I)) or (ds and ds:L(I))
   elseif VT == CLOSE then      --Close
      return (C and C(I)) or (ds and ds:C(I))
   elseif VT == VOLUME then      --Volume
      return (V and V(I)) or (ds and ds:V(I)) 
   elseif VT == MEDIAN then      --Median
      return ((GetValueEX(I,HIGH,ds) + GetValueEX(I,LOW,ds)) / 2)
   elseif VT == TYPICAL then   --Typical
      return ((GetValueEX(I,MEDIAN,ds) * 2 + GetValueEX(I,CLOSE,ds))/3)
   elseif VT == WEIGHTED then   --Weighted
      return ((GetValueEX(I,TYPICAL,ds) * 3 + GetValueEX(I,OPEN,ds))/4) 
   elseif VT == DIFFERENCE then   --Difference
      return (GetValueEX(I,HIGH,ds) - GetValueEX(I,LOW,ds))
   else                     --Any
      return (ds and ds[I])
   end
return nil
end
 
Здравствуйте.

Просьба уточнить текущую версию используемого Вами терминала QUIK, также версию Lua-машины, в которой выполняется запуск индикатора.
 
QUIK 9.7.1.10, lua 5.3.5.и 5.4.1.
 
Здравствуйте.

Не получилось воспроизвести проблему, просьба прислать нам на quiksupport@arqatech.com архив Вашего рабочего места QUIK без ключей pubring.txk и secring.txk, если они там присутствуют. Дополнительная просьба в письме укажите, пожалуйста, ссылку на данную ветвь форума.
 
Цитата
Евгений написал:
function Init()
  func = SO()
  return #Settings.line
end
попробуйте перенести функцию Init в самый конец скрипта
 
Цитата
nikolz написал:
     Цитата         Евгений    написал:
function Init()
 func = SO()
 return #Settings.line
end   попробуйте перенести функцию Init в самый конец скрипта
Здравствуйте.
Не помогло.
Ошибку "311:attempt to call a number value (global 'C')" удалось убрать, поменяв в моём коде, который обращается к файлу индикатора цену C на c.
Но значения индикатора не удаётся получить, появляется ошибка "attempt to concatenate a nil value (global 'so2')".
Видимо я неправильно обращаюсь к индикатору, хотя по подобному запросу к PSAR скрипт получает значения:
Код
dofile(getWorkingFolder()..'\\LuaIndicators\\SO.lua' )
funcSo = SO()
...

for i=1,ds:Size() do
so1, so2 = funcSo(i, {Period = 5, Metod = "SMA", Shift = 3, Period_D = 3, Metod_D = "SMA"}, ds)
so1, so2 = funcSo(ds:Size(), {Period = 5, Metod = "SMA", Shift = 3, Period_D = 3, Metod_D = "SMA"}, ds)
end
 
А Вы используете этот код как индикатор или как скрипт?


Если как скрипт, то не забывайте передавать поток данных, для которого даже есть переменная ds. Или, возможно, Вы просто переопределили глобальную переменную C, например С = 5. Что делать в индикаторе нельзя. Да и в скрипте тоже, если используете этот код, т.к. (C and C(I)) просто проверяет на nil, а уж число там или нет уже не проверяет.
 
Цитата
Евгений написал:
Цитата
nikolz написал:
     Цитата         Евгений    написал:
function Init()
 func = SO()
 return #Settings.line
end   попробуйте перенести функцию Init в самый конец скрипта
Здравствуйте.
Не помогло.
Ошибку "311:attempt to call a number value (global 'C')" удалось убрать, поменяв в моём коде, который обращается к файлу индикатора цену C на c.
Но значения индикатора не удаётся получить, появляется ошибка "attempt to concatenate a nil value (global 'so2')".
Видимо я неправильно обращаюсь к индикатору, хотя по подобному запросу к PSAR скрипт получает значения:
Код
  dofile( getWorkingFolder () .. '\\LuaIndicators\\SO.lua' )
funcSo  =  SO()
 .. .

 for  i =  1 ,ds: Size ()  do 
so1, so2  =  funcSo(i, {Period  =   5 , Metod  =   "SMA" , Shift  =   3 , Period_D  =   3 , Metod_D  =   "SMA" }, ds)
so1, so2  =  funcSo(ds: Size (), {Period  =   5 , Metod  =   "SMA" , Shift  =   3 , Period_D  =   3 , Metod_D  =   "SMA" }, ds)
 end 
  
вы пытаетесь использовать монстра который нагородили разработчики, но они его сами не применяют в квике.
---------------
Проще всего поместите встроенный этот индикатор  на график, задайте идентификатор и прочитайте значения с графика. В результате получите ровно то, что увидите.
--------------  
если надо скрипт на луа, то либо найдите существенно более простой код что то что взяли, либо напишите сами по формуле из вики.
 
по форме этот индикатор написан правильно, но по сути - это издевательство над пользователями.
Писавший эти индикаторы совершенно не понимает зачем они нужны.
 
удивляюсь, как можно такой простой индикатор изложить в виде такого громадного количества операторов.
Полагаю, что разработчику платили по количеству операторов.
 
Цитата
Nikolay написал:
А Вы используете этот код как индикатор или как скрипт?  


Если как скрипт, то не забывайте передавать поток данных, для которого даже есть переменная ds.   Или, возможно, Вы просто переопределили глобальную переменную C, например С = 5. Что делать в индикаторе нельзя.   Да и в скрипте тоже, если используете этот код, т.к. (C and C(I))     просто проверяет на nil, а уж число там или нет уже не проверяет.
Как скрипт, ds есть.
 
Цитата
nikolz написал:
Цитата
 Евгений    написал:
 
Цитата
nikolz  написал:
     Цитата         Евгений    написал:
function Init()
 func = SO()
 return #Settings.line
end   попробуйте перенести функцию Init в самый конец скрипта
  Здравствуйте.
Не помогло.
Ошибку "311:attempt to call a number value (global 'C')" удалось убрать, поменяв в моём коде, который обращается к файлу индикатора цену C на c.
Но значения индикатора не удаётся получить, появляется ошибка "attempt to concatenate a nil value (global 'so2')".
Видимо я неправильно обращаюсь к индикатору, хотя по подобному запросу к PSAR скрипт получает значения:  
Код
    dofile(  getWorkingFolder  ()  ..   '\\LuaIndicators\\SO.lua'  )
funcSo   =   SO()
  ..  .

  for   i  =    1  ,ds:  Size  ()   do  
so1, so2   =   funcSo(i, {Period   =     5  , Metod   =     "SMA"  , Shift   =     3  , Period_D   =     3  , Metod_D   =     "SMA"  }, ds)
so1, so2   =   funcSo(ds:  Size  (), {Period   =     5  , Metod   =     "SMA"  , Shift   =     3  , Period_D   =     3  , Metod_D   =     "SMA"  }, ds)
  end  
    
 
 вы пытаетесь использовать монстра который нагородили разработчики, но они его сами не применяют в квике.
---------------  
Проще всего поместите встроенный этот индикатор на график, задайте идентификатор и прочитайте значения с графика.   В результате получите ровно то, что увидите.
--------------  
если надо скрипт на луа, то либо найдите существенно более простой код что то что взяли, либо напишите сами по формуле из вики.
С графика беру, но не всегда это удобно и быстро. По формуле написать - интересный вариант, но было бы здорово иметь универсальный метод - запрос в луа к индикатору.
 
Брать данные с графика - это крайний вариант, когда неизвестен алгоритм построения. А когда известно, то зачем. Тем более, что приведенный пример - очень неаккуратный. При этом очень неэффективен по памяти.

Что касается этого случая, добавьте дебаг сообщения в лог, если есть или  типа такого message("C "..type©..'' "..tostring©)

И смотрите где теряете переменную.
 
Цитата
Евгений написал:
Цитата
Nikolay написал:
А Вы используете этот код как индикатор или как скрипт?  


Если как скрипт, то не забывайте передавать поток данных, для которого даже есть переменная ds.   Или, возможно, Вы просто переопределили глобальную переменную C, например С = 5. Что делать в индикаторе нельзя.   Да и в скрипте тоже, если используете этот код, т.к. (C and C(I))     просто проверяет на nil, а уж число там или нет уже не проверяет.
Как скрипт, ds есть
Вычисление стохастика по ВИКИ  элементарно просто:
---------------------
x=100*(C(i)-Ln)/(Hn-Ln);  K=Filt(AL1,K,x);    D=Filt(AL,D,K);
---------------------------
где  Hn и Ln  - это максимум и минимум на интервале N
а Filt - это мувинг , например,  такой:  K=Filt(AL1,K,x);
------------------------------
Т е все до безобразия примитивно и просто, как и вся финансовая математика.
---------------
сравните это с монстром, который вам подсунули.
=================
Для справки  - стохастик - это примитивный полосовой фильтр
с очень плохими фильтрующими свойствами.
Параметры этого фильтра биржевые игроки подбирают методом тыка.
 
Цитата
nikolz написал:
     Цитата         Евгений    написал:
 
Цитата
  Николай     написал:
 А Вы используете этот код как индикатор или как скрипт?  


 Если как скрипт, то не забывайте передавать поток данных, для которого даже есть переменная ds.   Или, возможно, Вы просто переопределили глобальную переменную C, например С = 5. Что делать в индикаторе нельзя.   Да и в скрипте тоже, если используете этот код, т.к. (C and C(I)) просто проверяет на nil, а уж число там или нет уже не проверяет.  
  Как скрипт, ds есть   Вычисление стохастика по ВИКИ элементарно просто:
---------------------
x=100*(C(i)-Ln)/(Hn-Ln); K=Filt(AL1,K,x); D=Filt(AL,D,K);  
---------------------------
где Hn и Ln - это максимум и минимум на интервале N
а Filt - это мувинг , например, такой: K=Filt(AL1,K,x);
------------------------------
Т е все до безобразия примитивно и просто, как и вся финансовая математика.
---------------
сравните это с монстром, который вам подсунули.
=================
Для справки - стохастик - это примитивный полосовой фильтр  
с очень плохими фильтрующими свойствами.
Параметры этого фильтра биржевые игроки подбирают методом тыка.
Для меня это не очень просто, т.к. данную формулу нужно адаптировать для своего скрипта, ведь так? Причём делать эту нужно для каждого индикатора, с которым захочется поработать. Пробовал я по другому индикатору это сделать - работает, но значения не те. Всё же, думаю, что удобнее всего было бы получать значения индикатора через запрос к файлу индикатора. Подскажите, где можно посмотреть примеры запросов к индикаторам?
 
Цитата
Евгений написал:
Цитата
nikolz написал:
     Цитата         Евгений    написал:
 
Цитата
  Николай     написал:
 А Вы используете этот код как индикатор или как скрипт?  


 Если как скрипт, то не забывайте передавать поток данных, для которого даже есть переменная ds.   Или, возможно, Вы просто переопределили глобальную переменную C, например С = 5. Что делать в индикаторе нельзя.   Да и в скрипте тоже, если используете этот код, т.к. (C and C(I)) просто проверяет на nil, а уж число там или нет уже не проверяет.  
   Как скрипт, ds есть   Вычисление стохастика по ВИКИ элементарно просто:
---------------------
x=100*(C(i)-Ln)/(Hn-Ln); K=Filt(AL1,K,x); D=Filt(AL,D,K);  
---------------------------
где Hn и Ln - это максимум и минимум на интервале N
а Filt - это мувинг , например, такой: K=Filt(AL1,K,x);
------------------------------
Т е все до безобразия примитивно и просто, как и вся финансовая математика.
---------------
сравните это с монстром, который вам подсунули.
=================
Для справки - стохастик - это примитивный полосовой фильтр  
с очень плохими фильтрующими свойствами.
Параметры этого фильтра биржевые игроки подбирают методом тыка.
Для меня это не очень просто, т.к. данную формулу нужно адаптировать для своего скрипта, ведь так? Причём делать эту нужно для каждого индикатора, с которым захочется поработать. Пробовал я по другому индикатору это сделать - работает, но значения не те. Всё же, думаю, что удобнее всего было бы получать значения индикатора через запрос к файлу индикатора. Подскажите, где можно посмотреть примеры запросов к индикаторам?
напишите, что хотите сделать.
Если Вы делаете индикатор и в нем будете делать робота, то можно использовать код который указали Выше. если вы не можете запустить его как индикатор, то могу выложить немного исправленный этот код который без проблем запускается как индикатор.
-----------------
если хотите как-то иначе использовать этот индикатор, то напишите подробнее, что хотите сделать.
будет настроение, подскажу как.
 
Цитата
Евгений написал:
Цитата
Подскажите, где можно посмотреть примеры запросов к индикаторам?
Функции для работы с графиками

  • getLinesCount
  • getNumCandles
  • getCandlesByIndex
 
Цитата
nikolz написал:
     Цитата         Евгений    написал:
 
Цитата
 Подскажите, где можно посмотреть примеры запросов к индикаторам?
  Функции для работы с графиками
    Получить количество строк
  getNumCandles
  Получитьcan
Цитата
nikolz написал:
     Цитата         Евгений    написал:
 
Цитата
  никольц     написал:
 Цитата Евгений написал:  
        Цитата         Николай написал:  
 А Вы используете этот код как индикатор или как скрипт?  


 Если как скрипт, то не забывайте передавать поток данных, для которого даже есть переменная ds.   Или, возможно, Вы просто переопределили глобальную переменную C, например С = 5. Что делать в индикаторе нельзя.   Да и в скрипте тоже, если используете этот код, т.к. (C and C(I)) просто проверяет на nil, а уж число там или нет уже не проверяет.  
  Как скрипт, ds есть Вычисление стохастика по ВИКИ элементарно просто:  
 ---------------------  
 x=100*(C(i)-Ln)/(Hn-Ln); K=Filt(AL1,K,x); D=Filt(AL,D,K);  
 ---------------------------  
 где Hn и Ln - это максимум и минимум на интервале N  
 а Filt - это мувинг , например, такой: K=Filt(AL1,K,x);  
 ------------------------------  
 Т е все до безобразия примитивно и просто, как и вся финансовая математика.  
 ---------------  
 сравните это с монстром, который вам подсунули.  
 =================  
 Для справки - стохастик - это примитивный полосовой фильтр  
 с очень плохими фильтрующими свойствами.  
 Параметры этого фильтра биржевые игроки подбирают методом тыка.     Для меня это не очень просто, т.к. данную формулу нужно адаптировать для своего скрипта, ведь так?   Причём делать эту нужно для каждого индикатора, с которым захочется поработать.   Пробовал я по другому индикатору это сделать - работает, но значения не те.   Всё же, думаю, что удобнее всего было бы получать значения индикатора через запрос к файлу индикатора.   Подскажите, где можно посмотреть примеры запросов к индикаторам?   напишите, что хотите сделать.
Если Вы делаете индикатор и в нем будете делать робота, то можно использовать код который указали Выше.   если вы не можете запустить его как индикатор, то могу выложить немного исправленный этот код который без проблем запускается как индикатор.
-----------------
если хотите как-то иначе использовать этот индикатор, то напишите подробнее, что хотите сделать.
будет настроение, подскажу как.
 Пишу робота, который запрашивает показания индикатора из его файла (в папке LuaIndicators), т.е.не открывая график и, исходя из полученных данных, выполняет транзакции. getNumCandles только с графика берёт данные, как я понял.
 В приведённом мною фрагменте кода для запроса данных с файла индикатора я нашёл ошибку - не хватало
end
while true do :
Код
    dofile(  getWorkingFolder  ()  ..   '\\LuaIndicators\\SO.lua'  )
funcSo   =   SO()
  ..  .

  for   i  =    1  ,ds:  Size  ()   do  
so1, so2   =   funcSo(i, {Period   =     5  , Metod   =     "SMA"  , Shift   =     3  , Period_D   =     3  , Metod_D   =     "SMA"  }, ds)

end 
while true do

so1, so2   =   funcSo(ds:  Size  (), {Period   =     5  , Metod   =     "SMA"  , Shift   =     3  , Period_D   =     3  , Metod_D   =     "SMA"  }, ds)
  end 

 
Возникла новая проблема - получить значения индикатора с нескольких предыдущих свечек. Пробовал поменять запрос so1,so2=funcSo(ds:Size(),..  на so1,so2=funcSo(ds:Size()-1,... или менял цикл  for i=1,ds:Size() do  на  for i=1,ds:Size()-1 do, получается ерунда. Подскажите?
 
Цитата
Евгений написал:
Возникла новая проблема - получить значения индикатора с нескольких предыдущих свечек. Пробовал поменять запрос so1,so2=funcSo(ds:Size(),..  на so1,so2=funcSo(ds:Size()-1,... или менял цикл  for i=1,ds:Size() do  на  for i=1,ds:Size()-1 do, получается ерунда. Подскажите?
так как вы хотите использовать этот индикатор без отображения на графике то для начала исправьте исходный файл и уберите все лишнее:
1) надо выкинуть это:
Код
Settings = {
Name = "*SO (Stochastic Oscillator)", 
Period = 5, 
Metod = "SMA", --(SMA, MMA, EMA, WMA, SMMA, VMA)
Shift = 3, 
Period_D = 3, 
Metod_D = "SMA", --(SMA, MMA, EMA, WMA, SMMA, VMA)
line = {{
      Name = "Horizontal line (top)",
      Type = TYPE_LINE, 
      Color = RGB(140, 140, 140)
      },
      {
      Name = "Horizontal line (bottom)",
      Type = TYPE_LINE, 
      Color = RGB(140, 140, 140)
      },
      {
      Name = "SO", 
      Type = TYPE_LINE, 
      Color = RGB(221, 44, 44)
      },
      {
      Name = "SO - %D", 
      Type = TYPE_LINE, 
      Color = RGB(0, 206, 0)
      }
      },
Round = "off",
Multiply = 1,
Horizontal_line="30"
}
         
function Init()
   func = SO()
   return #Settings.line
end

function OnCalculate(Index) 
local Out1,Out2 = ConvertValue(Settings, func(Index, Settings))
local HL = tonumber(Settings.Horizontal_line)
   if HL then
      return 50+HL,50-HL,Out1,Out2
   else
      return nil,nil,Out1,Out2
   end
end

2) Из большого числа скользящих средних взять то, которое будете использовать
Остальное выкинуть.
-------------------
3) Переписать  функцию SO, указав в ней функцию из 2
--------------------------
В результате у Вас будет скрипт очень похожий на то, что я написал Выше.
в итоге не будет кучи ошибок и все будет просто и понятно.
-----------
Если захотите другую функцию сглаживания то просто замените ее в скрипте.
 
Цитата
Евгений написал:
Возникла новая проблема - получить значения индикатора с нескольких предыдущих свечек. Пробовал поменять запрос so1,so2=funcSo(ds:Size(),..  на so1,so2=funcSo(ds:Size()-1,... или менял цикл  for i=1,ds:Size() do  на  for i=1,ds:Size()-1 do, получается ерунда. Подскажите?
чтобы получить значения индикатора с предыдущих свечей надо сохранять значения индикатора в массиве
тогда значения предыдущие читаете из массива по индексу влево от длины массива.
т е
local t={}
t[#t+1]=текущее значение индикатора

читаем значение на 1 свечу назад
x=t[#t-1]
на 2 свечи
x=t[#t-2]
Страницы: 1
Читают тему
Наверх