nikolz (Автор тем)

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

Страницы: 1 2 3 След.
алгоритм бота - стопа
 
Предлагаю обсудить один из моих вариантов бота, который управляет стопом.
-------------------------
Конструктивная критика приветствуется.
===================
Открываем график с инструментом , помещаем на него скрипт-индикатор бота и совершаем сделки.
----------------------
Бот имеет два режима.
----------------------------------
В первом режиме бот автоматически установит стоп, если есть позиция  по инструменту.
--------------------------
Во втором режиме бот начнет управлять стопом, если руками установить стоп  в любую позицию.
Когда бот обнаружит установленный стоп, он будет его переставлять в соответствии с заданным алгоритмом.
----------------------
Если позиция закроется, то стоп будет снят.
При появлении новой позиции бот будет управлять стопом.
----------------------------------
Чтобы бот перестал управлять, надо снять стоп руками.
---------------------------------
При старте QUIK бот начинает работать в установленном режиме.

 
Торговый советник - это просто.
 
Тема для начинающих писателей роботов.
Продолжение темы:
https://forum.quik.ru/messages/forum17/message80773/topic9417/#message80773
-------------------------
Чтобы сразу не сливать депозит,  лучше написать робот-советник, который на истории покажет , что он сможет.
---------------------------
Напишем такой советник.
Для этого в приведенный по ссылке выше скрипт добавим расчет прибыли/убытков при совершении сделок по приведенному ранее(см ссылку) алгоритму
------------------------
Примем что брокер и биржа забирают com=0.006 (0.6%)
Расчет будет проводить в %, количество лотов примем равным 1. Сделки совершаются в long и short.
В результате получился вот такой скрипт:
Код
function OnCalculate(i)
  local buy,sel;
  if i==1 then OnChangeSettings() 
    i1=0; t={}; Prof=0; Los=0; Q=Settings.Q; com=Settings.com; ProfAll=0;  BS=0;
  elseif i1~=i  then 
     ind(i1,Settings.tag,t); 
     if #t>0 then
          local Oi,Hi,Li=O(i1),H(i1),L(i1)  local prib=0;  local z=T(i1);   x=t[#t]; 
          params.DATE=100*(100*z.year+z.month)+z.day; 
          params.TIME=100*(100*z.hour+z.min)+z.sec;
          if Li>x and 0>=BS then buy=Li-0.05;  if BS==0 then prib=-com; else prib=(1-com)*(price/Oi-1); end  BS=1; price=Oi; params.YVALUE=buy-0.1; end
          if x>Hi and BS>=0  then  sel=Hi+0.05 if BS==0 then prib=-com; else prib=(1-com)*(Oi/price-1); end price=Oi;  BS=-1; params.YVALUE=sel+0.1; end
          if buy or sel then
            ProfAll=ProfAll+prib;    params.TEXT=(0.1*(1000*ProfAll//1)).."%" 
            if ProfAll>=0 then params.B=255 params.R=0 else params.B=0 params.R=255 end
            Label=AddLabel(Settings.tag,params);
          end
      end
  end
  i1=i;  
 return buy,sel;
 end

function Init() 
local t={} Settings.line =t;
   t[#t+1]={Name = "Bu",Color = RGB(0,255,0),Type = 10,Width = 4};
    t[#t+1]={Name = "Se",Color = RGB(255,0,0),Type = 11,Width = 4};
   return #t; end
    
function OnDestroy ()  DelAllLabels(Settings.tag) end
function OnChangeSettings() 
   DelAllLabels(Settings.tag); 
end


а это результат его тестирования на демо-сервере:
Данные с индикатора. Просто и быстро.
 
Тема для начинающих писателей роботов.
----------------------------
Ранее на форуме я рассказывал как построить робота-эксперта  на основе двух любых индикаторов отображаемых на графике.
https://forum.quik.ru/forum17/topic7630/
---------------------------
В этой теме поясню как читать данные с индикатора быстро и просто.
------------------------
Напишем пример скрипта индикатора, который считывает значения индикатора moving в массив t и выводит на график значения индикатора смещенные на 0.1 в виде зеленых треугольников .
---------------------------
При этом  сделаем так, чтобы индикатор не тратил время на считывание тиков, а читал значение индикатора один раз в момент появления новой свечи цены.

В моих роботах именно в этот момент и принимается решение о выставлении заявки.

Т е решение принимается в момент открытия новой свечи .
------------------------------  
Если робот будет торговать на интервала 30 минут, то чтение индикатора будет происходить всего 1 раз в 30 минут именно на открытии новой свечи.
Код
Settings={ tag="moving", Name = '*nk_test'}

function OnCalculate(i)
 if i==1 then  i1=0; t={};
 elseif i1~=i  then local M=getNumCandles (Settings.tag);  
    if M>=i then x=getCandlesByIndex(Settings.tag,0,i1,1); if x then t[#t+1]=x[0].close end  i1=i;  end
 end
 i1=i;  if #t>0 and t[#t]~=0 then  return t[#t]+0.1; end
end

function Init() 
local t={} Settings.line =t;
t[#t+1]={Name = "Bu",Color = RGB(0,255,0),Type = 10,Width = 3};
return #t;
end



это результат:
Торговые роботы без программирования
 
Тема создана с целью  обсудить мой подход к созданию торговых роботов без написания сложных скриптов на Lua.
--------------------------
Приведу примеры, потом объясню что и как.
----------------------
Пример 1: Скрипт скользящего стопа на основе индикатора fractals записывается таким образом:



Пример 2: Скрипт торгового робота на основе индикаторов moving и RSI



Робот строится как скрипт индикатора и состоит из обязательной таблицы Settings, встроенных в QUIK индикаторов  и библиотеки nklibi, начальным объемом  11 КБ.
-------------------
Все необходимые параметры робота определяются в Settings.
Изначально указывается, если надо, создание лог файла, набор индикаторов, на основе которых будет работать робот.  Для каждого индикатора указывается линия, параметр свечи и смещение относительно текущего значения.
-------------------  
Для применения робота необходимо открыть график инструмента, поместить на него указанные в Settings индикаторы и записать им в качестве идентификаторов указанные имена.
-------------------
Алгоритмы новых роботов можно добавить либо в библиотеку, либо в конец скрипта.
===================
Библиотека nklibi реализует конечный автомат  управления заявками и стоп-заявками, а также определяет по графику инструмента все необходимые для торговли параметры.
====================
Если график с индикатором робота связать якорем с таблицей текущих параметров(ТТП) торгов, то, перебирая инструменты в ТТП,  можно переключать робота  на различные торгуемые инструменты.
----------------------------------
Конструктивные предложения по расширению возможностей данного подхода приветствуются.
----------------------------
В настоящее время библиотека nklibi находится в стадии тестирования.


 
Индикатор с метками
 
По просьбе трудящихся, написал Пример ПРАВИЛЬНОГО индикатора, который  через секунду удаляет ранее выставленную метку и выводит новую.
--------------------------------
Пользуйтесь на здоровье.
----------------------------

Код
Settings={ Name = "*nk_test", tag ="Metka"  }

params={R = 255, G = 255, B = 255, TRANSPARENCY = 0,FONT_HEIGHT = 10,TRANSPARENT_BACKGROUND = 1, FONT_FACE_NAME = 'Verdana' }

function OnCalculate(i)
  if i==1 then
  OnChangeSettings()  
  elseif i== Size() then    -- последняя свеча
     if os.time() > LastSecond  then          -- раз в секунду (или больше)  
          LastSecond = os.time();    -- потиковое обновление (с задержкой)  
        if Label then DelLabel(Settings.tag,Label) end
           params.TEXT =tostring(C(i))
           params.HINT = tostring(i)
        local h=0   local  m=i;  
        while 14>i-m  do if H(m) > h then h=H(m) end;m=m-1;   end
        local Ti=T(i-3)
        params.DATE=100*(100*Ti.year+Ti.month)+Ti.day;
        params.TIME=100*(100*Ti.hour+Ti.min)+Ti.sec;  
        params.YVALUE =h;
        Label= AddLabel(Settings.tag, params)
       end -- every second
   end
end

function OnChangeSettings()
sec = getDataSourceInfo().sec_code; DelAllLabels(Settings.tag);
LastSecond=0  end
function OnDestroy() OnChangeSettings() end
function Init()  return 1 end




Ускорение загрузки QUIK
 
Добрый день,
Предлагаю следующие решения :
------------------------------
1) Сделать возможным указывать начальную дату загрузки  сохраненной на ПК  истории при старте QUIK.
--------------------------
2) Сделать возможным сохранять слепок памяти для последующей загрузки.
Время загрузки тарминала QUIK
 
Я утверждаю, что время загрузки(старта)  существенно зависит от наличия скриптов индикаторов на луа и архива истории.
------------------
Провел тест времени загрузки (начала работы )терминала QUIK (брокер Сбербанк)
---------------------

Тест 1:
Сделал копию рабочей папки QUIK
Удалил папку архивы и индикаторы и подключился к брокеру:
-------------
Время старта вычислял по интервалу от момента двухфакторной до начала отображения стакана и графиков





Тест2:  загрузил рабочий вариант QUIK



В результате Тест 1 время загрузки без скриптов на луа составляет  12 секунд, а время загрузки со скриптами индикаторов 69 секунд
----------------------------------  
Выводы делайте сами.
Такого не может быть, но опять.
 
Вопрос к разработчикам.
--------------------
можете объяснить причину такого явления.
------------------
Терминал работает нормально. На рынке все спокойно.
вдруг приходит сообщение:  "Сервер принудительно разорвал соединение"
-----------------------
после этого терминал пытается автоматически восстановить соединение.
----------------------
приходит сообщение: "Вы уже работаете в системе"

потом сообщение "соединение восстановить не удалось"
---------------------
И так пока не надоест.
=====================
Приходится закрывать принудительно терминал и запускать снова.
====================
Что за хрень происходит?
Структура моего робота
 

В данной теме рассказываю, как построен мой торговый робот.

Полагаю, что тема будет интересна не только начинающим писателям роботов,

так как излагаю свои идеи, которые обладают определенной новизной .

----------------------------

Структура робота организована в виде сети роботов типа “звезда”.

Каждый робот – это отдельный поток или процесс ОС Windows.

------------------------------

В центре звезды находится главный робот nkbot, который обрабатывает события колбеков и таймера  и раздает задания другим роботам.

События организованы в виде очереди. Если событий нет в течении заданного интервала, то робот выполняет задание по таймеру.

---------------------------

Все остальные роботы работают с заданной для каждого робота группой инструментов

и выполняют свои задачи по команде nkbot, либо по истечению заданного интервала времени.

---------------------------

Каждый робот работает в своем потоке OS Windows, либо в процессе терминала  QUIK и имеет доступ к библиотеке QLua, либо в изолированном потоке(процессе) OS  

Роботы в терминале запускаются как скрипты терминала QUIK.

----------------------------

Связь робота nkbot с каждым роботом сети выполняется через очередь команд в общей памяти.

Список работающих роботов создается в файле инициализации nkbot_ini.lua.

Задачи для роботов создаются в отдельных файлах в виде функций и загружаются в робота во время запуска скрипта по заданному списку задач для каждого робота.

--------------------------

Несколько примеров реализации отдельных элементов данной структуры.

Все роботы сети, кроме nkbot, имеют одинаковую структуру и реализуются одним скриптом.

Имя робота состоит из “nkbot_” и далее идентификатор робота.

Например, nkbot_B.lua, nkbot_C.lua  два робота B и C

Файл nk_bot_B.lua

Код
Ts={SBER={int={1,2,5,10,20},q=true},
GAZP={int={2,5},q=true}, LKOH={int={5},q=true}} 
--инструменты, которыми торгует робот , интервалы свечей и флаг
получения стакана

list_task="task1,task2"  -- задачи, которые
быдет исполнять робот  

nkLog=true;  -- -включить вывод в лог файл

----------------не трогать---------------

minfo =
debug.getinfo(1, "S").source:sub(2); path =
minfo:match("(.*[/\\])") or "."

dofile(path.."stream.lua")

Файл nk_bot_С.lua
Код
Ts={SiZ5={int={5}}, RIZ5={int={5,10},},SRZ5={int={30}}}
--инструменты и интервалы свечей

list_task="task3,task4"  -- список задач

nkLog=true;

----------------не трогать---------------

minfo =
debug.getinfo(1, "S").source:sub(2); path =
minfo:match("(.*[/\\])") or "."

dofile(path.."stream.lua")

файл инициализации nkbot_init.lua
Код
list_stream="B,C"  --список потоков
nkLog=true; --включаем лог файл
Асинхронная подписка на свечи
 
Это можно сделать так:
Код
--Пример ассинхронного запроса свечей--
--результат в массиве 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,подписка завершена
Обсуждаем интерфейс для робота
 
Сейчас пишу робота  на основе ИИ Lua и QUIK.
Кратко изложу интерфейс для работы с ним.
---------------------  
Интерфейс имеет такой вид:


содержание строк и столбцов задается двумя строками в файле инициализации робота:
Код
list_sec="ROSN,GAZP,SBER,PLZL,GMKN,CHMF,HYDR,LKOH,MOEX,SNGS"   --список торгуемых инструментов
list_user_table="sec:-108,short:-4:0,int:4:1,quote:-4:0,stop:-108:1,spred:4:1,offset:4:1,dp:4:1,Qn:4:0,Q:4:0,last:8:0.,bid:8:0.,offer:8:0.,price:8:0.,prof:8:0." 
 -- описание столбцов
В таблице отображаются либо отдельные значения, либо значения из списка.
Например, я задаю типы стоп заявок в виде :
Код
T_stop={"stop","take","st_ta","oth_sec","linked","ord_st","ord_ta","ord_st_ta"}; T_stop[0]=#T_stop; --типы стоп-заявок
Пользователь может изменять данные лишь двумя способами  -- выбирать из существующего списка или изменять значение на плюс минус 1 нажатием правой или левой кнопки мышки..
Двойным щелчком мышки можно сделать значение активным или пассивным.
-----------------
Например, можно сделать неактивными все инструменты ,кроме одного, и робот будет торговать лишь этим инструментом.
Можно сделать неактивным стоп или short и робот не будет ставить стоп или покупать в шорт.
-------------------------  
Еще в файле инициализации задается список имеющихся алгоритмов торговли , я называю их задачами.  
Код
list_task="task1,task2,task3,task4"  -- список существующих задач
а также список задач для всех инструментов по умолчанию
Код
user_task={"task1","task2" } --задачи для каждого инструмента по умолчанию

для каждого инструмента можно указать индивидуальные параметры или задачи, которые в списке инструментов указываются через ":"
=========================
Это весь интерфейс.

Конструктивные предложения приветствуются.
Проблема с нажатием правой кнопки
 
Когда в таблице в скрипте нажимаю правую кнопку мышки, то вылезает окно квика


можно как-то это отключить?
проблема с двойным нажатием кнопки
 
При двойном нажатии кнопки мыши в таблице созданной в скрипте всегда сначала приходит сигнал об одинарном нажатии кнопки.
Код
msg=1,j=2
msg=1,левая кнопка
msg=5,j=-1
msg=5,изм текущей (выделенной) строки
msg=11,j=2
msg=11,отпущена левая кнопка
msg=3,j=2
msg=3,двойное левой кнопки
Как  устранить сигнал об одинарном нажатии при двойном нажатии?
Метки на графике в скрипте
 
По просьбе трудящихся.


Код
label_params={["TEXT"]="",["IMAGE_PATH"]="",["ALIGNMENT"]="Left",["YVALUE"]=0,["DATE"]=0,["TIME"]=0,["R"]=255,["G"]=255,["B"]=255,
["TRANSPARENCY"]=0,["TRANSPARENT_BACKGROUND"]=0,["FONT_FACE_NAME"]='Times New Roman',["FONT_HEIGHT"]=10,["HINT"]=""}

function labeldraw(price, YYYYMMDD,HMS,textlabel, texthint)  
label_params.TEXT = textlabel;
label_params.DATE = YYYYMMDD; 
label_params.TIME =HMS;
label_params.YVALUE = price;
label_params.HINT = texthint;
label_id_text = AddLabel(tag, label_params)
end

function main()
local i=0; local _size=0; 
while true do
   local  size= getNumCandles(tag);
   while  size>i do
         local t, _, _ = getCandlesByIndex(tag, 0, i, 1)  
         local z=t[0];    local Hi,Li,Ci,Oi=z.high,z.low,z.close,z.open;
             i=i+1;
         local Ti=ds:T(i)
      YYYYMMDD=100*(100*Ti.year+Ti.month)+Ti.day;
      HMS=100*(100*Ti.hour+Ti.min)+Ti.sec;
      labeldraw(Hi, YYYYMMDD,HMS,"A", "B")
   end
   sleep(1)
end
end


function OnInit(p) -- инициализация функции main
sec,clas,int="SBER","QJSIM",5;
tag = "SBER_ID"
ds=CreateDataSource ("sec","QJSIM",5) 
while ds==nil do ds,err=CreateDataSource(clas,sec,int); sleep(1); end
end

остановка скрипта при запуске QUIK
 
Если Вам надо чтобы скрипт, запущенный в QUIK остановился при новом старте нужно первую строку в  колбек OnInit записать так:
Код
function OnInit(path)
 if os.clock()<2 then return  end
индикатор на Lua
 
Индикатор определяет максимум и минимум на заданном периоде и отображает среднее значение.
Алгоритм оптимизировал для ускорения вычислений.
Выкладываю для всех желающих:
Код
Settings = {Name = "*Kijun-sen",kijun_period = 6,}

function OnCalculate(i)
   Hi=H(i) or H1; Li=L(i) or L1; x1=x;
   if i1>i then
      ma=Hi; mi=Li; jma=i; jmi=i;
   end
   if Hi and Li then
      local j=i-Settings.kijun_period; if j<1 then j=1; end
      if j>jma or j>jmi then
         ma=Hi; mi=Li; jma=i; jmi=i;
         while i>j do
            Hi,Li=H(j),L(j)
            if Hi and Hi>ma then ma = Hi jma=j; end
            if Li and Li<mi then  mi =Li jmi=j;end
            j=j+1
         end
      else
         if Hi>ma then ma=Hi; jma=i; end
         if mi>Li then mi=Li; jmi=i; end
      end
      x=(ma + mi)/2;    H1,L1,i1=Hi,Li,i;
   end
return x1
end

function OnChangeSettings()
   i1=0;jma=0; jmi=0; H1=0; L1=0;ma=0;mi=0;
end

function Init()
OnChangeSettings()
Settings.line = {{ Name=Settings.Name, Color=RGB(32,255,128), Type=TYPE_LINE, Width = 2,}}
return #Settings.line  end
это мой вариант модификации этого алгоритма .  
Код
Settings = {Name = "*ind_nk",period = 6,}

function OnCalculate(i)
   Hi=H(i) or H1; Li=L(i) or L1;
   Oi=O(i) or O1; Ci=C(i) or C1;
   if i1>i then
      ma=Hi; mi=Li; jma=i; jmi=i;
   end
   if Hi and Li and i1~=i then

      local j=i-Settings.period; if j<1 then j=1; end
      if j>jma or j>jmi then
         ma=Hi; mi=Li; jma=i; jmi=i;
         while i>j do
            Hi,Li=H(j),L(j)
            if Hi and Hi>ma then ma = Hi jma=j; end
            if Li and Li<mi then  mi =Li jmi=j;end
            j=j+1
         end
      else
         if Hi>ma then ma=Hi; jma=i; end
         if mi>Li then mi=Li; jmi=i;
         end
         if x then
            local z=2*Li-Hi; if Li>x and Ci>Oi then mi=z; jmi=i; end
            z=2*Hi-Li; if x>Hi and Oi>Ci then ma=z; jma=i; end
         end
      end
      if ma and mi then x=(ma + mi)/2; end
      H1,L1,O1,C1,i1=Hi,Li,Oi,Ci,i;
   end
return x
end

function OnChangeSettings()
   i1=0;jma=0; jmi=0; H1=0; L1=0;ma=0;mi=0;
end

function Init()
OnChangeSettings()
Settings.line = {{ Name=Settings.Name, Color=RGB(255,255,255), Type=TYPE_LINE, Width = 2,}}
return #Settings.line  end
Если нравится, можете сказать "спасибо".
Скрипты от ИИ
 
Добрый день,
Выкладываю работающий скрипт, который написал ИИ под моим руководством.
-------------------------------
Скрипт позволяет загружать историю с биржи MOEX.
-------------------------
Состоит из двух файлов.
---------------
config.json  
Код
{
    "instruments": [
        {
            "name": "SBER",
            "start_date": "2015-01-01",
            "decimal_places": 2,
            "intervals": [1, 10, 60, 24],
            "parameters": ["open", "high", "low", "close", "volume"],
            "board": "TQBR"
        },
        {
            "name": "GAZP",
            "start_date": "2015-01-01",
            "decimal_places": 2,
            "intervals": [1, 10, 60, 24],
            "parameters": ["open", "high", "low", "close", "volume"],
            "board": "TQBR"
        }
    ]
}
data_fetcher.py
Код
import os
import pandas as pd
import requests
import json
from datetime import datetime, timedelta

def load_config(config_file="config.json"):
    """
    Загружает конфигурацию из JSON файла

    Параметры:
    config_file (str): Путь к файлу конфигурации

    Возвращает:
    dict: Конфигурация
    """
    if not os.path.exists(config_file):
        print(f"Файл конфигурации {config_file} не найден")
        return None

    try:
        with open(config_file, 'r', encoding='utf-8') as f:
            config = json.load(f)
        return config
    except Exception as e:
        print(f"Ошибка при загрузке конфигурации: {e}")
        return None

def fetch_moex_data(ticker, start_date, end_date, interval=60):
    """
    Загружает данные с MOEX API для указанного тикера и временного периода

    Параметры:
    ticker (str): Тикер инструмента
    start_date (datetime): Начальная дата загрузки
    end_date (datetime): Конечная дата загрузки
    interval (int): Интервал свечей в минутах (по умолчанию 60 минут)

    Возвращает:
    pd.DataFrame: DataFrame с загруженными данными
    """
    data = []
    current_start = start_date
    print(f"Загрузка данных с MOEX для {ticker} (интервал: {interval} мин) с {start_date} по {end_date}...")

    while True:
        url = f"http://iss.moex.com/iss/engines/stock/markets/shares/boards/TQBR/securities/{ticker}/candles.json"
        params = {
            'from': current_start.strftime('%Y-%m-%d'),
            'till': end_date.strftime('%Y-%m-%d'),
            'interval': interval,
            'start': 0
        }

        try:
            response = requests.get(url, params=params)
            response.raise_for_status()  # Проверка на ошибки HTTP
            json_data = response.json()

            if 'candles' not in json_data or 'data' not in json_data['candles']:
                print("Нет данных в ответе API")
                break

            candles = pd.DataFrame(json_data['candles']['data'],
                                  columns=json_data['candles']['columns'])

            if len(candles) == 0:
                break

            data.append(candles)

            # Обновляем время для следующего запроса
            current_start = (pd.to_datetime(candles['end'].iloc[-1]) + timedelta(minutes=interval))

            if len(candles) < 500:  # Если получено меньше 500 записей, это последняя порция
                break

        except requests.exceptions.RequestException as e:
            print(f"Ошибка при запросе данных: {e}")
            break

    print(f"Загружено {len(data)} блоков данных")

    if not data:
        return pd.DataFrame()

    # Объединяем все блоки данных и удаляем дубликаты
    return pd.concat(data).drop_duplicates()

def process_raw_data(raw_data):
    """
    Обрабатывает сырые данные: разделяет begin на date и time, удаляет end

    Параметры:
    raw_data (pd.DataFrame): Сырые данные с MOEX

    Возвращает:
    pd.DataFrame: Обработанные данные
    """
    # Разделение begin на date и time
    raw_data['date'] = pd.to_datetime(raw_data['begin']).dt.date

    # Преобразование времени в формат без двоеточий (HHMMSS)
    raw_data['time'] = pd.to_datetime(raw_data['begin']).dt.strftime('%H%M%S')

    # Удаление ненужных столбцов
    columns_to_keep = ['date', 'time', 'open', 'high', 'low', 'close', 'volume']
    processed_data = raw_data[columns_to_keep].copy()

    # Сортировка по дате и времени
    processed_data = processed_data.sort_values(['date', 'time'])

    return processed_data

def get_last_available_date(ticker_dir):
    """
    Определяет последнюю дату, за которую есть данные в структуре каталогов

    Параметры:
    ticker_dir (str): Путь к каталогу тикера

    Возвращает:
    datetime.date: Последняя дата или None, если данных нет
    """
    last_date = None

    # Проходим по всем подкаталогам (годы)
    if not os.path.exists(ticker_dir):
        return None

    for year_dir in os.listdir(ticker_dir):
        year_path = os.path.join(ticker_dir, year_dir)
        if not os.path.isdir(year_path):
            continue

        # Проходим по месяцам
        for month_dir in os.listdir(year_path):
            month_path = os.path.join(year_path, month_dir)
            if not os.path.isdir(month_path):
                continue

            # Проходим по дням
            for day_dir in os.listdir(month_path):
                day_path = os.path.join(month_path, day_dir)
                if not os.path.isdir(day_path):
                    continue

                # Проверяем, что имя дня - это число (день месяца)
                if not day_dir.isdigit():
                    continue

                # Формируем дату: год, месяц, день
                try:
                    year = int(year_dir)
                    month = int(month_dir)
                    day = int(day_dir)
                    current_date = datetime(year, month, day).date()
                except:
                    continue

                # Сравниваем с последней датой
                if last_date is None or current_date > last_date:
                    last_date = current_date

    return last_date

def update_data_file(ticker, interval, output_dir, start_date, end_date):
    """
    Обновляет файлы данных, добавляя новые записи при необходимости

    Параметры:
    ticker (str): Тикер инструмента
    interval (int): Интервал свечей в минутах
    output_dir (str): Путь к каталогу для сохранения данных
    start_date (datetime): Начальная дата для загрузки
    end_date (datetime): Конечная дата для загрузки

    Возвращает:
    None
    """
    # Определяем последнюю дату, за которую есть данные
    last_date = get_last_available_date(output_dir)

    if last_date is None:
        # Данных нет, загружаем с начальной даты
        new_start_date = start_date
        print("Не найдено существующих данных. Загружаем все данные...")
    else:
        # Загружаем с последней даты (включительно)
        new_start_date = datetime.combine(last_date, datetime.min.time())
        print(f"Найдены данные до {last_date}. Загружаем новые данные начиная с этой даты...")

    # Загружаем данные с MOEX
    raw_data = fetch_moex_data(ticker, new_start_date, end_date, interval)

    if raw_data.empty:
        print("Нет новых данных для загрузки")
        return

    # Обрабатываем данные
    processed_data = process_raw_data(raw_data)

    # Сохраняем данные, разбивая по датам
    save_data_by_date(ticker, interval, output_dir, processed_data)

    print(f"Загружено и сохранено {len(processed_data)} записей")

def save_data_by_date(ticker, interval, output_dir, data):
    """
    Сохраняет данные с разбиением по датам в подкаталоги

    Параметры:
    ticker (str): Тикер инструмента
    interval (int): Интервал в минутах
    output_dir (str): Базовый каталог для сохранения
    data (pd.DataFrame): Данные для сохранения

    Возвращает:
    None
    """
    # Получаем имя интервала
    interval_name = get_interval_name(interval)

    # Группируем данные по датам
    grouped = data.groupby('date')

    for date, day_data in grouped:
        # Разбиваем дату на год, месяц, день
        year = date.year
        month = date.month
        day = date.day

        # Форматируем месяц и день с ведущими нулями
        month_str = f"{month:02d}"
        day_str = f"{day:02d}"

        # Формируем путь к каталогу для этой даты
        date_dir = os.path.join(output_dir, str(year), month_str, day_str)

        # Создаем каталог, если он не существует
        os.makedirs(date_dir, exist_ok=True)

        # Создаем подкаталог для интервала
        interval_dir = os.path.join(date_dir, interval_name)
        os.makedirs(interval_dir, exist_ok=True)

        # Удаляем столбец date перед сохранением
        day_data_to_save = day_data.drop(columns=['date'])

        # Сохраняем каждый параметр в отдельный файл
        for column in day_data_to_save.columns:
            file_path = os.path.join(interval_dir, column)

            # Сохраняем столбец без индекса и без заголовка
            day_data_to_save[column].to_csv(file_path, index=False, header=False)

            print(f"Сохранено {len(day_data_to_save[column])} значений параметра '{column}' за {date} в {file_path}")

def get_interval_name(interval):
    """
    Преобразует интервал в минутах в текстовое представление

    Параметры:
    interval (int): Интервал в минутах

    Возвращает:
    str: Текстовое представление интервала
    """
    if interval == 1:
        return "1min"
    elif interval == 10:
        return "10min"
    elif interval == 60:
        return "1hour"
    elif interval == 1440:
        return "1day"
    else:
        return f"{interval}min"

if __name__ == "__main__":
    # Загрузка конфигурации
    config = load_config()
    if not config:
        print("Не удалось загрузить конфигурацию. Выход...")
        exit(1)

    # Параметры загрузки
    end_date = datetime.now()

    print(f"Начало загрузки данных для тикеров: {', '.join([item['ticker'] for item in config['tickers']])}")
    print(f"Период: с {min([datetime.strptime(item['start_date'], '%Y-%m-%d') for item in config['tickers']])} по {end_date.strftime('%Y-%m-%d')}")
    print("-" * 50)

    # Обработка каждого тикера и интервала
    for ticker_config in config['tickers']:
        ticker = ticker_config['ticker']
        start_date_str = ticker_config['start_date']
        intervals = ticker_config['intervals']

        # Преобразование начальной даты из строки в datetime
        try:
            start_date = datetime.strptime(start_date_str, '%Y-%m-%d')
        except ValueError:
            print(f"Ошибка в формате даты для тикера {ticker}: {start_date_str}")
            continue

        print(f"\nОбработка тикера: {ticker} (начальная дата: {start_date_str})")
        print(f"Интервалы: {', '.join([get_interval_name(i) for i in intervals])}")

        # Формирование пути к каталогу для сохранения данных
        base_dir = "moex"
        ticker_dir = os.path.join(base_dir, ticker)

        # Обработка каждого интервала для текущего тикера
        for interval in intervals:
            print(f"\nОбработка интервала: {get_interval_name(interval)}")

            # Обновление файла данных
            update_data_file(ticker, interval, ticker_dir, start_date, end_date)

            # Проверка сохраненных данных
            print("\nПроверка сохраненных данных:")
            interval_name = get_interval_name(interval)

            # Проверяем наличие подкаталогов с датами
            if os.path.exists(ticker_dir):
                # Собираем все даты из структуры каталогов
                dates_found = []

                # Проходим по годам
                for year_dir in sorted(os.listdir(ticker_dir)):
                    year_path = os.path.join(ticker_dir, year_dir)
                    if not os.path.isdir(year_path):
                        continue

                    # Проходим по месяцам
                    for month_dir in sorted(os.listdir(year_path)):
                        month_path = os.path.join(year_path, month_dir)
                        if not os.path.isdir(month_path):
                            continue

                        # Проходим по дням
                        for day_dir in sorted(os.listdir(month_path)):
                            day_path = os.path.join(month_path, day_dir)
                            if not os.path.isdir(day_path):
                                continue

                            # Проверяем наличие подкаталога с интервалом
                            interval_path = os.path.join(day_path, interval_name)
                            if os.path.isdir(interval_path):
                                # Формируем дату для отображения
                                try:
                                    year = int(year_dir)
                                    month = int(month_dir)
                                    day = int(day_dir)
                                    date_str = f"{year:04d}-{month:02d}-{day:02d}"
                                    dates_found.append(date_str)
                                except:
                                    pass

                if dates_found:
                    print(f"Найдено {len(dates_found)} дат с данными:")
                    # Показываем последние 5 дат
                    for date_str in sorted(dates_found)[-5:]:
                        # Формируем путь к каталогу интервала
                        interval_path = os.path.join(ticker_dir, date_str.split('-')[0],
                                                    date_str.split('-')[1], date_str.split('-')[2],
                                                    interval_name)

                   #     if os.path.exists(interval_path):
                    #        print(f"  {date_str}:")

                            # Проверяем наличие файлов с параметрами
                    #        for param in ['time', 'open', 'high', 'low', 'close', 'volume']:
                    #            param_file = os.path.join(interval_path, param)
                    #            if os.path.exists(param_file):
                    #                # Читаем файл
                    #                param_data = pd.read_csv(param_file, header=None)
                    #                print(f"    {param}: {len(param_data)} значений")

                                    # Выводим последние 3 значения для проверки
                               #     if len(param_data) > 0:
                               #         print(f"      Последние 3 значения: {', '.join(map(str, param_data.tail(3).values.flatten()))}")
                    #    else:
                    #        print(f"  {date_str}: каталог интервала не найден")
                else:
                    print("Данные не найдены")
            else:
                print(f"Каталог тикера {ticker} не найден")

            print("-" * 30)

   #     print("-" * 50)

    print("\nЗагрузка данных завершена для всех инструментов и интервалов")
QUIK на VPS
 
Добрый день,
Вопрос к разработчикам и знатокам.
Хочу поставить торгового робота c возможностью ручной торговли на VPS.
QUIK или что-то подобное вполне устроило бы.
робота могу написать на любом языке, но предпочитаю С и Lua.
----------------------
Какое решение можете посоветовать.
-------------------
Какие требования к железу. Если есть что-то в интернете просьба дать ссылку.
Что-то с сайтом не так.
 
Сегодня при попытке зайти на Ваш сайт получаю это:
Данные с MOEX на Lua
 
Для этого надо установить пакет luasocket.
-------------------
Пример скрипта  получить данные по Сбер для тайма 10 минут
Код
p2 = "D:/luasocket/"; 
package.cpath =package.cpath ..";"..p2.."?.dll";
package.path =package.path..";"..p2.."?.lua;"
local http = require("socket.http")

local header="http://iss.moex.com/iss/"
local sec="SBER"
local Date="2025-03-10"
local interval="10"
Data=http.request(header..eng..sec.."/candles.csv?from="..Date.."&interval="..interval) --не более 500 значений
print(Data)
результат:
Код
candles

open;close;high;low;value;volume;begin;end
316.98;316.98;316.98;316.98;6558316.199999993;20690;2025-03-10 06:50:00;2025-03-10 06:59:59
317;318.71;318.71;317;175975306.3;553270;2025-03-10 07:00:00;2025-03-10 07:09:59
318.6;318.23;318.68;318.01;47408624.699999996;148930;2025-03-10 07:10:00;2025-03-10 07:19:59
318.26;318.35;318.6;318.07;84248628.7;264640;2025-03-10 07:20:00;2025-03-10 07:29:59
318.34;318.2;318.53;318.2;27067709.6;85020;2025-03-10 07:30:00;2025-03-10 07:39:59
318.2;318.47;318.5;318.16;19870959.499999996;62420;2025-03-10 07:40:00;2025-03-10 07:49:59
318.49;318.15;318.58;318.15;30327046.200000003;95250;2025-03-10 07:50:00;2025-03-10 07:59:59
318.14;318.03;318.2;317.98;41976335.3;131970;2025-03-10 08:00:00;2025-03-10 08:09:59
318.02;318.25;318.46;318;38795280.800000004;121920;2025-03-10 08:10:00;2025-03-10 08:19:59
318.24;318.21;318.43;318.16;21885336.900000002;68770;2025-03-10 08:20:00;2025-03-10 08:29:59
318.26;318.11;318.36;317.97;35239183;110760;2025-03-10 08:30:00;2025-03-10 08:39:59
318.12;318.15;318.24;318;21160924.200000003;66520;2025-03-10 08:40:00;2025-03-10 08:49:59
318.15;317.82;318.17;317.82;40041972.60000001;125950;2025-03-10 08:50:00;2025-03-10 08:59:59
317.81;317.76;318;317.75;133830122.00000001;421140;2025-03-10 09:00:00;2025-03-10 09:09:59
317.77;317.39;317.87;317.32;49434518.60000001;155660;2025-03-10 09:10:00;2025-03-10 09:19:59
317.39;317.85;317.93;317.39;66449996.699999996;209220;2025-03-10 09:20:00;2025-03-10 09:29:59
317.86;318.5;318.7;317.7;131819408.4;413940;2025-03-10 09:30:00;2025-03-10 09:39:59
318.49;318.4;318.51;318.24;49213137.300000004;154560;2025-03-10 09:40:00;2025-03-10 09:49:59
318.38;318.4;318.52;318.22;71269440.2;223850;2025-03-10 09:50:00;2025-03-10 09:59:59
318.36;318.05;318.53;317.92;219652877.20000002;690420;2025-03-10 10:00:00;2025-03-10 10:09:59
318.08;318.16;318.28;317.93;88167886;277180;2025-03-10 10:10:00;2025-03-10 10:19:59
318.16;316.67;318.2;316.37;471615257.1;1486720;2025-03-10 10:20:00;2025-03-10 10:29:59
316.67;317.23;317.63;316.67;204793272.60000005;645670;2025-03-10 10:30:00;2025-03-10 10:39:59
317.23;317.41;317.52;317;121681174.80000004;383570;2025-03-10 10:40:00;2025-03-10 10:49:59
317.41;317.29;317.93;317.26;164760496.00000003;518700;2025-03-10 10:50:00;2025-03-10 10:59:59
317.29;317.47;317.74;317.2;71508892.9;225250;2025-03-10 11:00:00;2025-03-10 11:09:59
317.44;317.8;318;317.3;100920005.19999999;317570;2025-03-10 11:10:00;2025-03-10 11:19:59
317.8;317.26;318.16;317;225224639.00000003;709590;2025-03-10 11:20:00;2025-03-10 11:29:59
317.25;317.6;317.82;317.25;115677122.69999997;364200;2025-03-10 11:30:00;2025-03-10 11:39:59
317.6;317.68;317.85;317.18;111280152.30000001;350360;2025-03-10 11:40:00;2025-03-10 11:49:59
317.6;317.37;317.97;317.31;105261628.70000003;331320;2025-03-10 11:50:00;2025-03-10 11:59:59
317.34;317.08;317.6;316.83;248860136.1000001;784780;2025-03-10 12:00:00;2025-03-10 12:09:59
317.08;316.99;317.15;316.8;120169067.6;379150;2025-03-10 12:10:00;2025-03-10 12:19:59
316.97;317.14;317.45;316.97;79511919.60000001;250680;2025-03-10 12:20:00;2025-03-10 12:29:59
317.14;317.74;317.79;317.13;100651973.49999999;317060;2025-03-10 12:30:00;2025-03-10 12:39:59
317.73;318.26;318.48;317.62;322494796.1;1013600;2025-03-10 12:40:00;2025-03-10 12:49:59
318.25;319.48;319.49;318.06;674781138.9000006;2115780;2025-03-10 12:50:00;2025-03-10 12:59:59
319.44;319.29;319.49;318.75;311378074.9000001;975590;2025-03-10 13:00:00;2025-03-10 13:09:59
319.3;319.12;319.94;319;553953558.5999991;1733680;2025-03-10 13:10:00;2025-03-10 13:19:59
319.16;319.18;319.31;318.67;258552251.50000006;810640;2025-03-10 13:20:00;2025-03-10 13:29:59
319.19;319.14;319.59;319.01;171823970.89999998;538100;2025-03-10 13:30:00;2025-03-10 13:39:59
319.15;318.92;319.2;318.57;188321384.6;590480;2025-03-10 13:40:00;2025-03-10 13:49:59
318.91;318.81;318.95;318.67;78612829.80000003;246570;2025-03-10 13:50:00;2025-03-10 13:59:59
318.78;319.38;319.95;318.77;513175851.2;1606420;2025-03-10 14:00:00;2025-03-10 14:09:59
319.38;318.96;319.38;318.84;182232033.90000004;571070;2025-03-10 14:10:00;2025-03-10 14:19:59
319;319.28;319.47;318.7;183904173.1;576430;2025-03-10 14:20:00;2025-03-10 14:29:59
319.23;319.15;319.37;319;157636132.9000001;494020;2025-03-10 14:30:00;2025-03-10 14:39:59
319.15;319.16;319.37;319;119519400.10000002;374540;2025-03-10 14:40:00;2025-03-10 14:49:59
319.17;319.55;319.75;319.1;136698176.20000002;427880;2025-03-10 14:50:00;2025-03-10 14:59:59
319.54;319.22;319.64;319;225211218.60000005;705350;2025-03-10 15:00:00;2025-03-10 15:09:59
319.27;319.55;319.55;319.12;57168158.599999994;179010;2025-03-10 15:10:00;2025-03-10 15:19:59
319.55;319.23;319.59;319.17;78352069.79999998;245310;2025-03-10 15:20:00;2025-03-10 15:29:59
319.23;319.33;319.5;319.2;50655222;158620;2025-03-10 15:30:00;2025-03-10 15:39:59
319.33;319.55;319.59;319.2;94761912.99999997;296650;2025-03-10 15:40:00;2025-03-10 15:49:59
319.55;319.71;319.75;319.42;85916305.70000002;268780;2025-03-10 15:50:00;2025-03-10 15:59:59
319.71;319.6;319.84;319.6;145533720.7;455280;2025-03-10 16:00:00;2025-03-10 16:09:59
319.6;320.48;320.63;319.6;667109220.6999998;2083330;2025-03-10 16:10:00;2025-03-10 16:19:59
320.46;320;320.51;319.92;281212775.49999994;878130;2025-03-10 16:20:00;2025-03-10 16:29:59
320;319.39;320.1;319.2;206595805.20000005;646280;2025-03-10 16:30:00;2025-03-10 16:39:59
319.4;319.41;319.72;319.21;133510730.40000004;417890;2025-03-10 16:40:00;2025-03-10 16:49:59
319.4;319.5;319.94;319.36;84631125.29999998;264730;2025-03-10 16:50:00;2025-03-10 16:59:59
319.51;319.55;319.76;319.4;62520826.6;195640;2025-03-10 17:00:00;2025-03-10 17:09:59
319.57;319.54;319.62;319.38;70866999.7;221830;2025-03-10 17:10:00;2025-03-10 17:19:59
319.53;318.52;319.56;317.5;517624221.59999996;1626050;2025-03-10 17:20:00;2025-03-10 17:29:59
318.53;318.64;318.88;318.33;94381582.50000001;296210;2025-03-10 17:30:00;2025-03-10 17:39:59
318.67;318.92;319.17;318.55;150513043.1;472080;2025-03-10 17:40:00;2025-03-10 17:49:59
318.85;318.5;318.9;318.5;51312515.699999996;161020;2025-03-10 17:50:00;2025-03-10 17:59:59
318.5;318.25;318.5;317.8;230751215.80000007;725410;2025-03-10 18:00:00;2025-03-10 18:09:59
318.25;318.34;318.6;318.07;75083299.89999999;235860;2025-03-10 18:10:00;2025-03-10 18:19:59
318.32;318.1;318.45;318;56363842.9;177190;2025-03-10 18:20:00;2025-03-10 18:29:59
318.09;318.15;318.41;317.91;72950185.7;229320;2025-03-10 18:30:00;2025-03-10 18:39:59
317.6;317.6;317.6;317.6;129739600;408500;2025-03-10 18:40:00;2025-03-10 18:49:59
317.95;318;318.18;317.72;61493505.89999999;193370;2025-03-10 19:00:00;2025-03-10 19:09:59
318;318.3;318.34;317.97;95886070.69999999;301400;2025-03-10 19:10:00;2025-03-10 19:19:59
318.3;317.76;318.45;317.75;45363522.7;142620;2025-03-10 19:20:00;2025-03-10 19:29:59
317.76;317.84;317.93;317.74;30867686.9;97120;2025-03-10 19:30:00;2025-03-10 19:39:59
317.83;318.05;318.36;317.75;47578783.3;149600;2025-03-10 19:40:00;2025-03-10 19:49:59
318.04;318.09;318.32;318.04;19216828.900000002;60410;2025-03-10 19:50:00;2025-03-10 19:59:59
318.08;317.9;318.16;317.9;28139057.39999999;88470;2025-03-10 20:00:00;2025-03-10 20:09:59
317.9;317.97;317.99;317.83;12054377.899999999;37920;2025-03-10 20:10:00;2025-03-10 20:19:59
317.94;317.98;318;317.88;9630865.600000001;30290;2025-03-10 20:20:00;2025-03-10 20:29:59
317.98;317.51;317.98;317.5;99723652.29999998;313920;2025-03-10 20:30:00;2025-03-10 20:39:59
317.5;317.15;317.5;316.68;357174365.49999994;1126890;2025-03-10 20:40:00;2025-03-10 20:49:59
317.15;317.02;317.34;316.97;28328302.4;89330;2025-03-10 20:50:00;2025-03-10 20:59:59
317.02;317.08;317.19;316.9;44550143.89999999;140530;2025-03-10 21:00:00;2025-03-10 21:09:59
317.07;317.92;317.96;317.06;98698390.19999999;310830;2025-03-10 21:10:00;2025-03-10 21:19:59
317.93;317.44;317.93;317.44;65801526.4;207060;2025-03-10 21:20:00;2025-03-10 21:29:59
317.44;317.84;317.88;317.24;27684769.1;87180;2025-03-10 21:30:00;2025-03-10 21:39:59
317.85;317.7;317.85;317.67;11610775.700000001;36540;2025-03-10 21:40:00;2025-03-10 21:49:59
317.68;317.67;317.8;317.67;7451154.200000001;23450;2025-03-10 21:50:00;2025-03-10 21:59:59
317.68;317.44;317.74;317.43;14800377.900000002;46600;2025-03-10 22:00:00;2025-03-10 22:09:59
317.43;317.19;317.57;317.02;43047580.3;135700;2025-03-10 22:10:00;2025-03-10 22:19:59
317.18;317.37;317.52;317.18;23116736.9;72830;2025-03-10 22:20:00;2025-03-10 22:29:59
317.37;317.57;317.68;317.33;24962601.300000004;78620;2025-03-10 22:30:00;2025-03-10 22:39:59
317.57;317.38;317.57;317.38;19585749.599999998;61700;2025-03-10 22:40:00;2025-03-10 22:49:59
317.39;317.38;317.39;317.3;14902353.6;46960;2025-03-10 22:50:00;2025-03-10 22:59:59
317.39;317.46;317.5;317.39;9695359.4;30540;2025-03-10 23:00:00;2025-03-10 23:09:59
317.46;317.49;317.49;317.41;33814353.800000004;106510;2025-03-10 23:10:00;2025-03-10 23:19:59
317.49;317.57;317.62;317.48;39505913.3;124420;2025-03-10 23:20:00;2025-03-10 23:29:59
317.57;317.5;317.57;317.31;31998754.200000003;100810;2025-03-10 23:30:00;2025-03-10 23:39:59
317.5;317.57;317.67;317.45;58358134.599999994;183770;2025-03-10 23:40:00;2025-03-10 23:49:59
317.7;317.7;317.7;317.7;2821176;8880;2025-03-11 06:50:00;2025-03-11 06:59:59
317.78;318.2;318.7;317.6;87586947.2;275220;2025-03-11 07:00:00;2025-03-11 07:09:59
318.23;318.05;318.29;318.04;23422902.1;73620;2025-03-11 07:10:00;2025-03-11 07:19:59
318.1;318.41;318.5;318;36120401.400000006;113470;2025-03-11 07:20:00;2025-03-11 07:29:59
318.42;318.29;318.5;318.2;13874050.399999999;43580;2025-03-11 07:30:00;2025-03-11 07:39:59
318.28;318.29;318.29;318.28;6238445.500000001;19600;2025-03-11 07:40:00;2025-03-11 07:49:59
318.28;318.11;318.29;318.1;16128308.4;50690;2025-03-11 07:50:00;2025-03-11 07:59:59
318.11;317.87;318.11;317.82;17662961.599999998;55550;2025-03-11 08:00:00;2025-03-11 08:09:59
317.93;318.16;318.19;317.93;8344390.7;26230;2025-03-11 08:10:00;2025-03-11 08:19:59
318.15;317.91;318.26;317.9;8340461.699999999;26220;2025-03-11 08:20:00;2025-03-11 08:29:59
317.96;317.8;317.97;317.6;26977807.199999988;84900;2025-03-11 08:30:00;2025-03-11 08:39:59
317.8;317.62;317.97;317.61;17680679.1;55620;2025-03-11 08:40:00;2025-03-11 08:49:59
317.74;317.32;317.81;317.32;67167200.39999999;211510;2025-03-11 08:50:00;2025-03-11 08:59:59
317.33;317.49;317.92;317.31;70360926.60000001;221550;2025-03-11 09:00:00;2025-03-11 09:09:59
317.49;317.29;317.5;317.21;52695987;166070;2025-03-11 09:10:00;2025-03-11 09:19:59
317.29;317.39;317.48;316.72;96404497.90000004;304100;2025-03-11 09:20:00;2025-03-11 09:29:59
317.38;317.58;317.86;317.3;50274399.79999996;158320;2025-03-11 09:30:00;2025-03-11 09:39:59
317.58;317.32;317.78;317;39921641.9;125780;2025-03-11 09:40:00;2025-03-11 09:49:59
317.36;317.06;317.4;316.07;315354329.2;996070;2025-03-11 09:50:00;2025-03-11 09:59:59
317.01;315.91;317.07;315.66;513685099.0000001;1625210;2025-03-11 10:00:00;2025-03-11 10:09:59
315.88;316.64;316.64;315.57;355175621.99999994;1123830;2025-03-11 10:10:00;2025-03-11 10:19:59
316.62;316.57;317.28;316.34;224793168.19999996;709750;2025-03-11 10:20:00;2025-03-11 10:29:59
316.57;316.65;316.76;316.03;216093107.90000004;682980;2025-03-11 10:30:00;2025-03-11 10:39:59
316.65;318.38;318.68;316.6;717415758.6;2257710;2025-03-11 10:40:00;2025-03-11 10:49:59
318.46;318.42;318.53;318.01;241769644.3;759470;2025-03-11 10:50:00;2025-03-11 10:59:59
318.42;319.99;320.49;318.14;1070825372.4;3350700;2025-03-11 11:00:00;2025-03-11 11:09:59
319.99;319.6;320.34;319.25;390892391.20000005;1222580;2025-03-11 11:10:00;2025-03-11 11:19:59
319.58;319.96;320;319.48;227905559.60000005;712670;2025-03-11 11:20:00;2025-03-11 11:29:59
319.96;319.99;320.1;319.95;152333402.00000006;476040;2025-03-11 11:30:00;2025-03-11 11:39:59
319.98;319.65;319.99;319;254934993.9;798230;2025-03-11 11:40:00;2025-03-11 11:49:59
319.62;319;319.66;318.65;170697046.00000003;535010;2025-03-11 11:50:00;2025-03-11 11:59:59
319;319.1;319.6;318.82;133154876.7999998;417050;2025-03-11 12:00:00;2025-03-11 12:09:59
319.1;318.78;319.4;318.6;348113064.8999999;1091620;2025-03-11 12:10:00;2025-03-11 12:19:59
318.78;318.01;318.8;318;378198086.6000001;1188160;2025-03-11 12:20:00;2025-03-11 12:29:59
318;318.86;318.96;318;156668099.10000002;491850;2025-03-11 12:30:00;2025-03-11 12:39:59
318.83;318.91;318.97;318.7;76522840.39999999;239980;2025-03-11 12:40:00;2025-03-11 12:49:59
318.96;318.98;318.99;318.7;88897780.9;278780;2025-03-11 12:50:00;2025-03-11 12:59:59
318.99;319.45;319.63;318.93;216690560.3;678460;2025-03-11 13:00:00;2025-03-11 13:09:59
319.41;319.47;319.65;319.26;112337813.89999999;351600;2025-03-11 13:10:00;2025-03-11 13:19:59
319.43;319.37;319.5;318.83;121616323.40000004;381050;2025-03-11 13:20:00;2025-03-11 13:29:59
319.34;319.82;319.89;319.1;170356178.79999986;533050;2025-03-11 13:30:00;2025-03-11 13:39:59
319.86;319.86;320.05;319.63;360185284.1;1125870;2025-03-11 13:40:00;2025-03-11 13:49:59
319.82;319.7;320.02;319.53;126334275.3;394940;2025-03-11 13:50:00;2025-03-11 13:59:59
319.71;319.4;319.71;319.18;64190452.599999994;200990;2025-03-11 14:00:00;2025-03-11 14:09:59
319.4;318.65;319.4;318.2;274579169.1;861710;2025-03-11 14:10:00;2025-03-11 14:19:59
318.65;319.56;320.06;318.55;357971726.90000004;1120010;2025-03-11 14:20:00;2025-03-11 14:29:59
319.57;319.39;319.6;319.03;116185744.19999999;363830;2025-03-11 14:30:00;2025-03-11 14:39:59
319.39;319.3;319.49;319.18;91109377.09999998;285280;2025-03-11 14:40:00;2025-03-11 14:49:59
319.22;318.5;319.5;318.44;239955025.19999996;752310;2025-03-11 14:50:00;2025-03-11 14:59:59
318.49;318.7;319.08;318.2;328263597.79999995;1030520;2025-03-11 15:00:00;2025-03-11 15:09:59
318.71;318.66;318.82;318.43;113859591.89999999;357410;2025-03-11 15:10:00;2025-03-11 15:19:59
318.66;318.9;319.1;318.53;77947730.50000001;244570;2025-03-11 15:20:00;2025-03-11 15:29:59
318.82;319;319.14;318.7;42302012.3;132630;2025-03-11 15:30:00;2025-03-11 15:39:59
319;319.24;319.5;318.8;125415824.9;392850;2025-03-11 15:40:00;2025-03-11 15:49:59
319.23;319.24;319.4;318.72;103262974.7;323560;2025-03-11 15:50:00;2025-03-11 15:59:59
319.24;319.53;319.74;319.18;195054758.1;610560;2025-03-11 16:00:00;2025-03-11 16:09:59
319.52;319.75;319.95;319.49;211115199.8;660210;2025-03-11 16:10:00;2025-03-11 16:19:59
319.75;320.09;320.25;319.63;341314600.7999999;1066620;2025-03-11 16:20:00;2025-03-11 16:29:59
320.07;319.78;320.09;319.73;129603205.10000001;405100;2025-03-11 16:30:00;2025-03-11 16:39:59
319.78;319.97;320;319.78;72642700.89999999;227040;2025-03-11 16:40:00;2025-03-11 16:49:59
319.96;320.03;320.18;319.96;105175298.60000001;328610;2025-03-11 16:50:00;2025-03-11 16:59:59
320.03;321.09;321.2;320.03;744500105.5000001;2321110;2025-03-11 17:00:00;2025-03-11 17:09:59
321.09;321.01;321.98;320.96;1269680795;3949580;2025-03-11 17:10:00;2025-03-11 17:19:59
321.01;320.8;321.3;320.79;254568182.40000007;792940;2025-03-11 17:20:00;2025-03-11 17:29:59
320.8;320.92;321.12;320.76;159533393.89999998;497040;2025-03-11 17:30:00;2025-03-11 17:39:59
320.98;320.46;321.04;320.25;199581991.60000002;622630;2025-03-11 17:40:00;2025-03-11 17:49:59
320.46;320.43;320.74;320.35;113832584.79999998;355120;2025-03-11 17:50:00;2025-03-11 17:59:59
320.42;320.1;320.5;319.51;242440416.5;757710;2025-03-11 18:00:00;2025-03-11 18:09:59
320.07;319.65;320.23;319.31;162779543.59999993;509110;2025-03-11 18:10:00;2025-03-11 18:19:59
319.65;320.05;320.05;319.5;105775473.7;330770;2025-03-11 18:20:00;2025-03-11 18:29:59
320.06;319.86;320.19;319.81;33642858.9;105130;2025-03-11 18:30:00;2025-03-11 18:39:59
320.23;320.23;320.23;320.23;63632903.299999975;198710;2025-03-11 18:40:00;2025-03-11 18:49:59
320.23;320.12;320.24;319.87;58630601.49999999;183210;2025-03-11 19:00:00;2025-03-11 19:09:59
320.13;319.88;320.17;319.87;77382776.19999999;241870;2025-03-11 19:10:00;2025-03-11 19:19:59
319.9;319.88;320.14;319.87;16706214.7;52210;2025-03-11 19:20:00;2025-03-11 19:29:59
319.88;320;320.1;319.88;16224184.199999997;50700;2025-03-11 19:30:00;2025-03-11 19:39:59
320;320.94;321.46;319.97;481574724.60000014;1500410;2025-03-11 19:40:00;2025-03-11 19:49:59
320.95;321.73;321.73;320.55;237047973.30000004;737720;2025-03-11 19:50:00;2025-03-11 19:59:59
321.73;320.81;321.82;320.66;396882068.6;1234690;2025-03-11 20:00:00;2025-03-11 20:09:59
320.85;321.09;321.43;320.84;133254530.4;415010;2025-03-11 20:10:00;2025-03-11 20:19:59
321.09;320.67;321.28;320.4;89851708.00000001;280040;2025-03-11 20:20:00;2025-03-11 20:29:59
320.63;320.6;320.91;320.51;97731504.49999999;304770;2025-03-11 20:30:00;2025-03-11 20:39:59
320.6;320.98;321;320.56;45949417.8;143250;2025-03-11 20:40:00;2025-03-11 20:49:59
320.98;320.82;321.82;320.78;342943078.3;1067340;2025-03-11 20:50:00;2025-03-11 20:59:59
320.82;319.48;321.34;319.2;754016925.4999996;2355380;2025-03-11 21:00:00;2025-03-11 21:09:59
319.47;319.91;320.33;318.53;830634081.9;2601560;2025-03-11 21:10:00;2025-03-11 21:19:59
319.9;320.06;320.98;319.8;296826357.5;926740;2025-03-11 21:20:00;2025-03-11 21:29:59
320.06;320.33;320.6;319.46;237834156.7;743160;2025-03-11 21:30:00;2025-03-11 21:39:59
320.38;318.72;320.53;318.72;487314780.2;1525770;2025-03-11 21:40:00;2025-03-11 21:49:59
318.72;319.56;320.4;318.68;460987075.2000001;1443950;2025-03-11 21:50:00;2025-03-11 21:59:59
319.52;319.05;319.7;319.01;186025632.10000002;582550;2025-03-11 22:00:00;2025-03-11 22:09:59
319.01;318.77;319.18;318.71;188625885.2;591590;2025-03-11 22:10:00;2025-03-11 22:19:59
318.78;319.19;319.54;318.77;149306283.4;467770;2025-03-11 22:20:00;2025-03-11 22:29:59
319.17;319.04;319.45;318.82;96810475.60000001;303500;2025-03-11 22:30:00;2025-03-11 22:39:59
319.04;318.92;319.1;318.82;110522481.00000001;346530;2025-03-11 22:40:00;2025-03-11 22:49:59
318.93;319.52;319.57;318.91;161189119.99999994;504990;2025-03-11 22:50:00;2025-03-11 22:59:59
319.52;320;320.23;319.51;297995934.2;931380;2025-03-11 23:00:00;2025-03-11 23:09:59
319.99;319.46;320.09;319.4;65165758.49999999;203790;2025-03-11 23:10:00;2025-03-11 23:19:59
319.5;319.96;320.03;319.34;61997007.699999996;193920;2025-03-11 23:20:00;2025-03-11 23:29:59
319.96;319.75;320.1;319.64;81898160.2;255980;2025-03-11 23:30:00;2025-03-11 23:39:59
319.77;319.69;319.87;318.81;159117429.7;498140;2025-03-11 23:40:00;2025-03-11 23:49:59
319.99;319.99;319.99;319.99;14092359.6;44040;2025-03-12 06:50:00;2025-03-12 06:59:59
319.8;319.86;320.9;319.7;189258639.9;590800;2025-03-12 07:00:00;2025-03-12 07:09:59
319.86;319.43;320.1;319.31;94263994.5;294750;2025-03-12 07:10:00;2025-03-12 07:19:59
319.43;319.49;319.65;319.13;49855972.099999994;156120;2025-03-12 07:20:00;2025-03-12 07:29:59
319.49;319.91;320;319.48;42978431.79999999;134360;2025-03-12 07:30:00;2025-03-12 07:39:59
319.8;319.86;319.98;319.55;17257491.3;53970;2025-03-12 07:40:00;2025-03-12 07:49:59
319.88;319.74;319.98;319.72;21772345.699999996;68060;2025-03-12 07:50:00;2025-03-12 07:59:59
319.74;319.46;320;319.05;142743038.8;446780;2025-03-12 08:00:00;2025-03-12 08:09:59
319.47;319.17;319.62;319.17;38793959.89999999;121490;2025-03-12 08:10:00;2025-03-12 08:19:59
319.17;319.08;319.18;318.82;114862033;360060;2025-03-12 08:20:00;2025-03-12 08:29:59
319.08;318.85;319.18;318.82;37435063.900000006;117360;2025-03-12 08:30:00;2025-03-12 08:39:59
318.86;318.94;318.94;318.84;11445194.9;35890;2025-03-12 08:40:00;2025-03-12 08:49:59
318.94;318.83;319.18;318.82;56561700.60000001;177280;2025-03-12 08:50:00;2025-03-12 08:59:59
318.83;318.95;319.18;318.83;66854225;209570;2025-03-12 09:00:00;2025-03-12 09:09:59
318.95;319.09;319.14;318.9;30375353.7;95220;2025-03-12 09:10:00;2025-03-12 09:19:59
319.07;319.2;319.2;318.83;59604721.599999994;186840;2025-03-12 09:20:00;2025-03-12 09:29:59
319.2;318.7;319.2;318.5;195157913.00000003;612360;2025-03-12 09:30:00;2025-03-12 09:39:59
318.68;318.75;318.77;318.5;80934915.30000001;254080;2025-03-12 09:40:00;2025-03-12 09:49:59
318.76;318.79;318.87;318.53;48744407.39999999;152930;2025-03-12 09:50:00;2025-03-12 09:59:59
318.78;319.39;319.89;318.38;522223041.3;1637460;2025-03-12 10:00:00;2025-03-12 10:09:59
319.39;318.96;319.5;318.68;118466513.10000002;371270;2025-03-12 10:10:00;2025-03-12 10:19:59
318.89;318.55;318.9;318.48;125755399.90000002;394670;2025-03-12 10:20:00;2025-03-12 10:29:59
318.56;318.59;318.79;318.21;266935099.59999996;838140;2025-03-12 10:30:00;2025-03-12 10:39:59
318.6;318.52;319.3;318.41;385909659.7000001;1210580;2025-03-12 10:40:00;2025-03-12 10:49:59
318.52;317.12;318.57;316.7;1024629631.6000003;3226890;2025-03-12 10:50:00;2025-03-12 10:59:59
317.12;317.55;317.87;316.74;545012790.7000002;1717870;2025-03-12 11:00:00;2025-03-12 11:09:59
317.45;316.69;317.9;316.33;626337185.9000003;1976620;2025-03-12 11:10:00;2025-03-12 11:19:59
316.74;316.6;316.74;315.8;728624311.3999999;2304620;2025-03-12 11:20:00;2025-03-12 11:29:59
316.58;317.32;317.72;316.23;305146801.5;962830;2025-03-12 11:30:00;2025-03-12 11:39:59
317.31;317.49;317.57;317.05;221604317.50000003;698190;2025-03-12 11:40:00;2025-03-12 11:49:59
317.47;317.08;317.75;316.93;180294600.6;567940;2025-03-12 11:50:00;2025-03-12 11:59:59
317.11;317.72;318.02;316.83;236743304.2;745430;2025-03-12 12:00:00;2025-03-12 12:09:59
317.74;317.62;318.32;317.6;255763005.4999999;804240;2025-03-12 12:10:00;2025-03-12 12:19:59
317.62;317.8;318.31;317.5;82693004.3;260220;2025-03-12 12:20:00;2025-03-12 12:29:59
317.78;317.78;317.9;317.18;145754533.39999998;459210;2025-03-12 12:30:00;2025-03-12 12:39:59
317.72;317.81;318;317.48;170713888;536990;2025-03-12 12:40:00;2025-03-12 12:49:59
317.8;318.15;318.18;317.76;96604710.20000002;303800;2025-03-12 12:50:00;2025-03-12 12:59:59
318.17;317.95;318.19;317.75;129962114.39999999;408650;2025-03-12 13:00:00;2025-03-12 13:09:59
318.01;318.11;318.15;317.78;82261181.50000003;258730;2025-03-12 13:10:00;2025-03-12 13:19:59
318.11;318.67;318.67;317.95;139746660.39999986;438930;2025-03-12 13:20:00;2025-03-12 13:29:59
Версия 11.4.0.54. Что не так?
 
Сбер перешел на версию 11.4.0.54.
По их предложению установил.
И сразу появились временами задержки при передвижении позиции мышкой.
Т е двигаешь, ничего не меняется, но через секунд 20-60 позиция перемещается.
Эффект проявляется не всегда, возможно при активном движении рынка.
До этого работал на версии 8 как самой устойчивой и надежной.
Возможно придется обратно откатиться.
Что скажут разработчики. Что не так?
Имена параметров ТТП и других данных торгового сервера MOEX
 
http://ftp.moex.ru/pub/ClientsAPI/ASTS/Bridge_Interfaces/MarketData/
http://ftp.moex.ru/pub/ClientsAPI/ASTS/Bridge_Interfaces/MarketData/Equities­31_Info_Russian.htm
Вопрос разработчикам. Как указать "Время окончания срока действия заявки "?
 
Нигде не нашел конкретное описание и установку данного параметра
------------------------
В документации по QUIK
параметр указан на русском языке :  Время истечения=124141
------------------------
В документации по QLua
аналогичный параметр  есть лишь в описании таблицы заявок :
expiry_timeNUMBERВремя окончания срока действия заявки в формате <ЧЧММСС  DESIGNTIMESP=19552>. Для GTT-заявок, используется вместе со сроком истечения  заявки (Expiry)
----------------------
Просьба объяснить каким образом установить данный параметр на Lua и при ручном вводе заявки.
Если это есть в документации, то дайте ссылку.
проблема с параметром "expiry_time "
 
Добрый день,
В формате таблицы "Заявки"   есть параметр
expiry_timeNUMBERВремя окончания срока действия заявки в формате <ЧЧММСС  DESIGNTIMESP=19552>.
Нигде не смог найти как этот параметр установить.
На демо сервере его установка никак не проявляется.
При ручном вводе заявки не увидел данного параметра.
Кто может пояснить, возможность его применения.  
Проблема с нажатием клавиш в таблице пользователя
 
Добрый день,
В своей таблице использую обработку нажатия правой и левой кнопки мыши.
С левой все нормально, а справой такая проблема
После обработки нажатия правой кнопки мыши в моем колбеке,терминал выдает предложение сортировки:



Как сделать так, чтобы это предложение не появлялось.
как найти единый счет
 
Вопрос к разработчикам.
Тестирую на демо поиск счата таким образом:
-------------------------
str="trade_accounts";
for i=0,getNumberOf(str)-1 do x=getItem(str,i) if string.find(x.class_codes,c) then account=x.trdaccid; break; end end
--------------------
Все находит замечательно.
Но на реальном едином счете, счет не находится.
Что не так?
Установка точного времени
 
Добрый день,
Иногда можно замечать, как время сервера брокера куда-то убегает относительно времени компьютера и времени сделок.
-----------------------
В моей практике были случаи, когда сервер брокера отставал.
Получалось прикольно, время сделок было в будущем.
----------------------  
Особенно важным становится знание точного времени в момент открытия торгов,
если Вы совершаете сделки на открытие.
-------------------------
Как известно, все биржи сверяют свои часы по серверам точного времени.
--------------------
Сделал это на своем компьютере.
Проверить насколько точно синхронизирован ваш компьютер можно здесь:
https://www.ntp-servers.net/
у меня так:


Про синхронизацию ПК можно прочитать здесь:

https://learn.microsoft.com/ru-ru/windows-server/networking/windows-time-service/windows-time-servic...

https://support.hanwhavision.com/hc/en-us/articles/26570683589529-How-to-Setup-an-NTP-Server-on-Wind...

Сервер лучше брать российский из этого пула:


Как исправить QUK без переустановки?
 
Вопрос к разработчикам.
Тестирую скрипт на версии 13. и 10. Ошибка одна и та же.
При вылете скрипта возникает ошибка системы с сообщением.


Удаление файлов с расширением dat не исправляет ошибку.
Исправить можно лишь переустановкой QUIK.
-------------------  
Переустанавливать каждый раз при такой ошибке очень муторно.
----------------------  
Предполагаю, что QUIK записывает какую-то информацию в служебный файл  и после этого выдает всегда эту ошибку.
===============
Какой файл удалить чтобы QUIK  нормально загрузился при возникновении данной ошибки.
===============
Для особо непонятливых поясняю. Сообщение о нехватке памяти -является фейком,
так как при переустановке с тем же или даже меньшим объемом свободной памяти  QUIK нормально работает до очередного затыка в скрипте.
сообщение в Telegram - это просто
 
Код
token="......"  --робот в telegram
chat_id="....." --ваш в telegram
curl="C:/Windows/System32/curl.exe --silent --output null "..'"'.."https://api.telegram.org/bot"..token.."/sendMessage?chat_id="..chat_id.."&text="
------------------------------
mes="привет!!"   --сообщение
os.execute(curl..mes..'"');  --отправляем
Циклические массивы - это просто
 
https://habr.com/ru/articles/828602/
Проблема версии 11.2.0.16
 
Обнаружил такой эффект.
делаем так:

1) Вызываем QUIK Junior, но не подключаемся к серверу.
2) Открываем  любой индикатор в отдельном окне Например ADX

3) Удаляем второе окно
В результате QUIK зависает, окно не удаляется.
4) Принудительно убиваем QUIK
Ускоряем скрипт и выкидываем sleep
 
Добрый день, Всем
С момента появления VMLua в КВИКЕ неоднократно рассказывал о том, что применение event вместо sleep
не только экономит ресурсы процессора, но и позволяет не пропускать события в колбеках и максимально бысто на них реагировать.
говорил об этом например здесь:
https://forum.quik.ru/forum17/topic8426/
---------------------
К сожалению, кроме бессмысленного хамства некоторых посетителей форума, ничего конкретного никто не написал.
---------------
Но вот наконец-то появился вменяемый чел paluke .
и после моей попытки в очередной раз объяснить преимущество event
https://forum.quik.ru/messages/forum10/message75435/topic8600/#message75435






он все же решил проверить это и убедился, что это так действительно:  

Код
Просто проверка концепции:
Кодw32 = require("w32")

run = true
evt = false

function OnInit()
  evt = w32.CreateEvent(nil, 0, 0, nil)
end

function OnStop()
 run = false
 w32.SetEvent(evt)
end

function main()
  while run do
     w32.WaitForSingleObject(evt, 1000000)
  end
  w32.CloseHandle(evt)
end

В колбеках вызываете SetEvent - main сразу просыпается.
С чем Всех и поздравляю.
AlgoPack Mocex, FinRL China
 

В 2023 году Мосбиржа запустила Algopack и выложила на Гитхаб библиотеку на python – moexAlgo,

которая должна упростить работу с AlgoPack API.

AlgoPack — это данные, сигналы и аналитика для алгоритмической торговли через API
  • Загружать большой набор исторических данных
  • Тестировать свои торговые гипотезы
  • Построить алгоритмическую торговлю

В рамках интерфейса доступны следующие типы информации: статические данные о рынках (режимы торгов и их группы, финансовые инструменты и их описание), данные для построения графиков ("свечей"), сделки (анонимно), котировки, исторические данные, различные метаданные.

Аналогично продукту MOEX Trade INFO, который также работает через ИСС,

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

Взаимодействие с сервером осуществляется по протоколу http.

https://data.moex.com/directory

https://www.moex.com/a2193
https://github.com/moexalgo/moexalgo

На питоне работает.
свечи: period_map = {'1m': 60, '10m': 600, '1h': 3600, '1D': 86400, '1W': 604800, '1M': 2678400, '1Q': 8035200}
----------------------
Использую для создания истории для ИИ
на основе FinRL:
Библиотека глубокого обучения с подкреплением для автоматизированной торговли акциями
https://github.com/AI4Finance-Foundation/FinRL
на питоне работает.
версия питона не выше 3.10
выше тоже можно, но сложнее.  работаю на 3.12.


Звук из файла и из памяти на Lua
 
Ранее в теме
https://forum.quik.ru/messages/forum10/message74775/topic8544/#message74775

Показал как воспроизвести звуковой файл на Lua из командной строки.
----------------
Недостаток такого способа - затраты времени на загрузку приложения плеера.
Достоинство - ничего не надо писать на СИ.
===============
В данной теме, по просьбе трудящихся, показываю как воспроизводить звуковой файл  сохранить его в памяти для
многократного воспроизведения.
--------------
Решить эту проблему невозможно без написания функции на СИ.
===============
По данной ссылке
https://cloud.mail.ru/public/PYXu/YrjyXLvcP
можно загрузить zip файл  nks.dll  c такой функцией,
там же есть пример, который напишу ниже,
и библиотека Lua53.dll
--------------------------
Пример :
Код
--функция для Lua 5.3 выводит на динамики звуковой файл
--при первом вызове записывает файл в буфер
--при последующих  вызовах воспроизводит содержимое буфера
--автор nikolz 2024
--распакуйте файл на диск  желательно D
--пример вызова функции для вывода на динамики системного звука

path = "D:/nks/"  --путь где находится файл nks.dll
package.cpath =path.."?.dll;"..package.cpath
require"nks"

local x="C:/Windows/Media/Alarm10.wav" -- звуковой файл
nks.run(x);        -- первый вызов с указанием файла
for x=1,5 do
   nks.run();     -- вызов воспроизведение из буфера памяти
end
nks.stop();        -- завершение работы и удаление буфера памяти
способ звукового сигнала в луа
 
Добрый день,
Можно воспроизводить звуковые сигналы Windows в скриптах луа так:
звук  из каталога C:/Windows/Media/:
Код
os.execute("powershell -c (New-Object Media.SoundPlayer 'C:/Windows/Media/Alarm10.wav').PlaySync();");
Код
os.execute("powershell -c (New-Object Media.SoundPlayer 'C:/Windows/Media/Ring10.wav').PlaySync();");
Что за хрень версия 10...
 
Решил сдуру поменять нормально работающую версию 8.7 на новую у сбербанка 10....
в итоге получился вроде бы тормоз.
---------------
Стал из бекапа восстанавливать и нате вам :


Ну и что теперь делать?
Индикатор Delta
 
Добрый день,
Написал индикатор Delta.
Скрипт 60 строк.
Пока он работает только для текущего дня.
Сам я им не пользуюсь, поэтому особенно не придумывал.
Вот такая картинка получилась для Сбера (нижний график ).
Рисует объему купить продать для тайма графика и накопительную функцию.

Работает быстро, если запустить с начала дня.
Если не сначала, то задумывается при запуске, так как для Сбера например получилось 35 тысяч сделок сегодня.
---------------------
Если кому надо, то пишите могу выложить nkDelta.luac  на какой-нибудь файлообменник.
Предлагаю реализовать
 
Добрый день,
Ув. разработчики
Предлагаю  реализовать возможность:
---------------------------
1) изменять параметры встроенных индикаторов   из скрипта индикатора.
-------------------------
2) устанавливать идентификатор индикатора из скрипта индикатора.
таблица "depo_limits" . Что не так?
 
