Вычисление индикатора внутри кода

Страницы: 1
RSS
Вычисление индикатора внутри кода
 
Добрый день.
Хочу вычислять скользящую среднюю внутри кода.
Что при этом нужно учитывать?
Период 14, часовик, по ценам close
Казалось бы всё просто, но есть особенности:
1. Старые свечки можно не обрабатывать, а обрабатывать только текущую.
2. Но обрабатывать старые всё же придётся, ведь рисуются новые свечки, поэтому каждый раз при формировании новой свечи придётся разок пересчитать старые.
Помогите пожалуйста выразить это в красивом коде.
Спасибо.
 
Сейчас формула такая.
На примере 5-периодной Moving Average:
Код
..............................
ds=CreateDataSource(p_classcode, p_seccode, INTERVAL_M1)    
ds:SetUpdateCallback(cb)

    
    while is_run do
    length=ds:Size()
    sum=0
        for i=0,4,1 do
            sum=sum+ds:C(length-i)    
        end
    moving5=sum/5
    sleep(100)
    end
end

 
И попутно вопрос: почему мувинг рассчитанный внутри этого кода капельку, но отличается от мувинга на графике?
Вот рисунок
 
Цитата
Космонавт написал:
Сейчас формула такая.
На примере 5-периодной Moving Average:
Код
   ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  .. 
ds =  CreateDataSource (p_classcode, p_seccode, INTERVAL_M1)    
ds: SetUpdateCallback (cb)

    
     while  is_run  do 
    length = ds: Size ()
    sum =  0 
         for  i =  0 , 4 , 1   do 
            sum = sum + ds:C(length - i)    
         end 
    moving5 = sum/ 5 
     sleep ( 100 )
     end 
 end 

  
Есть два момента, которые необходимо учитывать:
----------------------------------------------
1) Расчет надо делать для двух состояний: а) свеча закрыта б) свеча открыта.
Либо лишь состояние а), которое надо обнаружить. состояние б) существует лишь на последней свече и лишь в режиме торгов.
Поэтому у Вас расчет последней свечи содержит ошибку.
--------------------------------------------------------------------
2) Не надо использовать циклы.
Циклы -это зло в системах реального времени.
Можно вычислить мувинг затратив лишь 1 деление +1 вычитание+1 сложение для любого значения параметра N.
У Вас N всего 4, а некоторые (обращались ко мне с такой проблемой) используют 1000000 (сто тысяч) Вот и посчитайте мколько времени у Вас будет считаться мувинг встроенным индикатором или вашим ( у обращавшихся квик виснул )
-----------------------------
 
 
Николай, спасибо за ответ.
Приведите пожалуйста формулу мувинга, которую Вы рекомендуете, там где  1 деление +1 вычитание+1 сложение.
 
И ещё - как решить проблему - не обращаться к тем свечкам, которые не изменились.
 
Здравствуйте,
У нас есть такой пример индикатора без циклов, он не адаптирован под CreateDataSource, но может дать идею решения:
Скрытый текст
 
Цитата
Sergey Gorokhov написал:
SUM_TMP=(SUM_TMP[i-1] or 0)+C(i)
Сергей, спасибо за интересный пример.
Обратил внимание на вот эту конструкцию. А Вы не могли бы пояснить, как он работает? как она обрабатывает оператор OR в данном случае? Если я правильно понимаю, она суммирует либо то, что перед ним, либо то что после, но по какому критерию?  
 
Цитата
Sergey Denegin написал:
Цитата
Sergey Gorokhov   написал:
SUM_TMP =(SUM_TMP[i-1] or 0)+C(i)
Сергей, спасибо за интересный пример.
Обратил внимание на вот эту конструкцию. А Вы не могли бы пояснить, как он работает? как она обрабатывает оператор OR в данном случае? Если я правильно понимаю, она суммирует либо то, что перед ним, либо то что после, но по какому критерию?

Если SUM_TMP[i-1] не существует (nil) то вместо него берется 0
 
Сергей, спасибо за пример, но не понятно как функции OnCalculate(i) удаётся обратиться ко всем требуемым 9 свечкам. Что передаётся в переменную i ?
 
Цитата
Космонавт написал:
Сергей, спасибо за пример, но не понятно как функции OnCalculate(i) удаётся обратиться ко всем требуемым 9 свечкам. Что передаётся в переменную i ?

По данному вопросу, рекомендуем к прочтению документ "Создание индикаторов технического анализа с помощью скриптов Lua.pdf" расположенный по ссылке:
https://arqatech.com/upload/iblock/022/quik_lua.zip
 
Добрый день.

Я использую другой подход: http://www.bot4sale.ru/blog-menu/qlua/spisok-statej/487-coffee.html

Он намного красивее, но имеет одну проблему с размером стека при рекурсии. Способ решения этой проблемы придумывайте на свой вкус.
www.bot4sale.ru

Пасхалочка для Алексея Иванникова: https://forum.quik.ru/messages/forum10/message63088/topic7052/#message63088
 
