Асинхронная подписка на свечи

Страницы: 1
RSS
Асинхронная подписка на свечи
 
Это можно сделать так:
Код
--Пример ассинхронного запроса свечей--
--результат в массиве ds для каждого инструмента

Tclas={}
Tclas.QJSIM={SBER={int={1,2,5,10,20},ds={}}, GAZP={int={2,5},ds={}}, LKOH={int={5},ds={}}}
Tclas.SPBFUT={SiZ5={int={5},ds={}}, RIZ5={int={5,10},ds={}},SRZ5={int={30},ds={}}}

local tim=os.clock()

function OnParam(c,s)
   local tc=Tclas[c]
   if tc then  local ts=tc[s];  
     if ts then local ts=tc[s]; local int=ts.int; local ds=ts.ds;local  N=#int; local M=#ds;
      if N~=M then local j=0; 
       while N>j do j=j+1; 
          if ds[j]==nil then local x=CreateDataSource(c,s, int[j]);  
        if x:Size()>0  then    local ti=math.tointeger(1000*(os.clock()-tim)//1);
           ds[j]=x; nkLog:write("time(ms)="..tostring(ti)..","..c..","..s..",j="..j..",int="..int[j]..",size="..ds[j]:Size().."\n"); nkLog:flush();
         end
      end
       end
    M=#ds; if N==M then nkLog:write(s..",подписка завершена\n"); nkLog:flush(); end
   end
      end
   end
end

RUN = truefunction main()
    while RUN do 
 --  Выполнение заданий скрипта --
      sleep (10)
   end 
end

function OnStop(signal)    RUN = false   return 5000 end

function OnInit(p)
  local p=string.reverse(p); local n,m=string.find(p,"\\"); 
  local pS=string.reverse(string.sub(p,n)); name=string.reverse(string.sub(p,5,n-1)) ;
  package.cpath =package.cpath..";"..pS.."?.dll;"
  package.path =package.path..";"..pS.."?.lua;"..pS.."?.luac;"
   fnlog=pS..name.."_nk.log";   nkLog=io.open(fnlog,"w")
end
В скрипте есть вывод в лог файл, который создается в каталоге скрипта.
Результат работы скрипта на тестовом сервере QUIK
Код
time(ms)=250,SPBFUT,SiZ5,j=1,int=5,size=18508
SiZ5,подписка завершена
time(ms)=704,SPBFUT,RIZ5,j=1,int=5,size=11284
time(ms)=706,SPBFUT,RIZ5,j=2,int=10,size=13779
RIZ5,подписка завершена
time(ms)=871,QJSIM,GAZP,j=1,int=2,size=350
time(ms)=871,QJSIM,GAZP,j=2,int=5,size=140
GAZP,подписка завершена
time(ms)=1547,SPBFUT,SRZ5,j=1,int=30,size=2251
SRZ5,подписка завершена
time(ms)=1880,QJSIM,LKOH,j=1,int=5,size=140
LKOH,подписка завершена
time(ms)=1882,QJSIM,SBER,j=1,int=1,size=696
time(ms)=1882,QJSIM,SBER,j=2,int=2,size=351
time(ms)=1882,QJSIM,SBER,j=3,int=5,size=140
time(ms)=1882,QJSIM,SBER,j=4,int=10,size=71
time(ms)=1884,QJSIM,SBER,j=5,int=20,size=36
SBER,подписка завершена
 
Поступило два вопроса.
1) Если инструмент очень редко изменяется в ТТП,  но кому-то надо срочно что-то считать ( не представляю что надо считать по этому инструменту) . Решаем эту проблему.
--------------------------
2)  Этот код, хоть и на 4 мкс, но будет грузить основной поток после того, как подписка закончится.  Решает и эту проблему,
-----------------------------------
Вот вариант скрипта, в котором этих проблем нет:
Код
--Пример асинхронного запроса свечей--
--результат в массиве ds для каждого инструмента
Tclas={}
Tclas.QJSIM={SBER={int={1,2,5,10,20},ds={}}, GAZP={int={2,5},ds={}}, LKOH={int={5},ds={}}}
Tclas.SPBFUT={SiZ5={int={5},ds={}}, RIZ5={int={5,10},ds={}},SRZ5={int={30},ds={}}}
local tim=os.clock()
 ------------------------
RUN = true
function main()
local fDS=true;
 while RUN do 
 --  Выполнение заданий скрипта --
    sleep (10)
   end 