Добрый день,
-----------------------
Проблема с чтением позиции по инструментам
----------------
В терминале позиция SBER есть  со сроком расчета T0 позиция 120


---------------
При чтении таблицы в скрипте
Код
local s="depo_limits";
local N1=getNumberOf(s)-1
for j=0,N1 do local x=getItem(s,j);
 if x and x.sec_code==sec then Qp=x.currentbal; jdep=j;
   Log:write(value2text(x,"depo=").."\n");Log:flush(); -- вывод в лог файл
   end;
end
есть только с limit_kind <0, естественно позиция НОЛЬ
Код
depo={
["trdaccid"]=NL0011100043,
["currentlimit"]=0.0,
["locked_buy"]=0.0,
["currentbal"]=0.0,
["limit_kind"]=-2000001,
["locked_buy_value"]=0.0,
["openlimit"]=0.0,
["openbal"]=0.0,
["awg_position_price"]=0.0,
["sec_code"]=SBER,
["locked_sell"]=0.0,
["wa_position_price"]=0.0,
["client_code"]=10326,
["wa_price_currency"]=SUR,
["locked_sell_value"]=0.0,
["firmid"]=NC0011100000}

версия 11.1.0.45
демо сервер.
----------------------------
Что не так?
Робот в виде скрипта индикатора
 
