подписаться на 2 таймфрейма

Страницы: 1
RSS
подписаться на 2 таймфрейма
 
Подскажите как грамотно подписаться в одном скрипте на два таймфрейма?

Код
rsi_tf=INTERVAL_M5
mov_tf=INTERVAL_M1
Код
function main()
for key,sec in pairs(fut_list) do
    DataSource(class,sec,rsi_tf)    
    DataSource(class,sec,mov_tf)    
    
end
end
Код
function mycallbackforallstocks(class,sec,index)         

end

 function DataSource(class,sec,interval)
   ds[sec] = CreateDataSource(class,sec,interval)
   ds[sec]:SetUpdateCallback(function(...) mycallbackforallstocks(class,sec,...) end)
   return ds[sec]
end
надо ли заводить вторую таблицу типа ds?
Спасибо
 
Цитата
Let_it_go написал:
надо ли заводить вторую таблицу типа ds?

Это зависит от того что вы будете дальше делать с данными.
Если Вам нужно дальше работать с источником ds то да надо создавать отдельный ds, если нет, то нет.
 
ds это зарезирвированное имя или можно какие угодно брать литеры?
 
Let_it_go,

ds это пример скопированный из документации.
С тем же успехом можно написать что угодно.
 
Взгляните пожалуйста на такой вариант. Не происходит ли тут лишних действий, всё ли экономно в плане получения и подсчёта индикаторов?
Код
ds={}
ds_minutes={}
Код
function mycallbackforallstocks(class,sec,index)         

end

function DataSource(class,sec,interval)
   ds[sec] = CreateDataSource(class,sec,interval)
   ds[sec]:SetUpdateCallback(function(...) mycallbackforallstocks(class,sec,...) end)
   return ds[sec]
end

 function DataSource_minutes(class,sec,interval)
   ds_minutes[sec] = CreateDataSource(class,sec,interval)
   ds_minutes[sec]:SetUpdateCallback(function(...) mycallbackforallstocks(class,sec,...) end)
   return ds[sec]
end
Код
function main()
for key,sec in pairs(fut_list) do
    DataSource(class,sec,rsi_tf)    
    DataSource_minutes(class,sec,mov_tf)
    
end
.............

while is_run do

for key,sec in pairs(fut_list) do
sleep (1000)
func = RSI()
local rsi_count={}
num_candles=ds[sec]:Size()
last_price[sec]=ds[sec]:C(num_candles)   
for i=1,num_candles do
 rsi_count[i]=func(i, {Period=rsi_period, VType="Typical"}, ds[sec])
end 
.....................
--Стандартное отклонение
func = SD()
dev=func(ds_minutes[sec]:Size(), {Period=mov_period, VType="Typical"}, ds_minutes[sec])
....................... 
 
Цитата
Let_it_go написал:
Не происходит ли тут лишних действий, всё ли экономно в плане получения и подсчёта индикаторов?

Происходит.
Например не понятно, зачем Вам две функции DataSource и DataSource_minutes. В чем смысл, ведь они делают одно и тоже?
Далее, для индикатора RSI() не обязательно передавать в функцию весь ds целиком, достаточно только предыдущее значение (i-1) и текущее.
А для индикатора SD() только текущее (ds_minutes[sec]:Size()).
 
Спасибо, Сергей.
Мысль понятно, но я не знаю как её реализовать?
Как то так?
Стандартное отклонение
Код
func = SD() dev=func(ds_minutes[sec]:Size(), {Period=mov_period, VType="Typical"}, ds_minutes[sec]:C())
Для RSI я брал пример из документации и сделал по аналогии с EMA:
Код
  for i=1,#tbl do
   ma_out=func(i, {Period=3, Metod = "EMA", VType="Any", round=2}, tbl)
  end 
вместо tbl нужно подставлять маленькую таблицу из двух значений: i и i-1?
Код
tbl={}
tbl.1=last=ds_minutes[sec]:C(i)   
tbl.2=last=ds_minutes[sec]:C(i-1) 
Но я строю по типической цене Typical, а не по Closa ...Подскажите пожалуйста, я с трудом всё это понимаю....      
 
Речь о том, что вместо:
Out = func(i, {Period=SP, Metod = M, VType="Close"}, ds)

можно писать так:
Out = func(i, {Period=SP, Metod = M, VType="Any"}, {[i] = C(i)})

Но надо помнить, что если в индикаторе, требуются значения предыдущих свечей, то надо их указать, например так:
Out = func(i, {Period=SP, Metod = M, VType="Any"}, {[i] = C(i), [i-1] = C(i-1)})

при этом VType надо указать именно "Any", а если надо "Typical", то указать его через функцию Value, например так:
Out = func(i, {Period=SP, Metod = M, VType="Any"}, {[i] = Value(i,"Typical",ds)})

такой способ, немного сэкономит ресурсы.
 
Здравствуйте, Сергей.
Добрался до того, чтобы посидеть над этими записями с форума.
Не получается запихивать в индикатор только последнее значение.
Начал с простого - Стандартное отклонение.
В таком виде работает:
Код
    --Стандартное отклонение
        func = SD()
        dev=func(num_candles_mov, {Period=mov_period, VType="Typical"}, ds_main[sec])
