Daniil Pozdnyakov, по сообщению #179 есть вопросы? Нужно пояснить, что делает скрипт?
После заказа обезличенных сделок скрипт замеряет время получения первых 200000 сделок. После этого скрипт выдаёт замеренное время и отключается. Тест проводится 4 раза: 1) с созданием локальной переменной, содержащей массив нулевого размера 2) с созданием локальной переменной, содержащей двумерный массив 100x1000 3) с подключением библиотеки socket 4) с подключением библиотеки iuplua
Предполагается, что во всех 4-х тестах время работы скрипта должно быть одинаковым, поскольку колбек OnAllTrade во всех тестах выполняет одну и ту же работу: OnAllTrade содержит только три простых оператора, они не должны существенно влиять на время работы функции. В действительности же время работы скрипта много больше в тестах 2, 3, 4 по сравнению с тестом 1. Выводы, вытекающие из теста я неоднократно приводил в этой теме.
Надо делать так, как надо. А как не надо - делать не надо.
nikolz написал: запустил Ваш тест на боевом квике ------------------ вот результаты:
Там колбеки-то были? Сравнивать имеет смысл при наличии колбеков.
Цитата
Старатель написал: Нагрузка на CPU пропорциональна количеству любых объявленных переменных [...] и количеству колбеков, получаемых скриптом.
Скрипт:
Скрытый текст
Код
--local n = 0
--local n = 1000000
--local n = 3000000
local list = {TQBR = {"SBER", "GAZP", "VTBR", "RUAL"}, CETS = {"USD000UTSTOM"}, SPBFUT = {"BRH2", "RIH2", "SiH2", "SRH2"}}
local param = {"BID", "OFFER", "LAST", "NUMTRADES", "NUMBIDS", "NUMOFFERS"}
local run
function OnStop()
run = nil
end
local c = 0
function OnQuote(class_code, sec_code)
if not run then return end
c = c + 1
end
function OnParam(class_code, sec_code)
if not run then return end
c = c + 1
end
function OnAllTrade(alltrade)
if not run then return end
c = c + 1
end
function main()
local a = {}
for i = 1, n do a[i] = i end
for class, sec in pairs(list) do
for i = 1, #sec do
Subscribe_Level_II_Quotes(class, sec[i])
for i = 1, #param do
ParamRequest(class, sec, param[i])
end
end
end
local t = os.clock()
run = true
while run and t + 90 > os.clock() do
sleep(500)
end
t = os.clock() - t
for class, sec in pairs(list) do
for i = 1, #sec do
Unsubscribe_Level_II_Quotes(class, sec[i])
for i = 1, #param do
CancelParamRequest(class, sec[i], param[i])
end
end
end
message(string.format("%u: %u; %.0f/сек", n, c, c/t))
end
Результаты в боевом QUIK 9.3.3.3
В утреннюю сессию (~ 9 ч. МСК)
1. n = 0: 18233; 202/сек
Скрытый текст
2. n = 1000000: 19444; 215/сек
Скрытый текст
3. n = 3000000: 18127; 200/сек
Скрытый текст
В дневную сессию (~ 10 ч. МСК)
4. n = 0: 54455; 605/сек
Скрытый текст
5. n = 1000000: 45956; 510/сек
Скрытый текст
Надо делать так, как надо. А как не надо - делать не надо.
--local n = 0
local n = 5000000 -- special for Junior. Тест проводится поздно вечером на тухлом рынке, потому такое большое число. Думаю, днём можно уменьшить
local list = {QJSIM = {"SBER", "GAZP", "VTBR", "RUAL"}, CETS = {"USD000UTSTOM"}, SPBFUT = {"BRH2", "RIH2", "SiH2", "SRH2"}}
local param = {"BID", "OFFER", "LAST", "NUMTRADES", "NUMBIDS", "NUMOFFERS"}
local run = true
function OnStop()
run = nil
end
function main()
local a = {}
for i = 1, n do a[i] = i end
for class, sec in pairs(list) do
for i = 1, #sec do
Subscribe_Level_II_Quotes(class, sec[i])
for i = 1, #param do
ParamRequest(class, sec, param[i])
end
end
end
while run do sleep(500) end
for class, sec in pairs(list) do
for i = 1, #sec do
Unsubscribe_Level_II_Quotes(class, sec[i])
for i = 1, #param do
CancelParamRequest(class, sec[i], param[i])
end
end
end
end
function OnQuote(class_code, sec_code) end
function OnParam(class_code, sec_code) end
function OnAllTrade(alltrade) end
Заказ обезличенных сделок:
Скрытый текст
Получение данных: снята галка "Запрашивать данные раз в ... сек."
1. Загрузка при запущенном скрипте с n = 0 и открытой ТТТ. В ТТТ добавлены 4 класса: те же, что и в ТОС, со всеми параметрами.
Скрытый текст
Практически нулевая - скрипт не оказывает никакого влияния.
2. Загрузка при запущенном скрипте с n = 5000000 и открытой ТТТ.
Скрытый текст
Загрузка стала больше. А что изменилось? Только добавился массив, больше ничего.
3. Загрузка при запущенном скрипте с n = 5000000 и закрытой ТТТ.
Скрытый текст
Daniil Pozdnyakov, если у вас не получается проделать то же самое, готов продемонстрировать на компьютере вашего тестировщика по RDP.
Надо делать так, как надо. А как не надо - делать не надо.
--local v = 0
--local v = 100
--local v = "socket"
--local v = "iuplua"
local function f(n)
if type(n) == "number" then
local a = {}
for i = 1, n do
a[i] = {}
for j = 1, 1000 do a[i][j] = j end
end
return a
elseif n == "socket" then
local socket = require("socket")
require("socket.smtp")
return socket
else
return require(n)
end
end
local run = true
function OnStop()
run = nil
end
local m
function OnInit()
m = f(v)
end
local t
function OnAllTrade()
if getNumberOf("all_trades") == 1 then
local num = 1
function OnAllTrade(alltrade)
if not run then return end
num = num + 1
if num == 200000 then
t = os.clock() - t
run = false
end
end
t = os.clock()
end
end
function main()
while run do sleep(500) end
if t then message(v .. ": " .. t) end
end
Поочерёдно раскомментирую одну из 4-х первых строк и запускаю скрипт. Далее делаю перезаказ обезличенных сделок: Система / Настройки / Основные настройки... -> «Программа» / «Получение данных» / «Обезличенные сделки». Выбираю класс "Акции 1-го уровня (эмулятор)" -> "Перезаказать данные"
Оговорюсь, что сейчас помимо тестового у меня запущено ещё 3 квика и несколько других приложений. Поэтому результаты могут быть искажены. Но позволяют сделать следующие выводы:
Цитата
Старатель написал: Сам по себе скрипт не выполняет какой-либо полезной работы, он только вызывает пустой OnAllTrade(), больше ничего. Увеличение времени работы скрипта при подключении различных библиотек как раз свидетельствует о наличии зависимости нагрузки, создаваемой колбеком, и количеством данных в скрипте.
Надо делать так, как надо. А как не надо - делать не надо.
Daniil Pozdnyakov, я правильно понимаю, что тесты проводились на Junior, где количество всех инструментов (если не считать информационный класс) чуть более тысячи? Из которых более половины редко обновляются или не торгуются вообще. Для справки: у меня в боевом квике, в котором открыты только стаканы и графики по 8-ми фьючерсам, "умный" заказ сформировал список из более 30 тыс. инструментов, которыми я вообще не торгую и не открывал даже. Плюс ко всему инструменты на бою обновляются на порядок чаще, чем у вас на демке. И все изменения параметров по всем этим инструментам вызывают OnParam во всех скриптах, где есть этот колбек. В таком случае и количество скриптов и/или количество данных надо увеличивать пропорционально. Это, конечно, если цель - разобраться в причинах повышенной загрузки, а не просто отчитаться "запустили/посмотрели".
Цитата
Daniil Pozdnyakov написал: "Какие конкретно функции используются в данных скриптах ?"
Исходя из вопросов, ясно, что никто ни черта не делал и даже не читал тему. Вижу, что "тестирование" (если это можно так назвать) проведено на от#сь, совершенно без включения мозгов. Как я отмечал, оказывают влияние не только функции, но также данные в локальных/глобальных таблицах.
Позже дам комментарий по сообщению #19. Думал, для людей с технической специализацией оно будет понятно. Видимо, придётся расписывать для тех, кто с компьютером на "Вы" и то шёпотом. Но на это потребуется время.
Надо делать так, как надо. А как не надо - делать не надо.
В целях минимизации количества транзакций и снижения нагрузки на сервера предлагаю повысить приоритет для данного пожелания. А то люди иногда попадают на повышенную комиссию при групповом снятии заявок: https://smart-lab.ru/blog/765010.php#comment13661438 Там, правда, сторонний привод используется. Но у квиковского функционала группового снятия заявок принцип схожий.
Надо делать так, как надо. А как не надо - делать не надо.
Anton написал: Дело в том, что нештатно останавливается. Если OnStop возвращает 0, сразу за ней выполняется WaitForSingleObject(main, 0), возвращаясь немедленно из-за нулевого таймаута, и сразу же TerminateThread. Там потом еще уведомление главному окну посылается. Видимо, какие-то сопли после этого всего остаются.
Получается с той или иной долей вероятности можно налететь на такое при любом значении в return и даже без него?
Надо делать так, как надо. А как не надо - делать не надо.
Так зависает не во время работы скрипта. Сначала скрипт штатно останавливается, при этом никаких ошибок не выдаёт. Затем скрипт уже перестаёт запускаться. И при попытке вызове какого-нибудь меню квик вешается.
Надо делать так, как надо. А как не надо - делать не надо.
Денис написал: после нажатия кнопки "Остановить" скрипт, вроде бы, штатно останавливается - но затем через пять-семь минут при нажатии на любой пункт меню QUIK намертво зависает.
Проверил - да, так и есть. Хоть с квиком работаю уже много лет, но на чём квик сейчас застопорился не пойму.
Надо делать так, как надо. А как не надо - делать не надо.
Срочный рынок. Через Lua подаётся транзакция MOVE_ORDERS. В течение более 6 мин. сервер сыпет ошибки: Вы не можете заменить заявку ..., так как ее обработка еще не завершена. Код ошибки: -1065103584 Источник ошибки: Библиотека расчёта лимитов
Сервер не способен обработать заявку более 6 мин.? Что за обработка такая? Зачем он вообще это делает? Обработкой заявок занимается торговая система биржи. А от терминала требуется передать транзакцию от пользователя в торговую систему и вернуть ответ от ТС в терминал пользователя. И сделать это желательно как можно быстрее.
Надо делать так, как надо. А как не надо - делать не надо.
D7DSk написал: Зачислять свои деньги туда онне может, соответственно торговать с него тоже в силу закона:
Ознакомьтесь с декларацией о рисках в договоре с вашим брокером. Скорее всего, там есть такой пункт:
Либо, если брокер является кредитной организацией:
Цитата
Законодательство не предусматривает возможности разделения денежных средств брокера, являющегося кредитной организацией, и денежных средств его клиентов, в связи с чем брокер вправе использовать ваши денежные средства и вы принимаете на себя риск его банкротства. Такой риск в настоящее время не страхуется
Надо делать так, как надо. А как не надо - делать не надо.
К сожалению, движок этого чудо-форума не позволяет редактировать заголовки тем или сообщения. С учётом полученной раннее информации заголовок темы должен выглядеть так:
Высокая нагрузка CPU в QUIK 9 при вызове колбеков в скриптах, которые содержат много переменных или хранят большое количество элементов в таблицах.
_sk_, посмотрите мои сообщения на первой странице и комментарий Антона #16. Суть в том, что сам по себе вызов колбеков при большом количестве хранимой информации создаёт огромную нагрузку вне зависимости от кода внутри колбека и параллельно выполняющейся работы в main. Отмечу, что объём хранимых данных (в байтах) не имеет значения. Нагрузка пропорциональна количеству данных. Обратите внимание также на тест в сообщении #19. Сам по себе скрипт не выполняет какой-либо полезной работы, он только вызывает пустой OnAllTrade(), больше ничего. Увеличение времени работы скрипта при подключении различных библиотек как раз свидетельствует о наличии зависимости нагрузки, создаваемой колбеком, и количеством данных в скрипте. А тормоза в GUI, которые вы наблюдаете, - скорее всего уже следствие, а не причина.
ЗЫ: версии библиотек qlua.dll, lua53.dll, lua54.dll в QUIK 9.3.3 не изменились по сравнению с QUIK 9.3.1
Надо делать так, как надо. А как не надо - делать не надо.
Владимир, я давно понял, что вы ни черта не понимаете в тех темах, куда суёте свой длинный нос. А объяснять что либо старому дураку бесполезно. Но я готов заключить с вами сделку: В первом сообщении данной темы есть скрипт. Если вы его отредактируете таким образом, чтобы в не зависимости от применённых к таблице фильтров или сортировки, при нажатии на любую клавишу выделялась строка с фактическим порядковым номером 2 (если строка она не скрыта фильтром), то я публично признаю, что вы - лучший, чем я программист. Если же вы этого сделать не сможете, то вы перестанете засирать этот форум и навсегда его покинете. Но я абсолютно уверен, что вы
Цитата
Владимир написал: не способны выделить нужную строку
, а потому сольётесь под любым предлогом.
Надо делать так, как надо. А как не надо - делать не надо.
Nikolay написал: begin: 0.0 end: 0.006, memory: 25.41796875
Только сейчас заметил: вы сравниваете время вызова библиотечной функции os.time() ? Причём сравниваемые величины явно меньше погрешности измерения. А memory то почему по-вашему должны сильно отличаться? На самом деле, разница в скорости в чистом луа и в квике есть. Причём, если запускать в main, то разница значительная. Надо только цикл поболее брать. Но ваш тест к теме имеет такое же отношение, как и война браузеров.
Надо делать так, как надо. А как не надо - делать не надо.
s_mike@rambler.ru написал: Я ещё раз прочитал сообщение _sk_, на которое я отвечал и да, речь идёт именно о занимаемой памяти скриптом, в котором очень много таблиц, описывающих дату/время.
Речь не о размере занимаемой памяти, а о количестве элементов в таблице.
Надо делать так, как надо. А как не надо - делать не надо.
Скрипт продолжает работать после выключения терминала, разрыва соединения, снятия всех сделок, После разрыва соединения со стороны брокера, скрипт не остановился и продолжает работать, не ясно как выключить
Alexey Ivannikov написал: 2. Обновление версии QUIK не через интерфейс программы. Оно делается очень просто: качаем архив с комплектом файлов для обновления программы вручную (актуальный архив присутствует на странице https://arqatech.com/ru/support/files/ ), после чего распаковываем его (с заменой файлов) в корень папки с QUIK. В этом случае происходит только обновление самой программы (не трогаются конфигурационные файлы) и QUIK будет работать без каких бы то ни было дополнительных манипуляций.
Alexey Ivannikov, могли бы вы ещё рядом с апдейтом класть библиотеки модулей InstrClient.dll, Reports.dll, StratVolat.dll ?
Надо делать так, как надо. А как не надо - делать не надо.