Добрый  день,
Рассказываю, как просто сделать робота в виде скрипта индикатора.
Сначала картинка работы такого робота.


В чем достоинство такого робота по сравнению с роботом на основе колбеков.
Робот значительно проще написать
Он загружается на график торгуемого инструмента,
Если для реализации алгоритма торговли  достаточно встроенных в QUIK индикаторов,
то нет надобности их программировать.
----------------  
Пример варианта основного  фрагмента такого робота:
Код
name="nkbot24"
Settings={["Name"] =name,["line"] ={},["account"]="",["client"]="",["Q"]=1;["wt"]=1000,["short"]=0}
Settings.Nind=0;

paths = "D:/QUIK_SCRIPT/"
package.cpath =package.cpath ..";"..paths.."?.dll";
package.path =package.path..paths.."?.lua;"
fnlog=paths..name..".log"; Log=io.open(fnlog,"w")

loadfile(paths.."nkbot24_func.lua")

function nkbuy(i,f)
---алгоритм покупки
 -- f=cross(1,1,2,1,1);
return f;
end

function nksell(i,f)
--алгоритм продажи
-- f=cross(1,1,2,1,1);
return f;
end

function nobuy(i,f)
--фильтр покупки
return f;
end

function nosell(i,f)
--фильтр продажи
return f;
end