В таком виде не получается:
Код
   --Стандартное отклонение
      func = SD()
      dev=func(num_candles_mov, {Period=mov_period, VType="Any"}, ds_main[sec]:C(num_candles_mov))
Если вместо Any писать Close - тоже.
Ошибк: attempt to index local 'ds' (a number value) в строчке 201, вот она:

       Out = (C and C(I)) or (ds and ds:C(I))
 
Let_it_go,

Попробуйте найти отличия в строках
Цитата
Sergey Gorokhov написал:
Out = func(i, {Period=SP, Metod = M, VType="Any"}, {[i] = C(i)})
и
Цитата
Let_it_go написал:
     dev=func(num_candles_mov, {Period=mov_period, VType="Any"}, ds_main[sec]:C(num_candles_mov))

и Вы сами найдете ответ
 
переменная i - это перебор значений в цикле. В моём случае она не определена. Она нужна только для EMA,RSI и других подобных индикаторов. Для стандартного отклонения она не требуется.
Поэтому ваш пример не рабочий в моём случае.
 
Let_it_go,

Речь о том что надо написать так:
dev=func(num_candles_mov, {Period=mov_period, VType="Any"}, {[num_candles_mov] = ds_main[sec]:C(num_candles_mov)})
 
не помогает.
Ругается на строчку 88
SD.lua:88: attempt to perform arithmetic on a nil value
 
Let_it_go,
Потому что функции у Вас старые.
Используйте последнее обновление.

И еще одно замечание
Все функции требуют предварительного расчета начиная с индекса 1.
Т.е. даже если нужен только последний индекс, все равно требуется провести цикл расчета начиная с самого первого индекса.
 
Обновил. Теперь ничего не работает, все роботы стали глючить.
Например перестал рассчитываться RSI
Вот вид, который был рабочим до обновления функций:
Код
        func = RSI()
        local rsi_count={}
        num_candles=ds[sec]:Size()
        for i=1,num_candles do
            rsi_count[i]=func(i, {Period=rsi_period, VType="Typical"}, ds[sec])
        end

rsi_count[i] теперь нил.
 
Мувинги тоже не считаются. Результат нил
Код
    dofile(getWorkingFolder().."\\LuaIndicators\\MA.lua")    
    num_candles=ds[sec]:Size()

    func = MA()    
    for i=1,num_candles do
    ma_out=func(i, {Period=3, Metod = EMA, VType=ANY}, ds_main[sec])
    message (i.."="..ma_out,1)
    end 
 
поправил последний пример. МА не считается. Нил
Код
    dofile(getWorkingFolder().."\\LuaIndicators\\MA.lua")    
    num_candles=ds_main[sec]:Size()

    func = MA()    
    for i=1,num_candles do
    ma_out=func(i, {Period=3, Metod = EMA, VType=ANY}, ds_main[sec])
    message (i.."="..ma_out,1)
    end 
 
Передавать последний элемент тоже не вариант. Результат такой же.
Код
   dofile(getWorkingFolder().."\\LuaIndicators\\MA.lua")   
   num_candles=ds_main[sec]:Size() --параметр получен, с ним всё ок.
   func = MA()   
   for i=1,num_candles do
   ma_out=func(i, {Period=3, Metod = EMA, VType=ANY}, {[i]=ds_main[sec]:C(i)})
   message (i.."="..ma_out,1)
   end 
   
 
Цитата
Sergey Gorokhov написал:
Речь о том что надо написать так:
dev=func(num_candles_mov, {Period=mov_period, VType="Any"}, {[num_candles_mov] = ds_main[sec]:C(num_candles_mov)})
В Lua переменные типа таблицы являются ссылочными и поэтому передаются в функции по ссылке (без создания новой таблицы)
А вот Ваш код как раз  тратит лишнюю память на создание новой таблицы.
 
Let_it_go,Вот рабочий набросок вашей задумки
Код
dofile(getWorkingFolder().."\\LuaIndicators\\SD.lua")
dofile(getWorkingFolder().."\\LuaIndicators\\RSI.lua")

rsi_tf=INTERVAL_M5
mov_tf=INTERVAL_M1

class = 'TQBR'
fut_list = {'SBER','GAZP'}
rsi_period = 14
mov_period = 14

secs = {}

function OnInit(script)
   is_run = true
end

function OnStop()
is_run = false
return 2000
end

