По вашим же тестам накладные расходы на вызов корутин в 97.33 раз больше, чем на вызов функций (coroutine=584.000 мс , func=6.000 мс ). Чтобы для вас было наглядно, при всяком вызове корутины, прежде чем она начнет что-то делать, делается 97 пустых вызовов функций.
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
Пользователь
Сообщений: Регистрация: 12.05.2020
28.10.2025 22:29:29
Цитата
nikolz написал: сделал прикольный тест на оценку быстродействия корутин.
Вы обнаружили существенную деградацию эффективности реализации корутин в Lua 5.4.1. Причем при выполнении модифицированного мною вашего теста она больше, чем вы пишите: накладные расходы на вызов корутин больше по сравнению с вызовом функции ~150 раз. В Lua 5.1 эта разница была ~4 раза. Кому интересно, можно проверить в QUIK 8.4.1. Код теста:
Код
function main()
local N =100000
local function foo ()
local yield = coroutine.yield
while 1 do
yield()
end
end
local function foo1 () return end
-----
local out = 'Результат теста: количество вызовов = ' .. N .. ', время вызова сопрограммы '
local resume = coroutine.resume
local co = coroutine.create(foo)
local TT1 = os.clock()
for i =1, N do resume(co) end
TT1 = (os.clock() - TT1) * 1000
out = out .. TT1 .. ' млс.'
-- message('coroutine = ' .. (os.clock() - TT) * 1000)
local TT2 = os.clock()
for i =1, N do foo1(10) end
TT2 = (os.clock() - TT2) * 1000
-- message('function = '.. (os.clock() - TT) * 1000)
out = out .. ', функции ' .. TT2 .. ' млс. T1/T2 = ' .. TT1/TT2
message(out)
end
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
DestroyTable (и Clear) закрывает скрипт вместо таблицы, Тема описана в Названии и в Тексте сообщения
Пользователь
Сообщений: Регистрация: 12.05.2020
14.10.2025 08:08:47
Цитата
paluke написал: Не только DestroyTable(), любые операции с таблицей не выполняются.
Цитата
TGB написал: Работа с таблицами QUIK выполняется в служебном потоке, отличном от main. В том же, в котором выполняется OnStop. И пока выполняется OnStop никакие операции с таблицами QUIK не возможны (поток работы с таблицами занят OnStop ).
Если бы я был архитектором QUIK, Что стоило бы изменить в QUIK по-крупному
Пользователь
Сообщений: Регистрация: 12.05.2020
13.10.2025 19:13:30
Дополнительно для анализа долгого запуска QUIK: 1) 2) 3)
Если бы я был архитектором QUIK, Что стоило бы изменить в QUIK по-крупному
Пользователь
Сообщений: Регистрация: 12.05.2020
13.10.2025 16:53:28
Цитата
Oleg Kuzembaev написал: Ранее уже ответили вам письмом на почту.
Здравствуйте. У меня в почте письма нет. Пришлите, пожалуйста повторно.
DestroyTable (и Clear) закрывает скрипт вместо таблицы, Тема описана в Названии и в Тексте сообщения
Пользователь
Сообщений: Регистрация: 12.05.2020
13.10.2025 16:14:37
Цитата
nikolz написал: Если он вызывается в main то вызов это и есть исполнение.
nikolz писатель ? Читайте:
Цитата
TGB написал: она не лезет в таблицы QUIK, а создает коллбек закрытия таблицы, который обрабатывается в потоке терминала,
Если бы я был архитектором QUIK, Что стоило бы изменить в QUIK по-крупному
Пользователь
Сообщений: Регистрация: 12.05.2020
12.10.2025 09:17:59
Цитата
TGB написал: 1) При проверке многократной (> 8 раз) остановки/запуска скрипта, в котором используется сторонний графический пакет IUP, QUIK (версия 12.6.1.2, Lua 5.4), после разного количества экспериментов, в моменты останова/запуска, падает: Дамп info_dmp_20251007_150748.dmp вышлю почтой.
На это нет ответа. ---- Предложения: 1) После завершения OnStop не обрабатывать только коллбеки, зарегистрированные в main. Коллбеки создаваемые в main продолжать отрабатывать (смотрите ветку . 2) Реализовать/проверить сихронизацию основного потока QUIK с потоком main при его остановки (не обращаться из основного потока к данным завершенного потока).
DestroyTable (и Clear) закрывает скрипт вместо таблицы, Тема описана в Названии и в Тексте сообщения
Зачем полагать, когда можно проверить. Переставьте DestroyTable в OnStop.
2.
Цитата
nikolz написал: Функция DestroyTable в данном примере вызывается в потоке Main.
Вы точно знаете как устроена DestroyTable? Не точно, но скорее всего, это реализовано следующим образом. При том, что DestroyTable вызывается в main, она не лезет в таблицы QUIK, а создает коллбек закрытия таблицы, который обрабатывается в потоке терминала, но он занят более интересным делом : остановкой скрипта (удаляет поток main и перестает обрабатывать коллбеки, созданные в нем, так как исчезнет контекст их выполнения).
DestroyTable (и Clear) закрывает скрипт вместо таблицы, Тема описана в Названии и в Тексте сообщения
Пользователь
Сообщений: Регистрация: 12.05.2020
11.10.2025 19:01:44
Цитата
Ростислав Дм. Кудряшов написал: В каком потоке управления выполняется вызов функции DestroyTable()
Работа с таблицами QUIK выполняется в служебном потоке, отличном от main. В том же, в котором выполняется OnStop. И пока выполняется OnStop никакие операции с таблицами QUIK не возможны (поток работы с таблицами занят OnStop ). OnStop в любом случае завершает скрипт, поэтому DestroyTable не выполнена и созданная в скрипте таблица существует после завершения скрипта. Если что то надо делать с таблицами по кнопке завершить, то это надо делать в функции OnStop.
DestroyTable (и Clear) закрывает скрипт вместо таблицы, Тема описана в Названии и в Тексте сообщения
Будет выход из цикла и функции main при закрытии таблицы и это правильно. В данном случае ошибки в Qlua нет.
Если бы я был архитектором QUIK, Что стоило бы изменить в QUIK по-крупному
Пользователь
Сообщений: Регистрация: 12.05.2020
09.10.2025 20:56:43
Цитата
Oleg Kuzembaev написал: В таком случае, пришлите нам архив вашего Рабочего места QUIK на почту поддержки
Посылал на ваше имя последние настройки QUIK, с которыми проверял длительность его перезапуска.
Если бы я был архитектором QUIK, Что стоило бы изменить в QUIK по-крупному
Пользователь
Сообщений: Регистрация: 12.05.2020
09.10.2025 10:30:05
Цитата
Oleg Kuzembaev написал: В таком случае, пожалуйста, конкретизируйте в чем именно ваш вопрос/пожелание к будущим версиям терминала?
Пожелание относительно длительности запуска/перезапуска QUIK на работающем ПК с характеристиками 8 ядер, 4 Ггц, память 32 Гб, диск SSD: <= 3 сек.
Неккоректная работа CreateDataSourse
Пользователь
Сообщений: Регистрация: 12.05.2020
09.10.2025 08:43:39
Цитата
Serchk написал: И переменная a при запуске постоянно возвращает nil значение
Данные приходят не сразу. Можно использовать функцию:
Код
--- Cl - класс, Sec - код бумаги, Int - таймфрейм.
--- T - ожидание поступления данных источника в сек. (по умолчанию 15 сек.)
local CreateDS = function(Cl, Sec, Int, T)
T = (T or 15) * 10
local ds, Error = CreateDataSource(Cl, Sec, Int)
for i = 1, T do
if not ((Error == "" or Error == nil) and ds:Size() == 0) then break end
if i >= T then error('Не дождались DS: ' .. Sec .. '. Ошибка: ' .. tostring(Error)) end
sleep(100)
end
return ds
end
Если бы я был архитектором QUIK, Что стоило бы изменить в QUIK по-крупному
Пользователь
Сообщений: Регистрация: 12.05.2020
09.10.2025 08:18:48
Цитата
Oleg Kuzembaev написал: В Рабочем месте QUIK существует настройка "Восстанавливать связь автоматически через". Как понятно из ее названия, она позволяет подключиться к торговому серверу снова через заданный пользователем промежуток времени в случае потери соединения. Настройка "При восстановлении использовать только параметры последнего соединения" позволит подключиться к тому серверу, с которым было утрачено соединение.
У меня все включено. QUIK запускается с опцией -clear.
Если бы я был архитектором QUIK, Что стоило бы изменить в QUIK по-крупному
Пользователь
Сообщений: Регистрация: 12.05.2020
08.10.2025 21:36:22
Цитата
Egor Zaytsev написал: Просьба подсказать, претензия в том, что после подключения к серверу по настройке Восстанавливать связь автоматически QUIK долго получает данные? Если да, то на какие именно данные ориентируетесь? Проблема исключительно только утром?
Ситуации: 1) При проверке многократной (> 8 раз) остановки/запуска скрипта, в котором используется сторонний графический пакет IUP, QUIK (версия 12.6.1.2, Lua 5.4), после разного количества экспериментов, в моменты останова/запуска, падает: Дамп info_dmp_20251007_150748.dmp вышлю почтой. Могу наделать сколько нужно. Причина 0xc0000005 - Потоком была предпринята попытка прочитать или записать данные на виртуальный адрес, к которому он не имеет соответствующего доступа. Это происходит только в рабочем экземпляре QUIK. В песочнице с такой же версией этого нет. В работе проблем с пакетом IUP не обнаружено (использую давно, но ранее при проверке запуска/перезапуска делал это 3-4 раза.). Экспериментально выяснил, что перенос закрытия IUP (iup:Close()) из служебного потока OnStop в пользовательский поток main, ситуацию исправляет. QUIK падать перестает. Но почему iup:Close() "ломает" поток OnStop? Опять что-нибудь с синхронизацией? Похоже, это очередная ситуация, подтверждающая то, что мною написано в п. 2) комментария . В комментарии предлагается вариант реализации п. 2). В комментарии есть предложение, как при реализации п. 2), сохранить существующий интерфейс QLua c QUIK. ------- При экспериментировании замучился ожидать перезапуски QUIK и об этом следующий пункт.
2) Задержка при запуске/перезапуске QUIK на моем ноутбуке, с ранее перечисленными характеристиками: ~1 мин. Это много и неоднократно в разные года обсуждалось в различных ветках. Мои комментарии трассировки запуска рабочего QUIK выделены символами ##.
Код
KW 08.10.25 16:50:36:220 ## Остановлен QUIK (16:50:36:220)
--- @ Остановлен по стоп бот D:\0 D\0 TGB\B_Q\Bots\B1 @ ---
## Через ~ 1 сек. QUIK запущен
==================================
KW 08.10.25 16:51:02:693 ## Начало работы скрипта (длительность от начала запуска 26 сек.)
Begin_Require: 08.10.25 16:51:02:693. End_Require: 08.10.25 16:51:02:696 ## Загружены все пакеты скрипта (длительность загрузки 3 млс.)
KW 08.10.25 16:51:02:717 ACCOUNT, CLASS_CODES, CLIENT_CODES, FIRM_ID: ## Получены реквизиты и скрипт готов продолжать работать
KW 08.10.25 16:51:02:717 #572:TRADER_lib Нет подключения к серверу
KW 08.10.25 16:51:02:717 #575:TRADER_lib С сервера не поступают необходимые данные
KW 08.10.25 16:51:02:717 #578:TRADER_lib Ждет возобновления связи
KW 08.10.25 16:51:25:197 #590:TRADER_lib Соединение с сервером восстановлено, ждет 10 сек. подгрузки данных
KW 08.10.25 16:51:35:201 #608:TRADER_lib Возобновил работу ## (16:51:35:201) Итого: длительность перезапуска ~ 1 мин.
Переформулирую два заданные ранее вопросы в один: Для взаимодействия сервера с терминалом QUIK существует протокол его быстрого восстановления при разрывах его по любой причине? Я не представляю, где проблемы с быстрым перезапуском QUIK с учетом того, что: 1) в ОС (Windows) многое кэшируется (на моем ноуте 32 Гб. и перезапуск выполняется сразу после падения QUIK); 2) реализован более менее приличный протокол быстрого восстановления взаимодействия.
Два варианта использования графического пакета IUP (Lua 5.4) в QUIKе
Пользователь
Сообщений: Регистрация: 12.05.2020
06.10.2025 12:43:26
Цитата
VPM написал: Сопрограммы в Lua — это мост между двумя мирами: 1. Мир для программиста: Удобный, последовательный, понятный код. 2. Мир для машины: Гибкое, асинхронное, неблокирующее выполнение.
Написано так красиво , что я не удержался, чтобы что-нибудь не добавить: 3. Есть задачи, которые могут быть реализованы с использованием сопрограмм проще, чем с использованием только функций. Например, подключение IUP в выложенном вами скрипте. Однако, следует учитывать, что сопрограммы (нити - псевдопотоки) отличаются от потоков, в основном, только следующим: 1) они не могут выполняться параллельно; 2) переключение между ними программное (yield), а не внешнее как в потоках (по прерываниям в любом их месте); 3) для их синхронизации не требуются тяжеловесные примитивы (критические секции и т.д.), достаточно использования переменных (так как нет параллелизма). При использовании сопрограмм всегда надо помнить: если в нескольких сопрограммах изменяются общие данные, то нужно заниматься их синхронизацией. Таким образом, используя сопрограммы вы попадаете в пусть специфическую, но многопоточную среду, почти со всеми проблемами программирования потоков. Использование сопрограмм это моделирование многопоточного поведения скрипта в однопоточной среде исполнения. Программировать сопрограммы сложнее, чем функции. Чем сложнее программа, тем больше в ней ошибок. То что можно сделать просто в виде функций, вряд ли стоит делать на сопрограммах, если это не для развлечения.
Два варианта использования графического пакета IUP (Lua 5.4) в QUIKе
Пользователь
Сообщений: Регистрация: 12.05.2020
05.10.2025 08:21:38
Цитата
Ростислав Дм. Кудряшов написал: Не поленись, а запусти на своём ПК пример переключения спорограмм-корутин между IUP и main(). И убедишься, что невытесняющая (кооперативная) многозадачность порой лучше вытесняющей.
С этого места, пожалуйста, поподробнее. Как вам удалось сумев запустить единственный готовый пример, определить что он порой лучше вытесняющей многозадачности? С чем вы его сравнивали? Или вы можете определять лучшее без сравнения? Откуда к вам приходят такие озарения ? Поделитесь.
Два варианта использования графического пакета IUP (Lua 5.4) в QUIKе
Пользователь
Сообщений: Регистрация: 12.05.2020
04.10.2025 22:40:12
1.
Цитата
Ростислав Дм. Кудряшов написал: Статья не разъясняет, "для чего и как". Поэтому нет причины углубляться в скрипт.
Ростислав Дм. Кудряшов написал: параллельное исполнение скрипта main() и ручных манипуляций в IUP с непрерывной связью между этими нитями (threads) в обоих направлениях.
Где вы прочитали, что корутины в Lua выполняются параллельно? Интересно, как в одном потоке можно с помощью корутин реализовать параллелизм (одновременность) их выполнения? Но на всякий случай цитата Р. Иерузалимски: "в любой момент времени программа с сопрограммами выполняет только одну из своих сопрограмм".
Два варианта использования графического пакета IUP (Lua 5.4) в QUIKе
Согласен, в работающем роботе достаточно возможностей пользовательских таблиц QUIK. Идеальный, зарабатывающий робот должен это делать без вводных и без лишнего вывода, только отчеты о прибыли в журнале с аналитикой, полезной пользователю. Реально, желателен вывод роботом сообщений о наступлении событий, требующих вмешательство пользователя. Все это без проблем реализуемо на таблицах QUIK. Графический пакет я использовал для реализации средств создания скриптов, что сделать на таблицах QUIK сложновато.
Два варианта использования графического пакета IUP (Lua 5.4) в QUIKе
Пользователь
Сообщений: Регистрация: 12.05.2020
04.10.2025 11:47:41
Цитата
Nikolay написал: Просто замечание, что если предлагаете какое-то открытое решение, то зачем скрывать код, его подключающее.
С этим можно бы согласиться, но есть вариант 1, в котором нет скрытых кодов.
Два варианта использования графического пакета IUP (Lua 5.4) в QUIKе
Пользователь
Сообщений: Регистрация: 12.05.2020
04.10.2025 10:41:20
Цитата
Nikolay написал: Я понял про что это библиотека. Я говорил, что нет исходников.
Мною рекомендуется использовать первый вариант и для него пакет QluaUser.dll не требуется.
Два варианта использования графического пакета IUP (Lua 5.4) в QUIKе
Пользователь
Сообщений: Регистрация: 12.05.2020
04.10.2025 09:09:10
Цитата
Nikolay написал: Просто к слову, т.к. используется неизвестная библиотека QluaUser.dll то запускать это не видя исходники будут сложно. По крайней мере мне, не знаю как другим.
Цитата
TGB написал: -- Вариант 1: запуск IUP в потоке main (надо подключать только IUP, но цикл обработки скрипта программировать -- в таймере IUP: помечено #### ). -- Вариант 2: запуск IUP в отдельном потоке отличном от main(кроме IUP, обязательно подключать пакет QluaUser). -- Вариант 1 более безопасный, чем 2. Так как однопоточный, и не требующий синхронизации диалога с -- основной работой скрипта.
Два варианта использования графического пакета IUP (Lua 5.4) в QUIKе
Пользователь
Сообщений: Регистрация: 12.05.2020
03.10.2025 20:50:09
Инструкция в коде примера:
Код
--- Использование графического пакета IUP (Lua 5.4...) в QUIKе (! ограничение IUP:
-- только в одном из запущенном скрипте экземпляра QUIK).
-- Доступны все возможности пакета IUP (подключаемой версии).
-- Вариант 1: запуск IUP в потоке main (надо подключать только IUP, но цикл обработки скрипта программировать
-- в таймере IUP: помечено #### ).
-- Вариант 2: запуск IUP в отдельном потоке отличном от main(кроме IUP, обязательно подключать пакет QluaUser).
-- Вариант 1 более безопасный, чем 2. Так как однопоточный, и не требующий синхронизации диалога с
-- основной работой скрипта.
-- Ссылка для скачивания пакетов iup.dll, iuplua54.dll, QluaUser.dll (мой):
-- https://cloud.mail.ru/public/7xAm/jaCgULqGo Перед использованием пакетов, надо их разблокировать.
-- Пакеты переслать в папку экземпляра QUIK, хранящую файл info.exe.
_RUN_ = true
function main()
-- Пример формы IUP со двумя вкладками ---
local Pause = 1000
local thread = false -- false - выполнение диалога в потоке main; true - запуск IUP в отдельном потоке --
local cpath = (getWorkingFolder() .. '\\?54.dll;' .. getWorkingFolder() .. '\\?_5_4.dll;'.. getWorkingFolder() .. '\\?.dll;' .. package.cpath)
---
package.cpath = cpath
require("iuplua")
local QluaUser = require('QluaUser') -- Это для запуска диалога IUP в отдельном потоке ---
if thread then
QluaUser = require('QluaUser')
end
local function iup_form()
local timer = iup.timer { time = Pause } ---- Вместо sleep таймер формы ( млсек.) ---
timer.run = "NO"
function timer:action_cb()
if not _RUN_ then
timer.run = "NO"
iup:ExitLoop() -- Завершает текущий диалог
end
if not thread then -- Основной цикл обработки скрипта в таймере IUP ---
-- Тело основного цикла скрипта -- ####
message('iup выполняется в потоке main. Тело основного цикла скрипта должно выполняеться здесь (в таймере iup)')
-------------------
end
end
-- Creates boxes
local vboxA = iup.vbox{iup.fill{}, iup.label{title="TABS AAA", expand="HORIZONTAL"}, iup.button{title="AAA"}}
local vboxB = iup.vbox{iup.label{title="TABS BBB"}, iup.button{title="BBB"}}
-- Sets titles of the vboxes
vboxA.tabtitle = "AAAAAA"
vboxB.tabtitle = "BBBBBB"
-- Creates tabs
local tabs = iup.tabs{vboxA, vboxB}
-- Creates dialog
local dlg = iup.dialog{iup.vbox{tabs; margin="10x10"}; title="Test IupTabs", size="150x80"}
-- Shows dialog in the center of the screen
dlg:showxy(iup.CENTER, iup.CENTER)
timer.run = "YES"
if (iup.MainLoopLevel()==0) then
iup.MainLoop()
end
timer.run = "NO"
end
if thread then
QluaUser.ThreadNew(iup_form)
else
iup_form()
iup.Close()
iup = nil
end
while _RUN_ do -- Основной цикл обработки скрипта в main ---
-----------------------
if thread then
message('iup был запущен в отдельном потоке. Тело основного цикла скрипта выполняется в потоке main.')
else
message('После завершения потока iup, продолжается выполняется поток main.')
end
sleep(Pause)
-----------------------
end
end
---
function OnStop(flag)
_RUN_ = false
sleep(2000)
if iup then iup.Close() end
return 3000
end
Если бы я был архитектором QUIK, Что стоило бы изменить в QUIK по-крупному
Из текста фрагмента протокола видно, но, наверное, надо пояснить: мною в меню "Система > Соединения.. > Восстанавливать связь автоматически" было указано начало c 6.50.
Если бы я был архитектором QUIK, Что стоило бы изменить в QUIK по-крупному
Пользователь
Сообщений: Регистрация: 12.05.2020
29.09.2025 08:47:44
На вопросы в общей постановке, ответа я не вижу. 1. Отвечать не отвечают, но реагируют . Протокол начала утренней сессии 29.09.25: KW 29.09.25 06:50:10:519 --- OnCleanUp (прилетел) ----------------- KW 29.09.25 06:50:32:746 #590:TRADER_lib Соединение с сервером восстановлено, ждет 10 сек. подгрузки данных KW 29.09.25 06:50:42:754 #608:TRADER_lib Возобновил работу
2. Проблема с длительностью запуска QUIK пока осталась. Для быстрого восстановления функционирования программ используются контрольные точки. Это значения переменных программ, возникшие при их выполнении и сохраненные в энергонезависимой памяти для возможности быстрого продолжения их работы, начиная с сохраненного состояния, после их перезапуска по любой причине (сбой аппаратуры, программная ошибка, и т.д.). Например: 1) Windows (программный монстр), используя контрольную точку, просыпается из режима сна за ~1сек. 2) Chrome (большая программа) c 50 вкладками открывается через ~2 сек. 3) В моих многоскриптовых роботах, со скриптами (в количестве:3-6), взаимодействующими между собой, есть режим, в котором после начала запуска/перезапуска, они готовы к продолжению прерванной работы менее чем через 15 млс. ---- На сервере есть контрольные точки терминалов (QUIKов) для быстрого продолжения работы с ними после любого его перезапуска? В QUIKе есть контрольная точка для быстрого продолжения работы с сервером после любого перезапуска QUIK?
Автозапуск скрипта LUA при старте QUIK
Пользователь
Сообщений: Регистрация: 12.05.2020
27.09.2025 21:52:32
Цитата
Андрей написал: А уточните, пожалуйста, функция, которую вы упоминаете, финализирует только таблицы? открытые файлы лучше отдельно закрыть?
У меня все объекты и таблицы и файлы финализируются следующим образом (фрагмент моего кода, обеспечивающего финализацию):
Код
--- Стек объектов финализации (автоматическая финализация) ---
-- В этот стек помещать для финализируемых объектов функции их очистки (сразу при создании объектов) в формате:
-- {<Функция финализации объекта>, {<Параметры финализации объекта через запятую>}}; таблица с параметрами может отсутствовать
local FINALIZATION_META
FINALIZATION_STEK = {}
--- Реализована возможность финализации "вручную":
-- 1) mess = true - финализация без выдачи сообщения;
-- 2) no_mess = 'string' - финализация c выдачи сообщения no_mess;
function FINALIZATION_STEK_FUNFIN(stek_fin, no_mess) -- ! Функция вызывается при любом варианте завершения скрипта --
if type(stek_fin) ~= 'table' then return end
if not next(stek_fin) then return end
-------- Выдача сообщений различных вариантов финализации ---
if not no_mess or type(no_mess) == 'string' then
-- message('FINALIZATION_STEK_FUNFIN - здесь выдать сообщение ADMIN: *** Завершение с не перехваченной ситуацией')
if B_Q_DLL and OPEN_CONTROL_BOT then
local mess
if type(no_mess) == 'string' then
mess = no_mess
else
mess = '\n *** Завершение с не перехваченной ситуацией в скрипте: ' .. (SCRIPT_NAME or '??')
..'\n Дополнительные подробности смотрите в журнале скрипта и диагностике QUIK.'
end
message(mess, 3)
---
end
end
--------------------------------------------
local ob_l
for i = #stek_fin, 1, -1 do -- обработка стека очистки объектов финализации ---
ob_l = stek_fin[i] -- #### 15.12.24
stek_fin[i] = nil -- #### 15.12.24
if type(ob_l) == 'table' and type(ob_l[1]) == 'function' then
if ob_l[2] then
ob_l[1](table.unpack(ob_l[2]))
else
ob_l[1]()
end
end
end
FINALIZATION_META.__gc= 0 -- отключение финализации ---
end
----
-- При подключении финализирующей метатаблицы в ней обязательно должно быть поле __gc
-- (! значения отличные от функции не будут обрабатываться, но функцию можно присвоить позже),
-- иначе не будет пометки для финализации (список финализации формируется при подключении метатаблиц с полем __gc)
FINALIZATION_META = {__gc = FINALIZATION_STEK_FUNFIN}
setmetatable(FINALIZATION_STEK, FINALIZATION_META)
--- Запись в стек функции финализации ---
function FINALIZATION_STEK_PUSH(tbl_rez) -- tbl_rez = {<Функция финализации объекта>, {<Параметры финализации объекта>}}
FINALIZATION_STEK[#FINALIZATION_STEK + 1] = tbl_rez
end
Но, может для вас окажется достаточно добавить sleep(1000) или большую задержку.
Автозапуск скрипта LUA при старте QUIK
Пользователь
Сообщений: Регистрация: 12.05.2020
27.09.2025 20:20:20
Цитата
Андрей написал: Видимо придется по одному действию возвращать в обработку остановки бота и смотреть, что приводит к его закрытию.
Мне пришлось столкнуться с похожей ситуацией когда в одном из скриптом стал использовать таблицы QUIK для визуализации. Посмотрите в эту сторону (код завершения моего скрипта, после добавления которого он стал перезапускаться вместе с QUIK):
Код
while _RUN_ do
< Тело основного цикла скрипта>
end
if TBL_QUIK then -- Если использовались таблицы
-- Финализация (не допускать одновременного выполнения в пользовательском и основном потоке QUIK) ---
FINALIZATION_STEK_FUNFIN(FINALIZATION_STEK, true)
----
-- #### Задержка sleep нужна чтобы установить признак запуска скрипта при перезапуске QUIK.
-- Иначе при перезапуске QUIK не будет перезапущен скрипт.--
-- При нормальном завершении QUIK, если есть таблицы QUIK, они удаляются (и вызываются коллбеки QTABLE_CLOSE)
-- Если при этом нет задержки, то скрипт завершается и не выставляется признак необходимости его перезапуска
-- при запуске QUIK. Признак TBL_QUIK устанавливается в основной пользовательской таблице QUIK.
-- Длительность задержки выбрана экспериментально.
sleep(sleep_TBL_QUIK_ or 1000)
end
FINALIZATION_STEK_FUNFIN(FINALIZATION_STEK, true) у меня финализирует по стековому принципу все открытые объекты, которые по-хорошему, требуют своего закрытия (в том числе созданные таблицы QUIK). Финализация выполняется при завершении скрипта по любой причине. Это делается с использованием метатаблицы финализации.
Ошибка при поиске пиков\впадин кастом индикатора
Пользователь
Сообщений: Регистрация: 12.05.2020
26.09.2025 12:24:05
Цитата
VPM написал: bit.band — чистая побитовая операция на целых, выполняется через С-библиотеку, работает на порядок быстрее, особенно если много итераций.
Вы это проверяли? bit.band это вызов функции, в теле которой выполняется битовая операция "И". Сам вызов до начала выполнения тела функции это довольно тяжелая операция, выполняющаяся дольше любой арифметической операции. В Lua 5.4 соотношение длительности выполнения приблизительно следующее: 1) % = 1 2) bit.band = 4,49 3) & (битовая операция "И" вместо bit.band , начиная c Lua 5.3) = 0,63
Можете попробовать использовать ранее выложенный мной, но слегка модифицированный код индикатора Kijun-sen, который работает в ~20 раз быстрее, чем чем то, что выложил Roman Koledin:
Код
Settings = {
Name = "*Kijun-sen",
kijun_period = 26, -- Период Kijun-sen (можно изменить)
line = {{
Name = "Kijun-sen",
Color = RGB(0, 0, 200),
Type = TYPE_LINE,
Width = 2
}}
}
local kijun_period = Settings.kijun_period
local QueueH, QueueL = {}, {}
local const_L = 999999999
function Init()
QueueH, QueueL = {}, {}
for i = 0, kijun_period - 1 do
QueueH[i] = 0; QueueL[i] = const_L
end
return 1
end
function OnChangeSettings()
kijun_period = Settings.kijun_period
QueueH, QueueL = {}, {}
for i = 0, kijun_period - 1 do
QueueH[i] = 0; QueueL[i] = const_L
end
end
---
local TT
local N_C = 500
local max_high, min_low
function OnCalculate(index)
-- -- Вычисление времени обработки свеч (500 свечкй за ~4 млс. в 5 раз быстрее моего же *Kijun-sen_opt)--
-- if index == kijun_period + 1 then
-- TT = os.clock()
-- end
-- if index == N_C + kijun_period then
-- message('Kijun-sen. Время обработки ' .. N_C .. ' свечей (млс.) = ' .. (os.clock() - TT) * 1000)
-- end
-- -----------------------------------
if index == 1 then
max_high = H(1) or 0
min_low = L(1) or const_L
QueueH[1], QueueL[1] = max_high, min_low
else
current_high = H(index) or 0
current_low = L(index) or const_L
local ind = index % kijun_period -- место в векторе --
local QueueH_end
local QueueL_end
if index > kijun_period then -- сохранение уходящих значений --
QueueH_end = QueueH[ind]
QueueL_end = QueueL[ind]
end
QueueH[ind], QueueL[ind] = current_high, current_low -- сохранение текущих в векторе --
-- --------
if current_high >= max_high then -- Пришел максимальный --
max_high = current_high
else
if index > kijun_period then -- начальный период завершен --
-- Максимум "ушел" из скользящего периода --
if QueueH_end >= max_high then -- поиск максимального в векторе
max_high = current_high
for j = 0, kijun_period - 1 do
current_high = QueueH[j]
if current_high > max_high then max_high = current_high end
end
end
end
end
---
if current_low <= min_low then -- Пришел минимальный
min_low = current_low
else
if index > kijun_period then
-- Ушел из скользящего периода минимальный --
if QueueL_end <= min_low then -- поиск минимального
min_low = current_low
for j = 0, kijun_period - 1 do
current_low = QueueL[j]
if current_low < min_low then min_low = current_low end
end
end
end
end
end
return (max_high + min_low) / 2
end
Если бы я был архитектором QUIK, Что стоило бы изменить в QUIK по-крупному
Пользователь
Сообщений: Регистрация: 12.05.2020
25.09.2025 10:56:01
Протокол начала утренней сессии (типичный случай): KW 25.09.25 03:15:00:724 #578:TRADER Ждет возобновления связи KW 25.09.25 07:00:14:716 --- OnCleanUp (прилетел) ----------------- KW 25.09.25 07:00:38:873 #590:TRADER Соединение с сервером восстановлено, ждет 10 сек. подгрузки данных KW 25.09.25 07:00:48:873 #608:TRADER Возобновил работу --- Задержка возможности что-то делать 48 сек. ---- В этой ветке я написал о том, что существующая архитектуре QUIK порождает проблемы. И вот практическое подтверждение этому. Мне потребовалось что-то сделать в начале утренней сессии. Ноут 8 ядер 4 Ггц, SSD-скорость последовательного чтения 3 Гб. В пересчет на флагман советской индустрии БЭСМ-6 (~1000000 операций в сек.) задержка (48 * 1000 сек.) более 13 часов с начала утренней сессии . 1. Что делает QUIK 13 часов? ----- 2. Код в любом месте любого скрипта: for i = 1, 4000000000 do end "обездвиживает" QUIK на 10 секунд (длительность зависит от производительности ПК), он не отвечает. Я понимаю, что такой код писать нехорошо, но как написан QUIK, что зацикливание в пользовательском скрипте полностью его "обездвиживает"? 3. При переключении индикаторов, QUIK на какое-то время впадает в "ступпор". Можно ли сделать так, чтобы этого не было? Или это нерешаемая задача? 4. Перезапуск QUIKа выполняется долго (в пересчете на БЭСМ-6 ~13 часов :)). Как удалось этого добиться ?
Ошибка при поиске пиков\впадин кастом индикатора
Пользователь
Сообщений: Регистрация: 12.05.2020
24.09.2025 12:58:19
Цитата
nikolz написал: Если нравится, можете сказать "спасибо".
Этот индикатор не Kijun-sen. Вы сравнивали его с исправленным, долго работающим индикатором пользователя Roman Koledin? Это же делается просто.
nikolz написал: if i%Settings.kijun_period==0 then max_high = H(i); min_low = L(i) end
ошибка, так как Settings.kijun_period = nil. 2. Вместо скользящей вами предлагается "прыгающая" . Начальные значения каждого периода берутся в качестве экстремумов. Но может быть вы предлагаете свой прыгающий индикатор? ----------- Ниже выложен код реализации индикатора Kijun-sen приблизительно в 3,5 раза более эффективный по времени выполнения, чем то, что выложил Roman Koledin:
Код
Settings = {
Name = "*Kijun-sen_opt",
kijun_period = 26, -- Период Kijun-sen (можно изменить)
line = {{
Name = "Kijun-sen_opt",
Color = RGB(0, 0, 200),
Type = TYPE_LINE,
Width = 2
}}
}
function Init() return 1 end
local kijun_period = Settings.kijun_period
function OnChangeSettings()
kijun_period = Settings.kijun_period
end
---
local TT
local N_C = 500
function OnCalculate(index)
-- -- Вычисление времени обработки свеч --
-- if index == kijun_period + 1 then
-- TT = os.clock()
-- end
-- if index == N_C + kijun_period then
-- message('Kijun-sen. Время обработки ' .. N_C .. ' свечей (млс.) = ' .. (os.clock() - TT) * 1000)
-- end
if index==1 then
max_high = H(1)
min_low = L(1)
else
current_high = H(index)
current_low = L(index)
--------
if current_high > max_high then -- Пришел максимальный
max_high = current_high
else
if index > kijun_period then
-- Ушел из скользящего периода максимальный --
if H(index - kijun_period) >= max_high then -- поиск максимального
max_high = current_high
for j = index - kijun_period + 1, index - 1 do
current_high = H(j)
if current_high > max_high then max_high = current_high end
end
end
end
end
---
if current_low < min_low then -- Пришел минимальный
min_low = current_low
else
if index > kijun_period then
-- Ушел из скользящего периода минимальный --
if L(index - kijun_period) <= min_low then -- поиск минимального
min_low = current_low
for j = index - kijun_period + 1, index - 1 do
current_low = L(j)
if current_low < min_low then min_low = current_low end
end
end
end
end
end
return (max_high + min_low) / 2
end
Ошибка при поиске пиков\впадин кастом индикатора
Пользователь
Сообщений: Регистрация: 12.05.2020
21.09.2025 12:30:32
Цитата
TGB написал: Надо: if index < kijun_period - 1 then
Не убрал 1. Должно: if index < kijun_period then
Ошибка при поиске пиков\впадин кастом индикатора
Пользователь
Сообщений: Регистрация: 12.05.2020
21.09.2025 12:27:38
Цитата
Roman Koledin написал: if index < kijun_period - 1 then
Надо: if index < kijun_period - 1 then. index начинается с 1.
Nikolay написал: циклически организовать проверку числа записей и если оно увеличилось, то считывать вновь пришедшие блоки.
Индекс запсииси в таблице ордеров
Пользователь
Сообщений: Регистрация: 12.05.2020
08.07.2025 11:39:06
Цитата
Nikolay написал: Все же пока это происходит только после OnCleanUp, а не вдруг.
Цитата
Nikolay написал: но назвать это ожидаемым - вряд ли.
------ В функции getItem "плавающая" ошибка при работе с ордерами. Не видны проблемы с ее исправлением. Рабочее место QUIK и сервер это продукты ARQA.
Индекс запсииси в таблице ордеров
Пользователь
Сообщений: Регистрация: 12.05.2020
08.07.2025 00:32:24
Цитата
Nikolay написал:. стоит принять за истину, что теперь терминал не гарантирует в таблицах сохранность порядка записей.
Они "дышат" . Это значит, что функция SearchItems работает некорректно. Она выдает таблицу индексов записей. В какой то момент (например через 3 секунды) эти индексы используются для обращения к записям, а записи могут "разбежаться" . ---- Предложение разработчику QUIK: 1) В таблицы QUIK добавить служебное поле номер записи в таблице и использовать его значение для обеспечения сохранности порядка в таблицах. 2)
Цитата
TGB написал: надо чтобы заявки в таблице появлялись с формированным номером заявки и trans_id;
Поддержка, пожалуйста, "донесите" предложение разработчику.
Вызов getDataSourceInfo() из Init() в Lua индикаторах
В скрипте можно создать любые индикаторы (с полным контролем над ними) с использованием источников (DS), полученных функцией CreateDataSource. Кроме того в ветке представлен модуль подключения в скрипте к индикаторам папки LuaIndicators с готовыми индикаторами с сайта разработчика QUIK.
Индекс запсииси в таблице ордеров
Пользователь
Сообщений: Регистрация: 12.05.2020
03.07.2025 20:25:00
Очередная ветка на тему таблицы заявок, в каком то смысле, продолжение темы:
Пользователям от таблицы заявок (стоп-заявок) надо чтобы: 1) заявки в таблице появлялись с формированным номером заявки и trans_id; 2) индекс заявки, пока она существует обеспечивает прямой доступ к ней и не меняется. Как это будет реализовано дело разработчика QUIK и, вообще, нас не интересует. Сколь угодно быстро, но неправильно работающие программы никому не интересны.
Замечания по реализации в QUIKе обработки заявок (и, наверное стоп-заявок).
Пользователь
Сообщений: Регистрация: 12.05.2020
19.06.2025 09:49:33
Цитата
paluke написал: К примеру, если предполагается, что есть единственный скрипт, работающий с инструментом - все заявки его, trans_id вообще может быть неинтересен.
С этим частным случаем можно согласиться, но все таки QUIK не "живопырка", используемая только в этом частном случае.
Замечания по реализации в QUIKе обработки заявок (и, наверное стоп-заявок).
Пользователь
Сообщений: Регистрация: 12.05.2020
18.06.2025 12:26:44
Цитата
Anton Belonogov написал: Описанные изменения негативным образом скажутся на скорости получения информации терминалом.
1. Зачем пользователю быстро видеть "сырые" данные, которые нельзя использовать непосредственно в своем скрипте? 2. Сам факт многократного обсуждения данной темы пользователями показывает, что в обработке заявок есть проблема. Пользователю все равно приходится выполнять ту работу, которая не реализована разработчиком QUIK, а именно, писать фрагмент учитывающий и обрабатывающий записи заявок без trans_id. Где тут скорость?
Замечания по реализации в QUIKе обработки заявок (и, наверное стоп-заявок).
Пользователь
Сообщений: Регистрация: 12.05.2020
18.06.2025 08:41:23
Цитата
Anton Belonogov написал: Для ускорения передачи информации сервер изначально может отправлять заявки без заполненного trans_id, это не является ошибкой.
Что может делать в скрипте пользователь с заявкой без заполненного trans_id? ----- Есть по крайней мере два варианта реализации того, чтобы пользователь получал заявку всегда с trans_id. 1. Счетчик выдаваемый функцией getNumberOf увеличивается только после заполнения trans_id. 2. Для формирования записей заявок создается буфер, в котором все делается как сейчас в таблице, но записи из буфера сохраняются в таблице заявок только после заполнения trans_id.
Замечания по реализации в QUIKе обработки заявок (и, наверное стоп-заявок).
Пользователь
Сообщений: Регистрация: 12.05.2020
16.06.2025 14:27:32
Цитата
Anton Belonogov написал: По предоставленному описанию не смогли воспроизвести подобную проблему при вызове функции getItem.
Эта ситуация "плавающая" (я ее увидел один раз, но с распечатанными параметрами доступа к таблице), связанная, возможно, с синхронизацией доступа к записям таблицы. У меня нет кода стабильно воспроизводящего эту ситуацию.
Цитата
Anton Belonogov написал: 1. Отсутствие trans_id на исходной записи заявки - корректное поведение. Причины обсуждались на форуме ранее, рекомендуем ознакомиться, например, с этой темой .
Я знаком с этим обсуждением. Там объясняется как сделано сейчас. Но зачем и на основании чего выполняется запись в таблицу заявок без trans_id? Если на основании созданной пользователем транзакции, то в ней trans_id есть.
Замечания по реализации в QUIKе обработки заявок (и, наверное стоп-заявок).
Пользователь
Сообщений: Регистрация: 12.05.2020
11.06.2025 07:20:27
Интересно бы было увидеть ответ поддержки.
limit_kind в таблице depo_limit
Пользователь
Сообщений: Регистрация: 12.05.2020
11.06.2025 07:14:07
Цитата
Anton Belonogov написал: Это взаимоисключающие параметры, сервер транслирует на терминалы только один из них, поэтому смысла в дополнительном параметре для QLua нет.
Не согласен. Разве "Дата предстоящих расчетов" рассчитывается без учета "Режима торгов"? Пожалуйста, объясните какие проблемы возникают у брокера и пользователя, если дополнительно к тому как было (limit_kind - "Режим торгов") транслировалось бы поле (возможно пустое) "Дата предстоящих расчетов"? Может быть разработчик не стал создавать новое поле с целью большой экономии памяти ?
Anton Belonogov написал: limit_kind - это параметр позиции на сервере QUIK, а не параметр инструмента в Торговой системе.Торговые режимы остаются прежними, изменяется только ведение позиций на сервере, что позволяет для каждой позиции видеть даты предстоящих расчетов.
Почему бы не оставить в покое limit_kind (как было)? В чем была проблема завести новое поле "Дату предстоящих торгов"?
Замечания по реализации в QUIKе обработки заявок (и, наверное стоп-заявок).
Пользователь
Сообщений: Регистрация: 12.05.2020
06.06.2025 08:06:25
Цитата
nikolz написал: Возможно, причина в том, что запись в таблицу заявок производится после выхода из колбек
Причина мне не интересна. Я написал как сделать так, чтобы у пользователей было меньше вопросов.