Большое спасибо за ответы!
Разрешите задать ещё вопрос. У меня робот перебирает много акций, и рассчитывать индикаторы надо для каждого из них. Вот как это выглядит сейчас. У меня ведь грубая ошибка - я каждый раз внутри цикла по новой подписываюсь на свечки и ставлю колбек? Подскажите пожалуйсте где грамотно размещать заказ свечек и обновлений? Функция MA - это готовый пример с сайта ARQA
Код
ticker_list = "AFLT,ALRS,BANE,CHMF,FEES,GAZP,GMKN,HYDR,IRAO,LKOH,MAGN,MFON,MGNT,MOEX,MTSS,NLMK,NVTK,RASP,ROSN,RSTI,RTKM,SBER,SNGS,SNGSP,TATN,URKA,VTBR"

 
is_run = true
function OnStop(s)
  is_run = false
  return 1000
end

dofile(getWorkingFolder().."\\LuaIndicators\\MA.lua") --взято с сайта ARQA
function main()                 
while is_run do        
    for sec in string.gmatch(ticker_list,"%a+") do
                 ds = CreateDataSource("TQBR", sec, INTERVAL_M1) 
                 ds:SetUpdateCallback()
                 sleep(100)
                        func = MA()
                        ma_out=func(ds:Size(), {Period=60, Metod = "SMA", VType="Typical", round=4}, ds)
     end
end             
end
 
Цитата
Космонавт написал:
У меня ведь грубая ошибка - я каждый раз внутри цикла по новой подписываюсь на свечки и ставлю колбек?

Не понятно, что мешает Вам этого не делать?
 
Цитата
Sergey Gorokhov написал:
Цитата
Космонавт   написал:
У меня ведь грубая ошибка - я каждый раз внутри цикла по новой подписываюсь на свечки и ставлю колбек?
Не понятно, что мешает Вам этого не делать?
Если я вывожу колбэки в начало кода - до функции main, они не работают.
 
Космонавт,

Какие колбеки? и зачем Вы их выносите?
Вы же сами сказали что не хотите подписываться на свечки в цикле. Так не подписывайтесь. Про колбеки никто ничего не говорил.
 
Ок, переформулирую вопрос.
1. Этот код работает, но он работает медленнее чем брать данные с графика через идентификатор. Почему? Где самый тяжёлый участок кода?
2. Мне надо запустить ds = CreateDataSource("TQBR", sec, INTERVAL_M1) единожды, верно?
3. Мне надо запустить ds:SetUpdateCallback() тоже единожды, верно?
4. Мне надо перебрать много бумаг. Если я сделаю так,
Код
for sec in string.gmatch(ticker_list,"%a+") do                  
ds = CreateDataSource("TQBR", sec, INTERVAL_M1)                   
ds:SetUpdateCallback()                  
end

а потом основной цикл программы внутри while is run

for sec in string.gmatch(ticker_list,"%a+") do      
запускаются функции, проверяются условия срабатывания, идёт торговля
end

это правильно? Ведь ds будет всё время принимать значение новой бумаги и будет каша.
Спасибо за ответы
 
Цитата
Космонавт написал:
это правильно?
Да правильно.

Цитата
Космонавт написал:
Ведь ds будет всё время принимать значение новой бумаги и будет каша.

Ничего не мешает сделать несколько ds, для каждой бумаги свой. Например если вместо переменной использовать таблицу
ds[sec] = CreateDataSource("TQBR", sec, INTERVAL_M1)
 
Цитата
Sergey Gorokhov написал:
Ничего не мешает сделать несколько ds, для каждой бумаги свой. Например если вместо переменной использовать таблицу
ds[sec] = CreateDataSource("TQBR", sec, INTERVAL_M1)
я пробовал, но тогда данные не заходят в функцию с вашего сайта:
Код
func = MA()                         
ma_out=func(ds:Size(), {Period=60, Metod = "SMA", VType="Typical", round=4}, ds)
 
Цитата
Космонавт написал:
я пробовал, но тогда данные не заходят в функцию с вашего сайта:

логично, ведь вы передаете в функцию таблицу из разных потоков.
а надо передавать какой-то один поток.
 
нужно так сделать?
Код
ma_out=func(ds[sec]:Size(), {Period=60, Metod = "SMA", VType="Typical", round=4}, ds[sec])
ds[sec]:Size() - так писать правильно?
 
Космонавт,
да правильно
 
Цитата
Космонавт написал:
Николай, спасибо за ответ.
Приведите пожалуйста формулу мувинга, которую Вы рекомендуете, там где  1 деление +1 вычитание+1 сложение.
вот код мувинга без циклов:
Код
Settings = {
Name = "*nkSMA",
Period = 9,
line = {{Name = "nkSMA",Type = 1, Color = RGB(255, 0, 0)}}
}

function Init()
   return #Settings.line
end

local P,i1,NP;
function OnCalculate(i)
   local Out=C(i);
   if i==1 then
      S={}; P=Settings.Period; NP=1/P;
   else
      if i<=P then  Out=(Out+i1*S[i1])/i;
      else  Out=S[i1]+ NP*(Out-C(i-P));  end
   end
   i1=i;  S[i]=Out;
   return Out
end

Страницы: 1
Читают тему
Наверх