end
---------------------------------]
function OnParam(c,s)
  if MaxDS then 
     for c,tc in pairs(Tclas) do 
   for s,ts in pairs(tc) do  
     local ts=tc[s]; local int=ts.int; local ds=ts.ds;local  N=#int; local M=#ds;
     if N~=M then       local j=0; 
        while N>j do j=j+1; 
      if ds[j]==nil then    local x=CreateDataSource(c,s, int[j]);  
        if x:Size()>0  then    local ti=math.tointeger(1000*(os.clock()-tim)//1);
           ds[j]=x; nkLog:write("time(ms)="..tostring(ti)..","..c..","..s..",j="..j..",int="..int[j]..",size="..ds[j]:Size().."\n");nkLog:flush();
                   end
      end
       end
       M=#ds; if N==M then MaxDS=MaxDS-1; nkLog:write(s..",подписка завершена\n"); nkLog:flush(); end
   end
    end
   end
  end
 if MaxDS==0 then  nkLog:write("блокируем OnParam\n");    nkLog:flush(); MaxDS=nil end
end

function OnStop(signal)    RUN = false   return 5000 end

function OnInit(p) -- инициализация функции main
local p=string.reverse(p); local n,m=string.find(p,"\\"); 
local pS=string.reverse(string.sub(p,n)); name=string.reverse(string.sub(p,5,n-1)) ;
package.cpath =package.cpath..";"..pS.."?.dll;"
package.path =package.path..";"..pS.."?.lua;"..pS.."?.luac;"
fnlog=pS..name.."_nk.log";   nkLog=io.open(fnlog,"w")
local x=0; for c,tc in pairs(Tclas) do  for s,ts in pairs(tc) do  x=x+1 end  end MaxDS=x;
end
---------------------------
а это результат его работы:
Код
time(ms)=53,QJSIM,SBER,j=1,int=1,size=1041
time(ms)=54,QJSIM,SBER,j=2,int=2,size=523
time(ms)=54,QJSIM,SBER,j=3,int=5,size=209
time(ms)=54,QJSIM,SBER,j=4,int=10,size=105
time(ms)=54,QJSIM,SBER,j=5,int=20,size=53
SBER,подписка завершена
time(ms)=55,QJSIM,GAZP,j=1,int=2,size=523
time(ms)=55,QJSIM,GAZP,j=2,int=5,size=209
GAZP,подписка завершена
time(ms)=207,QJSIM,LKOH,j=1,int=5,size=209
LKOH,подписка завершена
time(ms)=207,SPBFUT,SiZ5,j=1,int=5,size=18572
SiZ5,подписка завершена
time(ms)=207,SPBFUT,SRZ5,j=1,int=30,size=2262
SRZ5,подписка завершена
time(ms)=207,SPBFUT,RIZ5,j=1,int=5,size=11347
time(ms)=207,SPBFUT,RIZ5,j=2,int=10,size=13811
RIZ5,подписка завершена
блокируем OnParam
 
поправил немного:
Код
function OnParam(c,s)
if MaxDS then 
for c,tc in pairs(Tclas) do 
   for s,ts in pairs(tc) do  
   local ts=tc[s]; local int=ts.int; local ds=ts.ds;local  N=#int; local M=#ds;
   if N~=M then local j=0; 
   while N>j do j=j+1; 
   if ds[j]==nil then  local x=CreateDataSource(c,s, int[j]);  
   if x:Size()>0  then  local ti=math.tointeger(1000*(os.clock()-tim)//1);
   ds[j]=x; nkLog:write("time(ms)="..tostring(ti)..","..c..","..s..",j="..j..",int="..int[j]..",size="..ds[j]:Size().."\n"); nkLog:flush();
       end
      end
   end
   M=#ds; if N==M then MaxDS=MaxDS-1; nkLog:write(s..",подписка завершена\n"); nkLog:flush(); end
      end
   end
   end
   if MaxDS==0 then  nkLog:write("блокируем OnParam\n"); nkLog:flush(); MaxDS=nil end
  end
end
 
В качестве финального варианта выкладываю скрипт подписки без колбеков.
Код
--Пример асинхронного запроса свечей--результат в массиве ds для каждого инструмента
----------------------
name="nk_bot"
fnlog="D:/"..name..".log"; nkLog=io.open(fnlog,"w") 
Tclas={}
Tclas.QJSIM={SBER={int={1,2,5,10,20},ds={}}, GAZP={int={2,5},ds={}}, LKOH={int={5},ds={}}}
Tclas.SPBFUT={SiZ5={int={5},ds={}}, RIZ5={int={5,10},ds={}},SRZ5={int={30},ds={}}}
local tim=os.clock()
 ------------------------
 function main()
  run=true;
  local x=0; for c,tc in pairs(Tclas) do  for s,ts in pairs(tc) do  x=x+1 end  end    MaxDS=x;
  while run do 
     if MaxDS then 
   for c,tc in pairs(Tclas) do 
      for s,ts in pairs(tc) do  
         local ts=tc[s]; local int=ts.int; local ds=ts.ds;local  N=#int; local M=#ds;
       if N~=M then local j=0; 
           while N>j do j=j+1; 
            if ds[j]==nil then local x=CreateDataSource(c,s, int[j]);  
            if x and x:Size()>0  then    local ti=math.tointeger(1000*(os.clock()-tim)//1);
            ds[j]=x; nkLog:write("time(ms)="..tostring(ti)..","..c..","..s..",j="..j..",int="..int[j]..",size="..ds[j]:Size().."\n"); nkLog:flush();
            end
         end
       end
       M=#ds; if N==M then MaxDS=MaxDS-1; nkLog:write(s..",подписка завершена\n");        nkLog:flush(); end
         end
      end
   end
   if MaxDS==0 then  nkLog:write("блокируем блок подписки\n");    nkLog:flush(); MaxDS=nil end
   end
 --  Выполнение заданий скрипта --
      sleep (10)
   end 
end
function OnStop(signal)    run = false   return 1000 end
после завершения подписки  в main будет исполнятся из кода подписки лишь один оператор if.
------------------------------  
Недостаток этого варианта по сравнению с первым тот, что в нем тратится время main на неисполненные подписки, если данный инструмент не торгуется.
Во втором варианте тратится время основного потока QUIK на подобные подписки.
--------------------------
Оптимальным вариантом будет решение, которое объединяет первый третий вариант.
--------------------------------
Именно такое решение я и использую в настоящее время.
Страницы: 1
Читают тему
Наверх