function OnCalculate(i)
   local i1=i-1;
   if i==1 then nkInit(); return end
   if i~=i_ then    getI()   end
   N,torder=order(N);    Q=depo();
   if #t==0 then
--      f,j=cross(1,1,2,1,5); --пересечение двух индикаторов
      if i~=i_ then torg(nkbuysel(i));end
      M=os.clock();
   else
      del_ord(M);
   end
   i_=i;
return M1,M2;
end
Продолжение вероятно следует...
Сдвиговые регистры, циклические массивы. Экономим память
 
Добрый день,
В этой теме я расскажу кратко что такое сдвиговые регистры и циклические массивы.
И покажу как на Lua  экономить память при создании роботов.
----------------------
При торговле на бирже приходит много информации, такой , как новости, результаты сделок, значения индикаторов, например свечей.
эта информация записывается в массивы и в файлы и может составлять очень большой объем.
------------------
Однако, при реальной торговле, для принятия решения, нет надобности не только во всей накопленной информации в файлах, но и порою нужна лишь информация за последние например 60 минут, свечей с интервалом 1 минута.
=================
Чтобы массивы с данными не разбухали до безумных размеров я реализую временное окно,
в пределах которого  храню текущую информацию.
-------------------
Например, храним только 1024 последних отсчета.
Для этого необходимо выделить массив всего в 1024 элемента.
Для каждого нового отсчета необходимо сдвинуть содержимое массив влево на один отсчет,
а в освободившейся место записать принятое значение.
--------------------
Возникает вопрос как реализовать этот сдвиг элементов массива, чтобы было быстро.
---------------------
Один из приемов - циклические массивы.
-------------------
В таком массиве элементы не двигаются, а двигается указатель на место удаляемого первого элемента .
Это же место является местом размещения принятого элемента.
---------------
Еще одним способом является использование многобитовых регистров процессора, с помощью которых можно реализовать многобитовые сдвиги данных за одну операцию.
===================
В луа есть операции сдвига >>m (<<m).
Они позволяют сдвинуть целое число на m разрядов влево ( вправо), что соответствует делению(умножению) этого числа на 2 в степени m.
Такая операция сдвига числа выполняется в регистре сдвига  ( в процессоре это АЛУ+регистры)
------------------
В современных процессорах Intel есть регистры в 256 бит (в последних 512 бит)
------------------------------
Так как число double занимает 64 бита, а long(integer в lua) 32 бита,
то с помощью этих регистров можно сдвигать не одно число, а массив из 4,8,16 чисел одной командой.
Для простоты будем называть эти регистры 256(512) ,битовыми тоже сдвиговыми регистрами.
------------------
Очевидно, что с помощью этих регистров можно сдвигать массивы чисел.
=======================
Если не использовать С for lua,
то в скрипте на луа можно реализовать два способа работы с такими временными окнами.
------------------------------
Либо циклический массив,
либо сдвиг элементов массива.
--------------------------------------
Так как данный ликбез в основном для начинающих,
то покажу наиболее простой способ, но при этом достаточно быстродействующий.
-------------------------------
Вот скрипт функций, которые реализуют механизм такого временного окна данных,
где N - размер временного окна
Код
local function newCA(N) local t={}; for j=1,N do t[j]=0; end; return t; end --вставка нового элемента
local function setCA(t,X) table.remove(t,1); t[#t+1]=X;  end --вставка нового элемента

Посмотрим, что сохраняется в таком массиве
Организуем цикл записи номеров отсчетов которые изменяются от 1 до M
и какие из отсчетов будут сохраняться в массиве фиксированной длины 32 элемента
Код
local M=1000000
local t=newCA(32)
for j=1,M do setCA(t,j)
print("j="..j..",t="..table.concat(t,","));
end
это содержимое массива на каждом цикле
Код
>D:/lua53/lua53.exe -e "io.stdout:setvbuf 'no'" "test_lines.lua" 
j=1,t=0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
j=2,t=0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2
j=3,t=0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3
j=4,t=0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4
j=5,t=0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5
j=6,t=0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6
j=7,t=0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7
j=8,t=0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8
j=9,t=0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9
j=10,t=0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,10
j=11,t=0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,11
j=12,t=0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,11,12
j=13,t=0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13
j=14,t=0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14
j=15,t=0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
j=16,t=0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16
j=17,t=0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17
j=18,t=0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18
j=19,t=0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19
j=20,t=0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20
j=21,t=0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21
j=22,t=0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22
j=23,t=0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23
j=24,t=0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24
j=25,t=0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25
j=26,t=0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26
j=27,t=0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27
j=28,t=0,0,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28
j=29,t=0,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29
j=30,t=0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30
j=31,t=0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31
j=32,t=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32
j=33,t=2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33
j=34,t=3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34
j=35,t=4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35
j=36,t=5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36
j=37,t=6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37
j=38,t=7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38
j=39,t=8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39
j=40,t=9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40
j=41,t=10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41
j=42,t=11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42
j=43,t=12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43
j=44,t=13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44
j=45,t=14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45
j=46,t=15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46
j=47,t=16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47
j=48,t=17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48
j=49,t=18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49
j=50,t=19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50
j=51,t=20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51
j=52,t=21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52
j=53,t=22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53
j=54,t=23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54
j=55,t=24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55
j=56,t=25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56
j=57,t=26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57
j=58,t=27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58
j=59,t=28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59
j=60,t=29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60
j=61,t=30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61
j=62,t=31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62
j=63,t=32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63
j=64,t=33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64
j=65,t=34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65
j=66,t=35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66
j=67,t=36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67
j=68,t=37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68
j=69,t=38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69
j=70,t=39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70
j=71,t=40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71
j=72,t=41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72
j=73,t=42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73
j=74,t=43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74
j=75,t=44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75
j=76,t=45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76
j=77,t=46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77
j=78,t=47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78
j=79,t=48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79
j=80,t=49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80
j=81,t=50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81
j=82,t=51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82
j=83,t=52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83
j=84,t=53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84
j=85,t=54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85
j=86,t=55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86
j=87,t=56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87
j=88,t=57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88
j=89,t=58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89
j=90,t=59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90
j=91,t=60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91
j=92,t=61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92
j=93,t=62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93
j=94,t=63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94
j=95,t=64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95
j=96,t=65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96
j=97,t=66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97
j=98,t=67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98
j=99,t=68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99
j=100,t=69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100
j=101,t=70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101
j=102,t=71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102
j=103,t=72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103
j=104,t=73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104
j=105,t=74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105
j=106,t=75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106
j=107,t=76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107
j=108,t=77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108
j=109,t=78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109
j=110,t=79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110
j=111,t=80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111
j=112,t=81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112
j=113,t=82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113
j=114,t=83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114
j=115,t=84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115
j=116,t=85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116
j=117,t=86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117

Оценим быстродействие такого метода для массива в 1024 элемента
Код
local M=1000000
local t=newCA(1024)
--nklib.startA();
local tim=os.clock();
for j=1,M do setCA(t,j) end
--local tim=0.1*nklib.stopA()/M
tim=os.clock()-tim
print(1000000.*tim/M.." мкс" )
результат:
Код
>D:/lua53/lua53.exe -e "io.stdout:setvbuf 'no'" "test_lines.lua" 
10.099 мкс
>Exit code: 0

Т .е. на сохранение одного нового элемента в таком массиве затрачивается примерно 10 мкс.
---------------------
Таким образом, с помощью приведенных выше двух простых функций,
Вы можете  управлять расходом оперативной памяти в своем роботе,
исходя из требуемого временного окна обработки поступающих данных.
CalcBuySell. Что не так?
 
Функция выдает нули.  Что не так?
-------------
Тест:
Код
function main()
   while fconnect do
      if getInfoParam("SERVERTIME") then fconnect=2;  end
      while fconnect==2 do
      c="QJSIM"; s="SBER"  client="10326"; acc="NL0011100043"; price=275.74;
      qty,com=CalcBuySell(c,s,client,acc,price,true,false);
      local s=c..","..s..","..tostring(client)..","..tostring(price)..","..tostring(acc)..", qty="..tostring(qty);
      message(s,1);
         sleep(10000); end
   end
end
function OnInit(pfile)    fconnect=isConnected(); end

Результат:

os.sysdate() . Что-то в ней не так..
 
Добрый день,
Вопрос к разработчикам
В документации на библиотеку QLua заявлено, что
os.sysdate() возвращает системное время с точность до микросекунды.
------------------------
Это означает, как я понимаю, что если я получу с помощью этой функции время в двух точках скрипта, то разница даст мне время исполнения этого участка с точностью до микросекунды.
------------------
Я написал такой тест:
Код
paths = "D:/nkarray/"
package.cpath =paths.."?.dll";
require "nkarray"
event=nkevent.Create("event");
---------------------
name="bot";  -- имя робота
path = "D:/QUIK_SCRIPT/nk_bot/"   --папка где разместим лог файл
Log=io.open(path..name..".log","w")   -- создаем лог файл для записи
------------
_N=0; _tN={};
----------------------
function main()
-----------------------
   while fconnect do
      if getInfoParam("SERVERTIME") then    fconnect=2;  end
------------------------------
      while fconnect==2 do
      w=nkevent.wait(event); --ждем события
         while _N>0 do
            t=_tN[_N]; _N=_N-1
   ----------------------
            tim2=0.1*nklib.stopA();
            T=os.sysdate();
            local _,_,_,t3=nkvm.D(); --HMS,YMD,dHMS,dt,ns
            t1=60.*(60.*T.hour+T.min)+T.sec+0.001*(T.ms+0.001*T.mcs);
            local x1=1000000.*(t1-t[1])//1;
            local x2=1000000.*(t3-t[2])//1;
            Log:write("os.sysdate OnParam(сек)="..t[1]..", os.sysdate main(сек)="..t1..",разность 1(мкс)=="..(t1-t[1]).."\n");Log:flush();
            Log:write("nkvm.D OnParam(мкс)="..t[2]..", nkvm.D main(мкс)="..t3..", разность 2(мкс)="..(t3-t[2]).."\n");Log:flush();
            Log:write("разность 3 по высокоточному таймеру OC(мкс)="..tim2.."\n\n");Log:flush();
         end
      end

   end
end
----------------------------
function OnInit(pfile)    fconnect=isConnected(); end
----------------
function OnParam(c,s)
local T=os.sysdate(); local tim=60.*(60.*T.hour+T.min)+T.sec+0.001*(T.ms+0.001*T.mcs)
nklib.startA();   local _,_,_,tim1=nkvm.D();    _N=_N+1; _tN[_N]={tim,tim1};
nkevent.Set(event);
end
В котором я замеряю системное время в колбеке on Param  в строке
Код
local T=os.sysdate(); local tim=60.*(60.*T.hour+T.min)+T.sec+0.001*(T.ms+0.001*T.mcs)

и передаю его в функцию main
в функции main я снова получаю системное время в строках
Код
T=os.sysdate();

t1=60.*(60.*T.hour+T.min)+T.sec+0.001*(T.ms+0.001*T.mcs);

вычисляю разность этих показаний в строке
Код
local x1=1000000.*(t1-t[1])//1;
и все три значения вывожу в лог файл, который покажу ниже.
----------------------
кроме того, для сравнения я делаю тоже самое на основе собственной функции времени а также своего таймера который реализован на высокоточном таймере процессора.  Но это так, чтобы показать, что действительность не такая, как показывает ваша функция.
и вот результат :
Код
os.sysdate OnParam(сек)=78115.93613, os.sysdate main(сек)=78115.93613,разность 1(мкс)==0.0
nkvm.D OnParam(мкс)=78114968.3296, nkvm.D main(мкс)=78114968.3932, разность 2(мкс)=0.063599988818169
разность 3 по высокоточному таймеру OC(мкс)=59.8

os.sysdate OnParam(сек)=78115.998828, os.sysdate main(сек)=78115.998828,разность 1(мкс)==0.0
nkvm.D OnParam(мкс)=78114999.9583, nkvm.D main(мкс)=78115000.0045, разность 2(мкс)=0.046200007200241
разность 3 по высокоточному таймеру OC(мкс)=30.3

os.sysdate OnParam(сек)=78115.870038, os.sysdate main(сек)=78115.870038,разность 1(мкс)==0.0
nkvm.D OnParam(мкс)=78115435.1791, nkvm.D main(мкс)=78115435.2126, разность 2(мкс)=0.033499985933304
разность 3 по высокоточному таймеру OC(мкс)=24.3
На основе Вашей функции разность показаний равна НУЛЮ.
Мои функции показывают разность от 63 до 24 мкс, что более соответствует реальному процессу,
так как процессор у меня далеко не квантовый.
--------------------
Вопрос:
Что не так с вашей функцией os.sysdate() ?
Очередь -элементарно и полезно, Как сделать очередь в роботе и зачем.
 
Добрый день,
Хочу поделиться некоторыми приемами, которые я использую при построении своих роботов.
См. тему -мой робот.
-----------------
В структуре спинного мозга робота , реализуемого в QUIK, условно можно выделить колбеки,
в которые приходят сообщения о событиях и функцию main,
работающую в отдельном потоке, которая обрабатывает эти события.
-------------------
Как правило, в  main делается бесконечный цикл, в котором и осуществляется обработка.
------------------------
Если обрабатывать нечего, то рекомендуют ставить sleep(time) , где time - число миллисекундах,
на которое Вы заморозите работу main.
===============
Но проблема в том, что пока Main не работает, в колбеки поступают события ,
которые надо обрабатывать либо как-то сохранить иначе они потеряются.
------------------------------
Если обрабатывать события  в колбеках, то на время обработки будет остановлен терминал QUIK, так как колбеки работают в основном потоке термина.
------------------
Проблема решается путем сохранения сообщений из колбеков в массиве,
из которого потом main сможет обработать все сохраненные сообщения.
Такой список (массив,таблица и т д) сообщений называется очередью.
===================
Вопрос лишь в том, как организовать эту очередь , чтобы было просто и быстро.
---------------
Есть несколько вариантов,
------------
Вариант 1: классический - это сделать универсальные списки, очереди. Алгоритмов и их реализаций много можно найти в интернете.
Сложно, малопонятно не спецам . Большая нагрузка на сборщик мусора, что замедляет исполнение скрипта.
--------------------
Вариант 2: -рекомендуемый  в документации QLUA - использовать потоко безопасные функции записи и удаления из массива.
Просто, но относительно медленно.
-------------------
Вариант 3:   это мой, тот который я расскажу далее. просто и быстро.
Объяснять буду на рабочем примере.
-------------------
Продолжение следует...

 
Прикольно: Lua5.4 медленнее Lua5.3
 
Добрый день,
Тестил скорость питона, луа и jit и решил посмотреть, как ускорит Lua5.4 по сравнению 5.3.
--------------------
Раньше было быстрее, да и интернет говорит об этом же.
Выкладывал тест на форуме.
------------
Но получился прикол.
На этом тесте оказалось наоборот
Вот этот testSM.lua
Код
local V={}
local t=os.clock();
local N=256;
local y=0.;
local A=100.
local P=128
local W=2*3.14/N
for i=1,10000000 do
   y=A*math.sin(W*i);
end
local t1=os.clock()
print("time="..t1-t,"y="..y);

результат:
Код
>D:/lua54/lua54.exe -e "io.stdout:setvbuf 'no'" "testSM.lua" 
time=0.74   y=-94.501629942958
>Exit code: 0

>D:/lua53/lua53.exe -e "io.stdout:setvbuf 'no'" "testSM.lua" 
time=0.597   y=-94.501629942958
>Exit code: 0
Кто сможет объяснить?
Cкорость обмена данными через файлы
 
Добрый день,
Эта тема в основном для начинающих строителей роботов.
--------------------------
На вопрос  как сохранить или как передать данные в другой скрипт и приложение,
я рекомендую начать с обмена через файлы.
--------------------
Как правило в ответ получаю - через файлы - это медленно.
На вопрос -откуда Вы это знаете -обычно ответа нет.
----------------
Аналогичный вопрос возникает при попытке передать данные из одного приложения в другое.
---------------
Тем кто,  знает С for Lua, рекомендую mapping files, как самый универсальный и быстрый способ обмена,
если Вас не устраивает обычный обмен через файлы.
---------------
В этой теме я покажу как "медленно" реализуется обмен через файлы.
===============
Тест обмена через файлы в одном приложении.
-------------------
Написал вот такой тест:
Код
pD ="D:/QUIK_SCRIPT/nk_bot/Data/"
fn=pD..name..".log";  Log=io.open(fn,"w");
pDA ="D:/QUIK_SCRIPT/nk_bot/DataA/"
fnA=pDA..name..".log"; LogA=io.open(fnA,"w");
--------------------
local nF=nkevent.ccf(fn);
local nFA=nkevent.ccf(fnA);
local _,_,dHMS1=nkvm.D();
for j=1,100 do
     local _,_,dHMS=nkvm.D(); d=(1000000.*(dHMS-dHMS1))//1;
    Log:write(j..","..dHMS..","..d.."\n");Log:flush();
    while true do
   if nkevent.wcf(nF) then  dHMS1=dHMS; local  C=Log; Log=LogA; LogA=C; local x=nF; nF=nFA; nFA=x  break; end
   end
end
Что он делает?
Создаем на диске два каталога Data и DataA до запуска скрипта.
Скрипт открывает  в каждом из каталогов файл test.log.
-------------------
Далее в цикле 100 раз производится
запись с нечетным j в файл в Каталоге Data.
При обнаружении записи в файл , производим запись в файл в каталоге DataA по четным значениям j.
------------------
Таким образом, в файл каталога Data записываются ответы на запись в файл каталога DataA и наоборот.
---------------------
Каждая запись содержит значения j, текущее время и  задержку обнаружения записи в очередной файл.

Результат  Data/test.log:
Код
1,151047.6863891,790.0
3,151047.6865335,61.0
5,151047.6865586,10.0
7,151047.6865764,8.0
9,151047.6865931,8.0
11,151047.6866097,8.0
13,151047.6866333,15.0
15,151047.6866505,8.0
17,151047.6866669,8.0
19,151047.686683,8.0
21,151047.6866992,8.0
23,151047.6867155,8.0
25,151047.6867317,8.0
27,151047.6867478,8.0
29,151047.6867637,7.0
31,151047.6867809,8.0
33,151047.6867971,8.0
35,151047.6868131,8.0
37,151047.6868292,8.0
39,151047.6868453,8.0
41,151047.6868614,8.0
43,151047.6868775,8.0
45,151047.6868937,8.0
47,151047.6869098,8.0
49,151047.686926,8.0
51,151047.6869421,8.0
53,151047.6869583,8.0
55,151047.6869748,8.0
57,151047.6869909,8.0
59,151047.6870071,8.0
61,151047.687025,8.0
63,151047.6870415,8.0
65,151047.687059,8.0
67,151047.6870752,8.0
69,151047.6870911,8.0
71,151047.6871073,8.0
73,151047.6871234,8.0
75,151047.6871394,8.0
77,151047.6871554,8.0
79,151047.6871715,8.0
81,151047.6871876,8.0
83,151047.6872036,8.0
85,151047.6872198,8.0
87,151047.687236,8.0
89,151047.6872521,8.0
91,151047.6872683,8.0
93,151047.6872844,8.0
95,151047.6873004,8.0
97,151047.6873165,8.0
99,151047.6873325,8.0
Результат  DataA/test.log:
Код
2,151047.6864724,83.0
4,151047.6865484,14.0
6,151047.6865676,9.0
8,151047.6865849,8.0
10,151047.6866013,8.0
12,151047.6866179,8.0
14,151047.686642,8.0
16,151047.6866586,8.0
18,151047.6866749,8.0
20,151047.6866911,8.0
22,151047.6867072,7.0
24,151047.6867237,8.0
26,151047.6867397,8.0
28,151047.6867558,8.0
30,151047.6867727,8.0
32,151047.686789,8.0
34,151047.686805,7.0
36,151047.6868212,8.0
38,151047.6868372,7.0
40,151047.6868533,8.0
42,151047.6868695,8.0
44,151047.6868856,8.0
46,151047.6869017,8.0
48,151047.6869179,8.0
50,151047.686934,8.0
52,151047.6869502,8.0
54,151047.6869665,8.0
56,151047.6869828,8.0
58,151047.686999,8.0
60,151047.6870167,9.0
62,151047.6870333,8.0
64,151047.6870509,9.0
66,151047.687067,8.0
68,151047.6870831,7.0
70,151047.6870991,8.0
72,151047.6871153,8.0
74,151047.6871314,7.0
76,151047.6871474,8.0
78,151047.6871635,8.0
80,151047.6871795,8.0
82,151047.6871956,8.0
84,151047.6872116,7.0
86,151047.6872278,8.0
88,151047.687244,8.0
90,151047.68726,7.0
92,151047.6872763,8.0
94,151047.6872924,8.0
96,151047.6873085,8.0
98,151047.6873245,8.0
100,151047.6873405,8.0
Самое смешное то ,
что задержка измеряется в мкс
и составляет в среднем не более  10 . т.е. 0.000001 сек.
-------------------------
Это медленно?  
Запаздывание тиков
 
Добрый день,
Вопрос к разработчикам.
Можете объяснить, почему на учебном сервере тики приходят с запаздыванием от 500 до 1700 ms.
При этом задержка обмена по интернет не более 30 ms.
Задержка обработка колбека не более 0.1 ms
Вот результаты теста
строки с первым числом 2 - это обработка колбека onAllTrade.
Последнее число в строке(zT) - это задержка в ms
Я понимаю, что это учебный сервер, но у всего есть причина.
Хотелось бы понять и простить.
Код
4; 0.2, 22.6,AMEZ, 108,Ntpm=0
2,1.4; 163; MTLR,zT=712.0
2,0.2; 37; SBER,zT=712.0
2,0.1; 56; NKNC,zT=712.0
2,0.1; 27; MTSS,zT=712.0
2,0.1; 42; MTSS,zT=712.0
2,0.1; 24; MTSS,zT=712.0
2,0.1; 42; KAZT,zT=712.0
2,0.1; 31; VSMO,zT=712.0
2,0.1; 22; VSMO,zT=712.0
2,0.2; 25; TCSG,zT=1712.0
2,0.1; 20; TCSG,zT=1712.0
2,0.1; 26; TCSG,zT=1712.0
2,0.1; 30; TCSG,zT=1712.0
2,0.2; 23; TCSG,zT=1712.0
2,0.1; 24; MTLR,zT=1712.0
2,0.1; 34; SPBE,zT=1712.0
2,0.2; 41; SPBE,zT=1711.0
2,0.1; 25; SPBE,zT=1711.0
2,0.2; 32; SPBE,zT=1711.0
2,0.1; 41; BSPB,zT=1711.0
2,0.1; 25; BSPB,zT=1711.0
14; 0.2, 260.5,VSMO, 108,Ntpm=12
14; 0.2, 24.0,VKCO, 108,Ntpm=11
14; 0.2, 18.4,TCSG, 108,Ntpm=10
14; 0.2, 27.1,SPBE, 108,Ntpm=9
14; 0.1, 22.7,SGZH, 108,Ntpm=8
14; 0.2, 15.5,SBER, 108,Ntpm=7
14; 0.2, 15.3,ROSN, 108,Ntpm=6
14; 0.2, 154658.2,NKNC, 109,Ntpm=5
14; 0.4, 23.9,MTSS, 109,Ntpm=4
14; 0.3, 110.0,MTLR, 109,Ntpm=3
14; 0.2, 21.5,KMAZ, 109,Ntpm=2
14; 0.1, 150429.8,KAZT, 110,Ntpm=1
14; 0.4, 29.6,BSPB, 110,Ntpm=0
2,1.2; 179; SBER,zT=777.0
2,0.2; 30; SBER,zT=777.0
2,0.2; 23; SBER,zT=777.0
2,0.2; 23; SBER,zT=777.0
2,0.1; 23; SBER,zT=777.0
2,0.1; 21; SBER,zT=777.0
2,0.1; 22; SBER,zT=777.0
2,0.1; 24; SBER,zT=777.0
2,0.1; 27; SBER,zT=777.0
2,0.2; 44; SBER,zT=776.0
2,0.1; 22; SBER,zT=776.0
2,0.2; 21; SBER,zT=776.0
2,0.2; 22; SBER,zT=776.0
2,0.2; 22; SBER,zT=776.0
2,0.1; 22; SBER,zT=776.0
2,0.1; 19; SBER,zT=776.0
2,0.2; 20; SBER,zT=776.0
2,0.1; 22; SBER,zT=776.0
2,0.1; 21; SBER,zT=776.0
2,0.1; 38; SBER,zT=776.0
Тест времени подключения источников данных
 
Добрый день,
По просьбе разработчиков
https://forum.quik.ru/messages/forum10/message73569/topic8440/#message73569
выкладываю для общего пользования
свой тест измерения времени подключения источников данных.
Так как ранее использовался очень большой скрипт,
то пришлось написать специально тест для общего пользования.
-------------------
В тесте используется два таймера.
Один - мой на основе высокоточного счетчика OC на СИ. Выкладывал его на форуме.  Его квант 0.1мкс.
Второй - на основе socket. Для исключения сомнения в измерениях. Его квант 1 мс.
-------------------
Начинающие писатели роботов, можете позаимствовать мое решение организации очереди.
Код
--тест скорости подключения источников данных -автор nikolz
name="testnk"
paths = "D:/nkarray/"
package.cpath =paths.."?.dll";
require "nkarray"
p2 = "D:/luasocket/"
package.cpath =package.cpath ..";"..p2.."?.dll";
package.path =package.path..p2.."?.lua;"
socket = require("socket")
path = "D:\\QUIK_SCRIPT\\nk_bot\\"
Log=io.open(path..name..".log","w")
Ntp=0;    tp={}
local ds_int={INTERVAL_M1,INTERVAL_M5,INTERVAL_M30,INTERVAL_TICK};
function main()
   local t,int,tms,t1;
     while true do
      while Ntp>0 do
         t=tp[Ntp]; Ntp=Ntp-1 clas=t[1] sec=t[2]
         for i=1,#ds_int do ds={}
            t2=socket.gettime()*1000.
            nklib.startB();
            int=ds_int[i];
            local d,err; while d==nil do d,err=CreateDataSource(clas,sec,int); end
            d:SetEmptyCallback();
            t1=0.01*nklib.stopB();
            tms=(socket.gettime()*1000.-t2)//1
            Log:write("interval="..int..",sec="..tostring(sec)..",tnk="..t1.."мкс, tsocet="..(tms).."мc\n");Log:flush();
         end
      end
      sleep(1);
   end
end

function OnInit(pfile)  fconnect=isConnected(); end
function OnParam(c,s) Ntp=Ntp+1;    tp[Ntp]={c,s}; end
Это результаты работы теста на моем компе:
Код
interval=1,sec=VTBR,tnk=39.41мкс, tsocet=0.0мc
interval=5,sec=VTBR,tnk=20.17мкс, tsocet=0.0мc
interval=30,sec=VTBR,tnk=17.82мкс, tsocet=0.0мc
interval=0,sec=VTBR,tnk=13072.46мкс, tsocet=130.0мc

interval=1,sec=VSMO,tnk=57.81мкс, tsocet=0.0мc
interval=5,sec=VSMO,tnk=21.82мкс, tsocet=0.0мc
interval=30,sec=VSMO,tnk=21.73мкс, tsocet=0.0мc
interval=0,sec=VSMO,tnk=13581.32мкс, tsocet=135.0мc

interval=1,sec=UGLD,tnk=57.16мкс, tsocet=0.0мc
interval=5,sec=UGLD,tnk=25.99мкс, tsocet=0.0мc
interval=30,sec=UGLD,tnk=26.66мкс, tsocet=1.0мc
interval=0,sec=UGLD,tnk=12974.53мкс, tsocet=128.0мc

interval=1,sec=NMTP,tnk=57.63мкс, tsocet=0.0мc
interval=5,sec=NMTP,tnk=19.32мкс, tsocet=0.0мc
interval=30,sec=NMTP,tnk=17.54мкс, tsocet=0.0мc
interval=0,sec=NMTP,tnk=12912.37мкс, tsocet=129.0мc

interval=1,sec=VRSB,tnk=35.37мкс, tsocet=0.0мc
interval=5,sec=VRSB,tnk=27.25мкс, tsocet=0.0мc
interval=30,sec=VRSB,tnk=21.7мкс, tsocet=0.0мc
interval=0,sec=VRSB,tnk=12604.62мкс, tsocet=125.0мc

interval=1,sec=SIBN,tnk=34.2мкс, tsocet=0.0мc
interval=5,sec=SIBN,tnk=43.41мкс, tsocet=0.0мc
interval=30,sec=SIBN,tnk=18.91мкс, tsocet=0.0мc
interval=0,sec=SIBN,tnk=12793.29мкс, tsocet=127.0мc

Время подключения источников с интервалом 1,5,30 минут  составляет 30 мкс.
Время подключения тиков 12900 мкс. замедление в 400 раз.
==================
Демо сервер КВИК.
версия КВИК 11.1.0.45
Lua таблицу в файл и обратно
 
Преобразование таблицы Lua в строку, запись в файл и загрузка таблицы из файла в скрипт.
Код
function value2text(t,s)  --преобразование таблицы в скрипт
   local s1=""; --новое значение
   local n=string.len(s); local z=string.sub(s,n);
   local m= type(t);
   if m=="string" then
      s1='"'..tostring(t)..'"';  elseif m=="number" then s1=tonumber(t);  elseif t==nil then s1="nil";
   elseif m=="table" then local f;
      for j,v in pairs(t) do
         local x=v;
         if f then s1=s1.."," end  f=1;
         if  type(j)~="number" then    s1=s1..'\n["'..tostring(j)..'"]='; end
         s1=value2text(x,s1);
      end
      if z=='}' then s1='\n{'..s1..'}'; else s1='{'..s1..'}' end
   end
return s..s1;
end

--------------------  это пример вывода и загрузки с распечаткой значений из таблиц
local t2={6,7,8,9}
local t={1,2,3,4,5,"asd",t2}  -- это таблица которую выводим в файл
----------вывод в файл
local fn=p3.."test999.lua"
fLog=io.open(fn,"w"); fLog:write("t1="..value2text(t,"").."\n");fLog:flush()
fLog:close();
-----------ввод из файла
dofile(fn);
----------------прочитали таблицу из файла в таблицу t1
--теперь печатаем из введенной таблицы значения и сравниваем их со значениями в t2 и t
local t3=t1[7]
local s1=t1[6];
print(t1[1],s1,t3[3])

результат:
это содержимое файла test999.lua:
Код
t1={1,2,3,4,5,"asd",{6,7,8,9}}
это печать значений
Код
1   asd   8
Тормоз подключения тиков
 
Добрый день,
Вопрос к разработчикам.
Можете объяснить, почему выполнение функции  
CreateDataSource для тиков выполняется в 700 раз медленнее (у меня за 189000 мкс)
чем для других интервалов (у меня за 270 мкс)
Страницы: 1 2 3 След.
Наверх