function main()
   for _,sec in pairs(fut_list) do
      DataSource(class,sec,rsi_tf)    
      DataSource(class,sec,mov_tf)    
   end

   local sec1, ds_rsi, ds_mov, num_rsi, num_mov, dev
   while is_run do
      sleep(1000)
      for _,sec in pairs(fut_list) do
         sec1   = secs[sec]
         ds_rsi = sec1[rsi_tf]
         ds_mov = sec1[mov_tf]
         
         num_rsi = ds_rsi:Size()
         for i = ds_rsi.lastI, num_rsi do 
         -- lastI надо пересчитывать т.к. последняя свеча будет изменяться неоднократно
            sec1.rsi_count[i] = sec1.RSI(i, {Period=rsi_period, VType="Typical"}, ds_rsi)
            message(sec ..' rsi_count - '.. i ..' : '.. tostring(sec1.rsi_count[i]))
         end
         ds_rsi.lastI = num_rsi

         num_mov = ds_mov:Size()
         for i = ds_mov.lastI, num_mov do 
         -- lastI надо пересчитывать т.к. последняя свеча будет изменяться неоднократно
            dev = sec1.SD(i, {Period=mov_period, VType="Typical"}, ds_mov)
            message(sec ..' dev - '.. i ..' : '.. tostring(sec1.rsi_count[i]))
         end
         ds_mov.lastI = num_mov
      end
      
   end
end

--[[ -- если автомат работает в цыкле можно применить SetEmptyCallback()
function mycallbackforallstocks(ds, I) -- ds = self, I = Index
   local class = ds.class
   local sec   = ds.sec
   local interval = ds.interval

end
--]]

function DataSource(class,sec,interval)
   local ds = CreateDataSource(class,sec,interval)
   ds.class = class
   ds.sec = sec
   ds.interval = interval
   ds.lastI = 1
    -- ds:SetUpdateCallback(function(...) mycallbackforallstocks(self.class,self.sec,...) end)
   ds:SetEmptyCallback()
   if not secs[sec] then secs[sec] = {} end
   secs[sec][interval] = ds
   secs[sec].RSI = RSI()
   secs[sec].rsi_count = {}
   secs[sec].SD = SD()
   return
end

Так как для последних свечек данные будут меняться несколько раз (причем для каждого набора отдельно), надо пожалуй проверять на действительное изменение данных или на изменение индексов свечек.

Можно из цыкла перенести обработку в функцию
mycallbackforallstocks но надо учитывать что она будет вызываться для каждого набора по мере его изменения (в том числе неоднократно для последней свечи
 
Владимир, спасибо за ответ. Но это старая ветка. Вопрос изложенный в начале давно решён.
Сейчас на повестке дня две других проблемы:
1. После обновления функций из INDICATORS.ZIP перестали работать скрипты.
2. Так и не получается передавать в индикатор только последний элемент.
В приведённом вами примере используется прежний (нерациональный) способ передачи, от которого я хочу отказаться.
dev = sec1.SD(i, {Period=mov_period, VType="Typical"}, ds_mov)
Вместо ds_mov надо передавать одно число типа такого варианта (но он не работает)
Out = func(i, {Period=SP, Metod = M, VType="Any"}, {[i] = C(i)})
 
Цитата
Let_it_go написал:
2. Так и не получается передавать в индикатор только последний элемент.
В приведённом вами примере используется прежний (нерациональный) способ передачи, от которого я хочу отказаться.
dev = sec1.SD(i, {Period=mov_period, VType="Typical"}, ds_mov)
Вы совсем не правы именно передача всего массива наиболее оптимальна.
При этом не делается копия исходного массива, а передается только одно число - ссылка на исходный массив.
А попытки создать урезанный массив с последними значениями приводят к лишним накладным расходам

Запустите скрипт
Код
function privet(t)
   message('function privet : t  = '.. tostring(tab1))
   t.privet = 'Привет из функции'
end

function main()
   message('*** start')
   tab1 = {o='1', h='2'}
   message('tab1 = '.. tostring(tab1))
   privet(tab1)
   message('tab1.privet = '.. tostring(tab1.privet))

   message('*** end')
   kvLogClose()
end

и посмотрите сообщения
 
Спасибо, буду разбираться. Я не кодер, поэтому страдаю от непонимания простых вещей.
Все же надеюсь, что в эту ветку заглянет Сергей Горохов и внесёт ясность.
 
Цитата
Let_it_go написал:
Владимир, спасибо за ответ. Но это старая ветка. Вопрос изложенный в начале давно решён.
Сейчас на повестке дня две других проблемы:
1. После обновления функций из INDICATORS.ZIP перестали работать скрипты.
Вы запускали мой скрипт из  сообщения №20.
У меня им корректно рассчитались RSI и SD для двух бумаг на последних версиях INDICATORS.ZIP

 
Let_it_go,

вот простой пример, на нем работает
Код
dofile(getWorkingFolder().."\\LuaIndicators\\MA.lua")
function main() 
  func = MA()
  t_id = AllocTable()
  AddColumn(t_id,1,"Price",true,QTABLE_INT_TYPE,10)
  AddColumn(t_id,2,"MA",true,QTABLE_INT_TYPE,10)
  CreateWindow(t_id)
  SetWindowCaption(t_id,"MA")
  ds = CreateDataSource("TQBR", "LKOH", INTERVAL_M5) 
  sleep(100)
  for i=1,ds:Size() do
   ma_out=func(i, {Period=3, Metod = EMA, VType=ANY},{[i]=ds:C(i)})
   tmp=InsertRow(t_id,-1)
   SetCell(t_id,tmp,1,tostring(ds:C(i)),ds:C(i))
   SetCell(t_id,tmp,2,tostring(ma_out),ma_out)
  end 
end
Страницы: 1
Читают тему
Наверх