Юрий написал: Коллеги! А можно это все как-то в виде примера с кодом увидеть? Нужно получать в реалтайме данные о сделках и подробности по бумаге (шаг цены, стоимость, число знаков и т.д.) во внешней программе на C++ через некий lua скрипт и я никак этому не дам ума так как нет опыта :(
nikolz написал: В таблице запуска скриптов отображается память занимаемая скриптом. Посмотрите как она изменяется. Попробуйте отключить скрипты.
Согласно той таблице, скрипты занимают несколько мегабайт. А согласно таск менеджеру, квик занимает 3 гигабайта. Да в нём и раньше утечки памяти были, но вроде фиксили. Вот опять. Я пытался старую версию из бекапа восстановить, скопировав поверх текущих файлов, но не запустилось. Какая-то ошибка.
я три раза пытался ставить версию 9 но снес и работаю на 8.7 Но то что у Вас 3 ГБ это не проблема версии. посмотрите сколько у Вас выбрано инструментов и параметров в заказе данных. При смене версий установки могут встать по умолчанию. еще в настройках уберите восстанавливать пропущенные данные, если установлено.
nikolz написал: Возможно, это не утечка. В зависимости от настройки может сохранятся или нет история параметров и ТТП для построения индикаторов. Если история параметров сохраняется, то и затраты памяти растут.
Но у меня же нет никакой активности, кроме скриптов lua. В том числе никаких индикаторов. Вообще никаких таблиц и графиков не открыто. Если бы я каждую секунду менял настройки, то можно было бы понять гигабайт истории параметров. А так - навряд ли. Да и на предыдущей версии такого не было.
В таблице запуска скриптов отображается память занимаемая скриптом. Посмотрите как она изменяется. Попробуйте отключить скрипты.
У меня последняя версия quik (открытие) 10.0.1.18. При работе медленно растёт объём используемой памяти. Только вчера перезапускал (примерно 23 часа назад), и уже Task Manager показывает, что quik занимает 1945 MB. За несколько минут число вырастает на несколько мегабайт. Перезапустил, теперь quik потребляет всего 492 мегабайта. Такого не было на последней версии на дату 24.12.2022. После этого не обновлял до 16.04.2023, всё было хорошо - quik мог работать неделю без сильного роста используемой памяти. Как обновил, а потом ещё раз 18.04.2023, так пошли утечки. У меня постоянно запущены скрипты lua, кроме этого никакой активности.
Хотелось бы, чтобы устранили утечки памяти. Спасибо.
Возможно, это не утечка. В зависимости от настройки может сохранятся или нет история параметров и ТТП для построения индикаторов. Если история параметров сохраняется, то и затраты памяти растут.
Вам достаточно информации, что объяснить по данным Вашего демо сервера: ----------------------------- 1) повторение обезличенных сделок в onAllTrade ---------------------------------- 2) запаздывание прихода обезличенных сделок до 60 секунд по ликвидному инструменту SBER.
в итоге имеем это: 229:156066>64821,89358,916,70,5,18,2,11,3,3,7,11,7,9,22,6,23,13,4,13,30,23,16,10,1,6,8,4,25,8,9,11,41,47,1,18,43,10,4,10,4,9,13,6,22,9,4,15,22,7,44,13,10,3,22,2,2,4,6,10,7,6,3,2,2,10,1,2,1,4,8,6,
анализ результата: ---------------------- 1-я сделка 26361,SBER,num=4781728079,size=57343,HMS=26306.0,dt=55.0,n=0,m=56,clock=2.4609999999998 ------------------------------ последняя сделка 26361,SBER,num=4781729267,size=57604,HMS=26358.0,dt=3.0,n=0,m=4,clock=2.4740000000002 --------------------- Первое число 26361 - это время компьютера в секундах. Оно не изменилось ------------------------- Последнее число - это os.clock в секундах изменяется от 2.461 до 2.474 т е на 13 миллисекунд. ---------------------- HMS - время сделок в секундах изменилось от 26306 до 26358 т е на 52 секунды ---------------------- Таким образом , запаздывание прихода сделок самого ликвидного инструмента составило 52 секунду. ----------------------------------------- Причем, сделки почти за минуту получили за 13 миллисекунд ------------------------------ Все верно? ----------------------------- Можете объяснить?
Даниил Волошин написал: Нужен также номер сделки, по которому можно её отследить на всех этапах её следования.
Обнаружил, что в колбек onAllTrade сделки прилетают повторно!!!! ------------------- Написал для этого такой тест:
Код
local ds={}
local count=0;
function OnParam(c,s)
local z=ds[c..s] if z==nil then d,err=CreateDataSource (c,s,INTERVAL_TICK); if d then d:SetEmptyCallback(); ds[c..s]={d,0,0}; end end
end
function OnAllTrade(t)
count=count+1;
local c,s=t.class_code,t.sec_code; local z=ds[c..s]; local num=t.trade_num;
if z then
if z[2]==num then
Log:write(os.date()..","..tostring(s)..",num="..tostring(num)..","..tostring(count)..",повторение "..tostring(z[3]) .."\n"); Log:flush();
else
Log:write(os.date()..","..tostring(s)..",num="..tostring(num)..","..tostring(count).."\n"); Log:flush();
end
z[2]=num; z[3]=count;
end
end
function OnInit(pfile) local path = getScriptPath(); Log=io.open(path.."/test.log","w") end
function main() while true do sleep(1000); end end
Для того, чтобы можно было провести анализ, нам необходимо знать номер сделки, которая пришла с запозданием, время её исполнения и время её появления на Вашем терминале. Потому просим Вас привести примеры в указанном формате, это позволит нам начать разбор Вашей ситуации.
сделал тест с автоподстройкой времени выкладываю скрипт теста
Код
local tmp={}
local ds={}
local ns=0;
local shH=1 --сдвиг часового пояса
local shS=0 -- сдвиг секунд
local count,count1=0,0; local sts={} ;-- for i=1,100 do sts[i]=0; end
function main()
while true do
-- nkevent.wait(event); --ждем события
while #tmp>1 do
local t=tmp[1]; table.sremove(tmp,1);
if count>=1000 then count=0;
local s=""; for i=1,100 do if sts[i] then s=s..tostring(sts[i])..","; end end
Log:write(tostring(ns)..":"..tostring(count1)..">"..s.."\n"); Log:flush();
end
end
sleep(1);
end
end
function OnParam(c,s)
local z=ds[c..s]
if z==nil then
d,err=CreateDataSource (c,s,INTERVAL_TICK);
if d then d:SetEmptyCallback(); ns=ns+1; ds[c..s]={d,0,0}; end
else
table.sinsert(tmp,{1,c,s}); --nkevent.Set(event);
end
end
function OnAllTrade(t)
local c,s=t.class_code,t.sec_code; local z=ds[c..s];
if z then local d=z[1]; local n=z[2]; local f=z[3];
local Ti=t.datetime; local HMS=(60*(60*Ti.hour+Ti.min)+Ti.sec)+0.001*Ti.ms;
local D=os.date("*t"); local hms=60*(60*(D.hour-shH)+D.min)+D.sec-shS;
local dt= hms-HMS+n;
local size=d:Size();
local T1=d:T(size); local HMS1=(60*(60*T1.hour+T1.min)+T1.sec)+0.001*T1.ms;
-- if 0>dt then dt=0 end
if f==0 then
if 0>=dt then f=1 z[3]=f end
end
if f~=0 and HMS==HMS1 then
-- if 60>dt then
if 0>dt then
if -1>=dt then
local n1=math.floor(0-dt) dt=dt+n1 n=n+n1;
if n>100 then n=0; z[3]=0; dt=0; end
z[2]=n
end
end
-- Log:write(tostring(hms)..","..tostring(s)..",size="..tostring(size)..",HMS="..tostring(HMS)..",dt="..tostring(dt)..",n="..tostring(n).."\n"); Log:flush();
if f~=0 then
local dt1=dt; if 0>dt then dt=0 end count=count+1; count1=count1+1;
local m=math.floor(dt)+1;
if m==nil or sts[m]==nil then
Log:write(tostring(hms)..","..tostring(s)..",size="..tostring(size)..",HMS="..tostring(HMS)..",HMS1="..tostring(HMS1)..",dt="..tostring(dt1)..",n="..tostring(n)..",m="..tostring(m).."\n"); Log:flush();
end
-- if m and 99>m then
if sts[m] then sts[m]=sts[m]+1; else sts[m]=1 end
-- end
end
end
end
end
function OnInit(pfile)
local path = getScriptPath(); Log=io.open(path.."/test.log","w") --лог файл
end
Так как Вам лень запускать его на вашем демо сервере, то выкладываю последние результаты На печать выводится сделка, которая первая с данной задержкой. Время компьютера, код инструмента, size, время этой сделки, время сделки но номеру size, разница времен, автосмещение, индекс ячейки (запаздывание sec+1)
думал что ошибка в тесте, написал новый , но лучше не стало. в тесте надо установить смещение часового пояса и секунд
Код
local tmp={}
local ds={}
local ns=0;
local shH=1 --сдвиг часового пояса
local shS=10 -- сдвиг секунд
local count,count1=0,0; local sts={} for i=1,200 do sts[i]=0; end
function main()
while true do
while #tmp>0 do
local t=tmp[1]; table.sremove(tmp,1);
if count>=1000 then count=0;
local s=""; for i=1,60 do s=s..tostring(sts[i])..",";end
Log:write(tostring(ns)..":"..tostring(count1)..">"..s.."\n"); Log:flush();
end
end
sleep(1);
end
end
function OnParam(c,s)
local d=ds[c..s]
if d==nil then
d,err=CreateDataSource (c,s,INTERVAL_TICK);
if d then d:SetEmptyCallback(); ns=ns+1; ds[c..s]=d; end
else
table.sinsert(tmp,{1,c,s});
end
end
function OnAllTrade(t)
local c,s=t.class_code,t.sec_code; local d=ds[c..s];
if d then
local Ti=t.datetime; local HMS=(60*(60*Ti.hour+Ti.min)+Ti.sec);--+0.001*Ti.ms;
local D=os.date("*t"); local hms=60*(60*(D.hour-shH)+D.min)+D.sec-shS;
local dt= hms-HMS; local size=d:Size(); local T1=d:T(size);
local HMS1=(60*(60*T1.hour+T1.min)+T1.sec);--+0.001*T1.ms;
if HMS==HMS1 then
if 0>dt then dt=0 end
if 60>dt then
count=count+1; count1=count1+1; local m=math.floor(dt)+1; sts[m]=sts[m]+1;
end
end
end
end
function OnInit(pfile)
local path = getScriptPath(); Log=io.open(path.."/test.log","w") --лог файл
end
local tmp={}
local ds={}
local ns=0;
local count,count1=0,0; local sts={} for i=1,200 do sts[i]=0; end
function main()
while true do
-- nkevent.wait(event); --ждем события
while #tmp>0 do
local t=tmp[1]; table.sremove(tmp,1);
if count>=100 then count=0;
local s=""; for i=1,60 do s=s..tostring(sts[i])..",";end
Log:write(tostring(ns)..":"..tostring(count1)..">"..s.."\n"); Log:flush();
end
end
sleep(100);
end
end
function OnParam(c,s)
local d=ds[c..s]
if d==nil then
d,err=CreateDataSource (c,s,INTERVAL_TICK);
if d then ds[c..s]=d; d:SetEmptyCallback(); ns=ns+1; end
else
table.sinsert(tmp,{1,c,s});
end
end
function OnAllTrade(t)
local Ti=t.datetime; local HMS=(100*(100*Ti.hour+Ti.min)+Ti.sec)+0.001*Ti.ms;
local hms=string.sub(os.date(),12,19); hms=string.gsub(hms,':','')-10000;
local dt=hms-HMS; if 0>dt then dt=0 end
if 60>dt then
count=count+1; count1=count1+1; local m=math.floor(dt)+1; sts[m]=sts[m]+1;
end
end
function OnInit(pfile)
path = getScriptPath(); Log=io.open(path.."/test.log","w") --лог файл
end
результат помещается в лог файл test.log, который создается в каталоге , где размещается этот скрипт. в лог файл через каждые 100 обезличенных сделок записывается следующая строка:
77 - число инструментов 3554 - число обезличенных сделок далее количество сделок в интервале запаздывания с шагом 1 секунда 79 - в интервале запаздывания до 1 секунды 90 - в интервале запаздывания от 1 до 2 секунд 89 -в интервале запаздывания от 2 до 3 секунд
Назвать конкретную причину такого распределения в Вашей выборке без конкретных примеров и участия брокера не удастся. В данной ситуации замешано большое количество неопределённостей: эпизодические сетевые задержки, ситуативные задержки на сервере в расчете и обработке сделок, возможные задержки в обработке поступающей информации на Вашем ПК, задержки в трансляции данных из ТС на сервер QUIK и из сервера на терминал и т.д.
Для того, чтобы можно было анализировать большие задержки поступления обезличенных сделок необходимы конкретные примеры. Например зафиксировать конкретные номера сделок с временем их исполнения и временем получения их терминалом, далее приложить эти данные и архив терминала сделанный в момент проявления задержек к Вашему обращению в техническую поддержку Вашего брокера, в котором попросить помочь в выяснении причин таких задержек и в случае, если брокер не сможет помочь по данному вопросу, то инициировать его обращение к нам для совместного анализа данной ситуации.
примерно такое же можно наблюдать и на вашем демо сервере. относительно задержек в сети и на компьютере не логично. В сети задержка 30 мс, а на графике задержка десятки секунд Ядро процессора загружено примерно на 10% -------------- Возможно не знаете, но недавно я делал тест на скорость выставления снятие заявок на вашем демо сервере. Полагаю я нго либо положил либо очень нагрузил так как меня отключили. По тестам скорость выставления и снятия заявки без учета прохождения по сети составляет порядка 10-100 мкс. ------------------------- Если у Вас есть возможность, то сделайте подобный тест и покажите результат. -------------------------- Если покажете, что у вас задержка прихода обезличенной сделки через колбек onAllTrade в пределах разумного, то вопрос будет закрыт. -------------------- Я мог бы повторить Ваш тест, так как у сбербанка постоянно какие-то глюки. Например вчера пропал предыдущий торговый день и не вогсстановлися.
Ув, разработчики Просьба объяснить следующий феномен работы системы QUIK ----------------------- На реальном рынке вычисляю функцию распределения запаздывания времени прихода обезличенных сделок в терминал QUIK на моем компе с сервера брокера сбербанк. ---------------------- Алгоритм расчета следующий Вычисляем разницу текущего времени компа и времени обезличенной сделки и в добавляем 1 в ячейку массива с индексом равным разности. В результата по 24 000 обезличенных сделок получаем следующий график распределения запаздывания
Что получилось: 80% пришло с задержкой не более 1 секунды это при пинге до сервера 0.03 сек. 12% с задержкой от 1 до 2 секунд 8% с задержкой более 2 секунд 1% с задержкой 17 секунд 0.5% с задержкой 30 секунд --------------------- Что не так c сервером QUIK у брокера Сбербанк.
К тому же, я незнаю как работает вся эту луашная магия:
Цитата
function unrequire(m) package.loaded[m] = nil _G[m] = nil end
Я вижу тут зануление таблиц. Приводит ли это к выгрузке модулей - неизвестно.
Для этого не надо знать лушную магию . Достаточно знать Сишную и назначение функции DllMain. ---------------------------------- Но, боже упаси Вас, подумать что я Вас заставляю что-то изучать или проводить эксперименты. Не утруждайте себя. Пишите на форум жалобы. Время потратите столько-же, но зато не будете себя утруждать.
Alexander написал: Если имелось ввиду заменить MessageBox на MessageBoxA, так я так уже пробовал. По умолчанию да юникод в свойствах проекта и функция из макроса MessageBox подставляется MessageBoxW, я это знаю. Замена ничего не меняет абсолютно. MessageBox, что один, что другой вызываются из оконной процедуры у меня.
какой IDE используете? Могу посоветовать для написания dll для Lua(QUIK) использовать Pelles C. Очень хороший, простой в настройках, быстрый по сравнению с Visual Studio .
Alexander написал: Попробую поднять данную тему вновь. Вобщем всё что выше написано - не работает Библиотека не выгружается!. Библиотека на C++. Выше писали, что типа если на чистом C++ то выгружается нормально. Не выгружается. Есть ли ещё какой способ выгрузить свою же DLL, которую Lua выгружать почему-то не хочет. Странное вообще какое-то поведение Lua. Скрипт отработал, библиотека - осталась. Функций в Lua для выгрузки не нашёл, что тоже довольно таки странно. Загружать значит можно, выгружать нет. Приходится постоянно перезагружать QUIK, чтобы удалить файл DLL, поскольку система не даёт его удалить, пока библиотека используется Lua. А удалять файл надо, чтобы после перекомпиляции DLL, новый DLL-файл записать на место того, что надо удалить. Это сильно напрягает поскольку сам QUIK грузится не быстро. Сталкивался кто с таким? Как ещё можно решить пролему? Ведь библиотека же чисто моя, зачем она вообще удерживается Lua - не понятно. Закончился скрипт без ошибок - освободи, но нет. Уж не знаю как решить, думаю уже как-то искать ID библиотеки, ну или там хэндл какой и выгружать отдельно программой через API винды.
А причем здесь скрипт? Скрипт - это даже не программа, а все лишь байткод для луа машины. Вспомните, когда dll выгружается.
У меня есть dll на основе API C for Lua Результат будет такой же. Просто сделайте как я Вам написал и увидите результат. Либо измените опции в компиляторе
Alexander написал: nikolz , у Вас что за функции nkcf.defF и rfs ? Какой их код, что они вызывают API винды? И Вы их вызываете прямо из скрипта, а я API прямо из DLL на C.
Это мой аналог библиотеки FFI,, Эти функции позволяют вызывать в луа функции из dll, у которых интерфейс C. любые функции из системных библиотек и сторонних dll нет надобности городить что-то на API C for Lua. Я об это на форуме уже писал. ------------------------- правда я встроил LuaJIT в QUIK и могу использовать и FFI. Тоже об этом писал на форуме.
Alexander написал: Аааа, я ещё что-то сразу то не приметил. nikolz , Вы на скрине показываете окно сообщений самого квика. Мои скрипты в это окно пишут по-русски нормально. Я писал не про это окно. У меня DLL. Скрипт вызывает её функции. Эти функции например вызывают MessageBox виндовую для вызова окна сообщенй винды с русским текстом. И вот оно то пишет не по-русски. Вот в этом проблема. А с простым message в скрипте проблем нет - сохраняю с русскими сообщениями как ANSI и проблем нет. Вобщем сама винда перестаёт по-русски писать в своём же сообщении, хотя если вызывать не из библиотеки DLL под QUIK, а просто из программы под винду, то пишет по-русски как положено. И ещё. Из DLL в этом окне только само сообщение абракадаброй выводится, а вот кнопки "Да", "Нет" - они нормально по-русски подписаны.
У Вас по умолчанию подставляется MessageBoxW а надо прописать явно MessageBoxA ---------------------- Вот ваш вариант с MessageBoxW
Alexander написал: Аааа, я ещё что-то сразу то не приметил. nikolz , Вы на скрине показываете окно сообщений самого квика. Мои скрипты в это окно пишут по-русски нормально. Я писал не про это окно. У меня DLL. Скрипт вызывает её функции. Эти функции например вызывают MessageBox виндовую для вызова окна сообщенй винды с русским текстом. И вот оно то пишет не по-русски. Вот в этом проблема. А с простым message в скрипте проблем нет - сохраняю с русскими сообщениями как ANSI и проблем нет. Вобщем сама винда перестаёт по-русски писать в своём же сообщении, хотя если вызывать не из библиотеки DLL под QUIK, а просто из программы под винду, то пишет по-русски как положено. И ещё. Из DLL в этом окне только само сообщение абракадаброй выводится, а вот кнопки "Да", "Нет" - они нормально по-русски подписаны.
Net error "Удалённый хост принудительно разорвал существующее подключение", Такая ошибка ,как правило, возникает ближе к концу торгов.Подключиться после этой ошибки невозможно в этот день. На пк установлено ещё 2 квика,они при этом работают нормально. Подключение через USB-модем
NPlay написал: Причем если подключаешься по wi-fi (Intel® Wi-Fi 6 AX200 160MHz)он встроен в материнскую плату а сетевую карту отключаешь то никаких проблем, тут же логинится и работает.
На самом деле Вы все уже рассказали и что делать примерно понятно. Но полагаю, что знаете сами. Успехов в творчестве.
Net error "Удалённый хост принудительно разорвал существующее подключение", Такая ошибка ,как правило, возникает ближе к концу торгов.Подключиться после этой ошибки невозможно в этот день. На пк установлено ещё 2 квика,они при этом работают нормально. Подключение через USB-модем
NPlay написал: Автор тебе удалось решить проблему? У меня такие же симптомы при логине в квик происходит разрыв локального соединения и сеть отключается, брандмаузер, антивирь, все отрублено, папка квик в исключениях. Проблема возникает исключительно при коннекте с квиком! сетевая карта I-225v мат плата asus 550b-e gaming. Мучаюсь уже несколько месяцев, так и не смог победить. 1 из 10-15 раз все таки удается залогинится на сервер квика, но при этом приходится включать/выключать сетевое подключение.
сделайте пинг до сервера брокера (в квике есть IP адрес сервера) Если серверов несколько то попробуйте подключится к другому.
да нет никаких потерь, вообще, никаких, проблема исключительно при коннекте квика 10.0.1.18 на сервер брокера( рабочий у них только один (открытие). ни переустановка квика, ни переустановка винды(10) не помогает, все обновления, драйвера на сетевую свежие.
спасибо что почистить кулер не советуете, а то рукалицо.
у вас болезнь другая, поэтому кулер чистить бесполезно
Net error "Удалённый хост принудительно разорвал существующее подключение", Такая ошибка ,как правило, возникает ближе к концу торгов.Подключиться после этой ошибки невозможно в этот день. На пк установлено ещё 2 квика,они при этом работают нормально. Подключение через USB-модем
NPlay написал: Автор тебе удалось решить проблему? У меня такие же симптомы при логине в квик происходит разрыв локального соединения и сеть отключается, брандмаузер, антивирь, все отрублено, папка квик в исключениях. Проблема возникает исключительно при коннекте с квиком! сетевая карта I-225v мат плата asus 550b-e gaming. Мучаюсь уже несколько месяцев, так и не смог победить. 1 из 10-15 раз все таки удается залогинится на сервер квика, но при этом приходится включать/выключать сетевое подключение.
сделайте пинг до сервера брокера (в квике есть IP адрес сервера) Если серверов несколько то попробуйте подключится к другому.
Alexander написал: За столько времени так никто и не ответил. Поддержка может хоть что-нибудь подсказать в решении проблемы? Мой вывод : в контексте толи потока QUIK, толь в Lua, локаль меняется с ru-Ru на локаль C, а в ней видимо русских букв вообще нету. Поэтому хоть что ты пиши, хоть кодируй текст - всё равно толку не будет, так как его попросту в чарактер сет(кодировке) нет как такового. Но почему не получается сначала сохранить локаль C, потом установить родную локаль, вывести текст, потом локаь C вернуть обратно - не пойму.
никогда не было проблемы с русскими буквами. Полагаю кодировка, которая в системе установлена.
Ув.разработчики Просьба пояснить причину систематического запаздывания свечей в следующем тесте. ------------------------ Тест проводится на реальных торгах. Брокер сбербанк ------------------- Были выбраны два инструмента SBER и IRAO Новая свеча выявляется по изменению числа свечей в колбеке источника данных для 1 минутных свечей. Ниже приведены результаты теста а также график запаздывания прихода свечи
Из графиков следует, что максимальное запаздывание прихода 1 минутной свечи SBER с сервера брокера составляет 16 секунд, в среднем 5 секунд. --------------------------------- максимальное запаздывание свечи IRAO составляет 59 секунд. в среднем 25 секунд. ------------------------------ При этом пинг до сервера не более 0.03 секунды. ----------------------------- Можете объяснить такое большое значение запаздывания даже для ликвидного инструмента SBER? Что не так?
Станислав написал: Предположу, что процессор Ryzen, а компьютер вышел из гибернации.
Все гораздо проще оказалось. Я инструменты брал из колбека onParam. А там как известно идут срезы т е не все сделки. Теперь все нормально (почти) Первое число в строке - номер новой свечи данного инструмента
Добрый день, Сделал тест получения свечей с интервалом 1 5 и 30 мин для всех инструментов, которые определены у меня в ТТП В лог файл выводим время открытия новой свечи и время свечей ------------------ Тест исполняем на реальных торгах Брокер Сбербанк. ================= вот результаты в лог файле время местное на 1 час сдвинуто относительно биржевого
Обращаю внимание на следующее: ---------------------- Для инструмента в 1 ой строке минутная свеча сформирована 01 секунду ---------------------------------- Fri Apr 14 12:36:01 2023,sec=MAGN ,T30=123000.0,T5=123500.0,T1=123600.0 ------------------------- а для инструмента в последней строке через 55 секунд после первой. Fri Apr 14 12:36:55 2023,sec=SNGS ,T30=123000.0,T5=123500.0,T1=123600.0 ----------------------------- Чем дальше в таблице инструмент от первой строки тем больше запаздывание. -------------------------------- Что не так?
nikolz написал: Так все же просто в этом случае .Время свечи содержит счетчик тиков. Если счетчик меньше предыдущего то это открытие новой свечи. А предыдущая это последняя закрытая.
Нашел код где выводит время бара, время изменяется при открытии нового бара. Выдает в таком виде, это оно? sTime --1681312260
не время а счетчик тиков см док Функции O, H, L, C, V, T
Функции в качестве параметра принимают индекс свечи и возвращают соответствующее значение. Время свечи возвращается с точностью до миллисекунд в виде таблицы с полями:
Денис написал: Погуглив немного нашел кое-что похожее для определения нового бара. Подправил, сейчас переменная first_candle_index обновляет свой индекс как только появляется новая свеча. Но как это прикрутить для дальнейших вычислений, пока не допер. Тут на форуме нашел вот что, цитирую : SetUpdateCallback при смене индекса даст вам как раз момент открытия новой свечи. Вот как ее прикрутить к функции поиска индекса ниже? Или может есть другие методы какие?
function newbar() ds, error_desc = CreateDataSource("SPBFUT", "SiM3", INTERVAL_M1) local try_count = 0 while ds:Size() == 0 and try_count < 1000 do sleep(100) try_count = try_count + 1 end if error_desc ~= nil and error_desc ~= "" then message("Ошибка получения таблицы свечей:" .. error_desc) return 0 end
local today_day = tonumber(os.date("%m")) local current_candle = ds:Size() local max_candles = math.min(20, ds:Size()) local first_candle_index = nil
while first_candle_index == nil and current_candle > ds:Size() - max_candles do if tonumber(ds:T(current_candle).day) ~= today_day then
first_candle_index = current_candle - 1 end end
return first_candle_index end
Рекомендую начать написание своего робота не в виде скрипта а в виде индикатора. Если будете торговать каким-то конкретным инструментом, то этого вполне достаточно, будет проще сделать работающий. ----------------- Кроме того, рекомендую писать не торговый робот, а торговый советник. Так будет меньше шансов слить свой счет. ----------------- Потом перепишите советник в робота, а затем если захотите большего -возьметесь за скрипты. -------------------- В итоге напишите все быстрее и качественнее.
Так я, если честно, qLua в глаза второй раз вижу, я больше на питоне, амиброкер,... хотел работающего бота перевести на qLua на срочный рынок для попробовать, почти все перевел, уперся в этот блин новый бар (получить его закрытие/открытие, так как расчет баров ведется после закрытия текущего). Собственно qLua - это вопрос разового применения. Хотел из питона сразу в Квик - но увидев что там еще больше прокладок между кодом и биржей - забил на это дело.
Так все же просто в этом случае . Время свечи содержит счетчик тиков. Если счетчик меньше предыдущего то это открытие новой свечи. А предыдущая это последняя закрытая.
Sergey написал: Всем доброго дня и мира! Хочется разработать индикатор для Quik. Кто понимает, поделитесь мнением. Реально ли так сделать на Lua, и как это будет грузить программу? Для наглядности такой пример: 1) Обычно на 4ч таймфрейме две свечи за дневной период. Зеленая свеча с объемом 200 и красная с объемом 50. Перейдя на дневку у меня будет свеча с объемом 250, и не важно какого цвета. 2) я бы хотел получить объем под дневной свечей исходя из условий свеч 4ч-го таймфрейма, т.е. из 200 вычесть 50 (т.к. свеча над 50 красная), и получить 150. По сути мне хотелось бы чтобы индикатор считывал, предположим, минутный таймфрейм, а значения более старших таймфреймов строил путем вычисления значений из этого минутного таймфрейма и выстраивал в накопительную линию. Что-то на подобии индикатора A/D, только чтобы линия отклонялась на сумму объемов минутного таймфрейма.
Все это можно сделать, но скорее всего уже лет сто назад написан индикатор, который нечто подобное отображает. ---------------- Попробуйте изучить смысл индикаторов типа RSI, индикатор Чайкина и др им подобные, обязательно найдете, то что Вам подойдет и встроен в QUIK.
Денис написал: Погуглив немного нашел кое-что похожее для определения нового бара. Подправил, сейчас переменная first_candle_index обновляет свой индекс как только появляется новая свеча. Но как это прикрутить для дальнейших вычислений, пока не допер. Тут на форуме нашел вот что, цитирую : SetUpdateCallback при смене индекса даст вам как раз момент открытия новой свечи. Вот как ее прикрутить к функции поиска индекса ниже? Или может есть другие методы какие?
function newbar() ds, error_desc = CreateDataSource("SPBFUT", "SiM3", INTERVAL_M1) local try_count = 0 while ds:Size() == 0 and try_count < 1000 do sleep(100) try_count = try_count + 1 end if error_desc ~= nil and error_desc ~= "" then message("Ошибка получения таблицы свечей:" .. error_desc) return 0 end
local today_day = tonumber(os.date("%m")) local current_candle = ds:Size() local max_candles = math.min(20, ds:Size()) local first_candle_index = nil
while first_candle_index == nil and current_candle > ds:Size() - max_candles do if tonumber(ds:T(current_candle).day) ~= today_day then
first_candle_index = current_candle - 1 end end
return first_candle_index end
Рекомендую начать написание своего робота не в виде скрипта а в виде индикатора. Если будете торговать каким-то конкретным инструментом, то этого вполне достаточно, будет проще сделать работающий. ----------------- Кроме того, рекомендую писать не торговый робот, а торговый советник. Так будет меньше шансов слить свой счет. ----------------- Потом перепишите советник в робота, а затем если захотите большего -возьметесь за скрипты. -------------------- В итоге напишите все быстрее и качественнее.
Anzhelika Belokur написал: Данная ошибка связана с сетевыми проблемами на стороне клиента (т.е у Вас), рекомендуем попробовать сменить канал для связи или провайдера.
Проблема не с провайдером. Сегодня попробовал через ноутбук на этом же соединении. И проводное и вайфай работают.
На ноутбуке стоит вин 10. Возможно проблема в этом.
Через ноутбук работать не удобно.
Плюс я уже описал обращение к провайдеру. Они проверили и у себя еще у двух провайдеров. Какая-то проблема с сервером сбербанка.
Александр_1976 написал: Здравствуйте! Ожидаю что в течении пары месяцев цена на акцию упадет. Хучу выставить отложенную заявку на покупку по более низкой чем сейчас цене. Есть ли разница в выставлении заявки через "стоп цена по другой бумаге" или через "тейк профит"? Пробовал через стоп лимит, заявка через несколько секунд заявка отклоняется. Как правильно выставить отложенную заявку на покупку по цене ниже рынка?
Вы кандидат на нобелевскую премию. Так как ранее получатели ее доказали, что прогноз с таким горизонтом невозможен.
openbuys - Активные на покупку opense[[s - Активные на продажу
Эти переменные содержат число, а не логическую переменную В них либо ноль либо не ноль, а не TRUE и FALSE -------------------------- Но запускать заново скрипт или main нет надобности в вашем случае.
Тут сорян, я не все написал видимо, то что переменные сравниваются с цифрами это так, я просто потом новую ввожу если ~=0 то запоминаю как TRUE, что есть активная лимитка. По поводу возвращаемых данных есть смысл писать в функции Return? или в LUA в коде можно сразу писать например -- If Buy_Active_Limit == true и т.д.?
function check_active_position () for i = 0,getNumberOf("FUTURES_CLIENT_HOLDING") - 1 do if getItem("FUTURES_CLIENT_HOLDING",i).sec_code == instrument then if getItem("FUTURES_CLIENT_HOLDING",i).openbuys ~= 0 then Buy_Active_Limit = true;
end; end; end; return Buy_Active_Limit end
Ликбез: луа отличается например от СИ тем, что 0 - это не false, а true. Т е все числа - это true. ---------------------- return надо писать если что-то возвращаете из функции. ---------------- Ваш пример лучше написать так:
Код
function check_active_position ()
for i = 0,getNumberOf("FUTURES_CLIENT_HOLDING") - 1 do
local x=getItem("FUTURES_CLIENT_HOLDING",i);
if x.sec_code == instrument then
if x.openbuys ~= 0 then return x.openbuys; end;
end
rnd
end
В этом варианте два момента. 1) работает быстрее так как у Вас три раза ходите в архив, что существенно дольше чем работа с локальной переменной х 2) если x.oprnbus не равен нулю то функция вернет это значение иначе она вернет nil - а это false
Иван__ написал: Примерно с пару недель начала регулярно появляться ошибка при попытки установки связи с сервером:
connection was closed by peer cant get message size from net
Появляется преимущественно в утренние с 09-10 и вечерние после 23-х часы (по крайней мере что я заметил). При обращении в сбер поддержку пиняют на провайдера.
Обратился к провайдеру. Провайдер проверил у себя и у двух других провайдеров (РОСТЕЛЕКОМ, МГТС, БИЛАЙН). Проблема явно с сервером сбера.
Провел трасеровку айпи адреса через командную строку виндовс 2/3 пакетов теряется.
Подскажите как быть. Торговать не возможно. Не получается оставить заявку когда мне это нужно. В поддержке Сбера сообщили что разбираться с заявкой будут месяц.
Как-то можно в медийное поле это вытащить, чтобы они зашевелились??
PS операционка Windows 7
Эта проблема может возникать при использовании устаревших DNS серверов или отключении используемого. Попробуйте обновить кэш DNS.
Денис написал: Похоже не просто будет мне получить информацию о том, что текущая свеча закрылась. Из ответов выше кроме костылей с обработкой времени баров других вариантов нет? В питоне есть candle_close = true or false, в Амиброкере тоже есть свой костыль. Попробовал что-то изобразить, но сессия закончилась. У меня вроде стандартная задача - начинать расчет баров (обычное сравнение Bar-1 и Bar-2), но только когда текущая свеча закрылась. То что после закрытия текущей те бары сдвинуться на 1 - это понятно. Может есть какие варианты с меньшим количеством костылей? Спасибо.
закрытие свечи - это завершение интервала .Простейший алгоритм - синхронизируете ком от сервера точного времени и контролируете завершение текущего интервала времени. --------------------- Но относительно нового бара вы ошибаетесь. Новый бар возникнет не тогда, когда закроется предыдущая свеча, а тогда, когда появится сделка. Т е если сделки в новом интервале нет, то и бара нет.