TGB (Все сообщения пользователя)

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

Страницы: 1 2 3 4 5 6 7 8 9 10 11 ... 15 След.
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Цитата
Nikolay написал:
Полная аналогия.
  С довесочком:
 1. Программировать корутины сложнее.
 2.
Цитата
VPM написал:
1   1   29.10.2025   10:31:19   Скрипт запущен. Идёт фоновое измерение производительности...
2   1   29.10.2025   10:31:20   Фон: N=100000, coroutine=584.000 мс (c=100000), func=6.000 мс (f=100000), T1/T2=97.33
 По вашим же тестам накладные расходы на вызов корутин в 97.33 раз больше, чем на вызов функций (coroutine=584.000 мс , func=6.000 мс ). Чтобы для вас было наглядно, при всяком вызове корутины, прежде чем она начнет что-то делать, делается 97 пустых вызовов функций.
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Цитата
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), Нечеткая логика или Система принятия решений в трейдинге
 
Цитата
nikolz написал:
  «Баба-яга против!» :smile:
                        Мультфильм
DestroyTable (и Clear) закрывает скрипт вместо таблицы, Тема описана в Названии и в Тексте сообщения
 
Цитата
paluke написал:
Не только DestroyTable(), любые операции с таблицей не выполняются.
   
Цитата
TGB написал:
Работа с таблицами QUIK выполняется в служебном потоке, отличном от main. В том же, в котором выполняется OnStop. И пока выполняется  OnStop никакие операции с таблицами QUIK не возможны (поток работы с таблицами занят OnStop ).
Если бы я был архитектором QUIK, Что стоило бы изменить в QUIK по-крупному
 
Дополнительно для анализа долгого запуска QUIK:
    1)   https://forum.quik.ru/forum1/topic8621/
    2)   https://forum.quik.ru/forum13/topic7561/
    3)   https://forum.quik.ru/forum1/topic3248/
Если бы я был архитектором QUIK, Что стоило бы изменить в QUIK по-крупному
 
Цитата
Oleg Kuzembaev написал:
Ранее уже ответили вам письмом на почту.
  Здравствуйте. У меня в почте письма нет. Пришлите, пожалуйста повторно.
DestroyTable (и Clear) закрывает скрипт вместо таблицы, Тема описана в Названии и в Тексте сообщения
 
Цитата
nikolz написал:
Если он вызывается в main то вызов это и есть исполнение.
   nikolz писатель  :smile: ?
 Читайте:
Цитата
TGB написал:
она не лезет в таблицы QUIK, а создает коллбек закрытия таблицы, который обрабатывается  в потоке терминала,
Если бы я был архитектором QUIK, Что стоило бы изменить в QUIK по-крупному
 
Цитата
TGB написал:
1) При проверке многократной (> 8 раз) остановки/запуска скрипта, в котором используется сторонний графический пакет IUP, QUIK (версия 12.6.1.2, Lua 5.4), после разного количества экспериментов, в моменты останова/запуска, падает:           Дамп info_dmp_20251007_150748.dmp вышлю почтой.
   На это нет ответа.
----
   Предложения:
     1) После завершения OnStop не обрабатывать только коллбеки, зарегистрированные в main. Коллбеки
       создаваемые в main продолжать отрабатывать (смотрите ветку https://forum.quik.ru/messages/forum10/message79751/topic9265/#message79751).
     2) Реализовать/проверить сихронизацию основного потока QUIK с потоком main при его остановки
     (не обращаться из основного потока к данным завершенного потока).
DestroyTable (и Clear) закрывает скрипт вместо таблицы, Тема описана в Названии и в Тексте сообщения
 
1.
Цитата
nikolz написал:
Полагаю, что не так.
   Зачем полагать, когда можно проверить. Переставьте DestroyTable в OnStop.

2.
Цитата
nikolz написал:
Функция  DestroyTable  в данном примере вызывается в потоке Main.
  Вы точно знаете как устроена DestroyTable?
    Не точно, но скорее всего, это реализовано следующим образом.
    При том, что DestroyTable вызывается в main, она не лезет в таблицы QUIK, а создает коллбек закрытия таблицы, который обрабатывается  в потоке терминала, но он занят более интересным делом  :smile: : остановкой скрипта (удаляет поток main и перестает обрабатывать коллбеки, созданные в нем, так как исчезнет контекст их выполнения).
DestroyTable (и Clear) закрывает скрипт вместо таблицы, Тема описана в Названии и в Тексте сообщения
 
Цитата
Ростислав Дм. Кудряшов написал:
В каком потоке  управления выполняется вызов функции DestroyTable()
  Работа с таблицами QUIK выполняется в служебном потоке, отличном от main. В том же, в котором выполняется OnStop. И пока выполняется  OnStop никакие операции с таблицами QUIK не возможны (поток работы с таблицами занят OnStop ). OnStop в любом случае завершает скрипт, поэтому DestroyTable не выполнена и созданная в скрипте таблица существует после завершения скрипта.
  Если что то надо делать с таблицами по кнопке завершить, то это надо делать в функции OnStop.
DestroyTable (и Clear) закрывает скрипт вместо таблицы, Тема описана в Названии и в Тексте сообщения
 
Цитата
Ростислав Дм. Кудряшов написал:
Версия Quik 12.5.0.20. Код скрипта
   В скрипте реализовано его закрытие при закрытии таблицы:
Цитата
Ростислав Дм. Кудряшов написал:
while not IsWindowClosed (t_id) do
Будет выход из цикла и функции main при закрытии таблицы и это правильно.  
 В данном случае ошибки в Qlua нет.
Если бы я был архитектором QUIK, Что стоило бы изменить в QUIK по-крупному
 
Цитата
Oleg Kuzembaev написал:
В таком случае, пришлите нам архив вашего Рабочего места QUIK на почту поддержки
  Посылал на ваше имя последние настройки QUIK, с которыми проверял длительность его перезапуска.
Если бы я был архитектором QUIK, Что стоило бы изменить в QUIK по-крупному
 
Цитата
Oleg Kuzembaev написал:
В таком случае, пожалуйста, конкретизируйте в чем именно ваш вопрос/пожелание к будущим версиям терминала?
   Пожелание относительно длительности запуска/перезапуска QUIK на работающем ПК с характеристиками 8 ядер, 4 Ггц, память 32 Гб, диск SSD:  <= 3 сек.
Неккоректная работа CreateDataSourse
 
Цитата
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 по-крупному
 
Цитата
Oleg Kuzembaev написал:
В Рабочем месте QUIK существует настройка "Восстанавливать связь автоматически через". Как понятно из ее названия, она позволяет подключиться к торговому серверу снова через заданный       пользователем промежуток времени в случае потери соединения. Настройка "При восстановлении использовать только параметры последнего соединения" позволит подключиться к тому серверу, с которым было утрачено соединение.
   У меня все включено.  QUIK запускается с опцией  -clear.
Если бы я был архитектором QUIK, Что стоило бы изменить в QUIK по-крупному
 
Цитата
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) комментария https://forum.quik.ru/messages/forum10/message74919/topic8563/#message74919. В комментарии https://forum.quik.ru/messages/forum10/message74928/topic8563/#message74928  предлагается вариант реализации п. 2).
В комментарии https://forum.quik.ru/messages/forum10/message74960/topic8563/#message74960 есть предложение, как при реализации п. 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е
 
Цитата
VPM написал:
Сопрограммы в Lua — это мост между двумя мирами:
1. Мир для программиста: Удобный, последовательный, понятный код.
2. Мир для машины: Гибкое, асинхронное, неблокирующее выполнение.
    Написано так красиво :smile: , что я не удержался, чтобы что-нибудь не добавить:
3. Есть задачи, которые могут быть реализованы с использованием сопрограмм проще, чем с использованием только функций. Например, подключение IUP в выложенном вами скрипте.
   Однако, следует учитывать, что сопрограммы (нити - псевдопотоки) отличаются от потоков, в основном, только следующим:
1) они не могут выполняться параллельно;
2) переключение между ними программное (yield), а не внешнее как в потоках (по прерываниям в любом их месте);
3) для их синхронизации не требуются тяжеловесные примитивы (критические секции и т.д.), достаточно использования переменных (так как нет параллелизма).
  При использовании сопрограмм всегда надо помнить: если в нескольких сопрограммах изменяются общие данные, то нужно заниматься их синхронизацией.
 Таким образом, используя сопрограммы вы попадаете в пусть специфическую, но многопоточную среду, почти со всеми проблемами программирования потоков.
 Использование сопрограмм это моделирование многопоточного поведения скрипта в однопоточной среде исполнения.
Программировать сопрограммы сложнее, чем функции. Чем сложнее программа, тем больше в ней ошибок. То что можно сделать просто в виде функций, вряд ли стоит делать на сопрограммах, если это не для развлечения.
Два варианта использования графического пакета IUP (Lua 5.4) в QUIKе
 
Цитата
Ростислав Дм. Кудряшов написал:
Не поленись, а запусти на своём ПК пример переключения спорограмм-корутин между IUP и main(). И убедишься, что невытесняющая (кооперативная) многозадачность порой лучше вытесняющей.
   С этого места, пожалуйста, поподробнее. Как вам удалось сумев запустить единственный готовый пример, определить что он порой лучше вытесняющей многозадачности?  С чем вы его сравнивали? Или вы можете определять лучшее без сравнения? Откуда к вам приходят такие озарения :smile: ? Поделитесь.
Два варианта использования графического пакета IUP (Lua 5.4) в QUIKе
 
1.
Цитата
Ростислав Дм. Кудряшов написал:
Статья не разъясняет, "для чего и как". Поэтому нет причины углубляться в скрипт.
  Где вы в этой ветке прочитали мою статью?
2.
Цитата
Ростислав Дм. Кудряшов написал:
есть и третий способ использования IUP
  Я это читал.
3.
Цитата
Ростислав Дм. Кудряшов написал:
параллельное исполнение скрипта main() и ручных манипуляций в IUP с непрерывной связью между этими нитями (threads) в обоих направлениях.
  Где вы прочитали, что корутины в Lua выполняются параллельно? Интересно, как в одном потоке можно с помощью корутин реализовать параллелизм (одновременность) их выполнения? Но на всякий случай цитата Р. Иерузалимски: "в любой момент времени программа с сопрограммами выполняет только одну из своих сопрограмм".
Два варианта использования графического пакета IUP (Lua 5.4) в QUIKе
 
Цитата
Nikolay написал:
Нет, мне это не надо.
   Согласен, в работающем роботе достаточно возможностей пользовательских таблиц QUIK. Идеальный, зарабатывающий робот должен это делать без вводных и без лишнего вывода, только отчеты о прибыли в журнале с аналитикой, полезной пользователю. Реально, желателен вывод роботом сообщений о наступлении событий, требующих вмешательство пользователя. Все это без проблем реализуемо на таблицах QUIK.
  Графический пакет я использовал для реализации средств создания скриптов, что сделать на таблицах QUIK сложновато.
Два варианта использования графического пакета IUP (Lua 5.4) в QUIKе
 
Цитата
Nikolay написал:
Просто замечание, что если предлагаете какое-то открытое решение, то зачем скрывать код, его подключающее.
 С этим можно бы согласиться, но есть вариант 1, в котором нет скрытых кодов.
Два варианта использования графического пакета IUP (Lua 5.4) в QUIKе
 
Цитата
Nikolay написал:
Я понял про что это библиотека. Я говорил, что нет исходников.

Мною рекомендуется использовать первый вариант и для него пакет QluaUser.dll не требуется.
Два варианта использования графического пакета IUP (Lua 5.4) в QUIKе
 
Цитата
Nikolay написал:
Просто к слову, т.к. используется неизвестная библиотека QluaUser.dll то запускать это не видя исходники будут сложно. По крайней мере мне, не знаю как другим.

Цитата
TGB написал:
-- Вариант 1: запуск IUP в потоке main (надо подключать только IUP, но цикл обработки скрипта программировать
-- в таймере IUP: помечено #### ).
-- Вариант 2: запуск IUP в отдельном потоке отличном от main(кроме IUP, обязательно подключать пакет QluaUser).
--    Вариант 1 более безопасный, чем 2. Так как однопоточный, и не требующий синхронизации диалога с
-- основной работой скрипта.
Два варианта использования графического пакета IUP (Lua 5.4) в QUIKе
 
Инструкция в коде примера:
Код

--- Использование графического пакета 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 по-крупному
 
Цитата
TGB написал:
но реагируют  
 Из текста фрагмента протокола видно, но, наверное, надо пояснить:
     мною в меню "Система > Соединения.. > Восстанавливать связь автоматически"   было указано начало c 6.50.
Если бы я был архитектором QUIK, Что стоило бы изменить в QUIK по-крупному
 
На вопросы в общей постановке, ответа я не вижу.
 1. Отвечать не отвечают, но реагируют  :smile: .
  Протокол начала утренней сессии 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
 
Цитата
Андрей написал:
А уточните, пожалуйста, функция, которую вы упоминаете, финализирует только таблицы? открытые файлы лучше отдельно закрыть?
  У меня все объекты и таблицы и файлы финализируются следующим образом (фрагмент моего кода, обеспечивающего финализацию):
Код
---  Стек объектов финализации (автоматическая финализация) ---
--  В этот стек помещать для финализируемых объектов функции их очистки (сразу при создании объектов) в формате:
--    {<Функция финализации объекта>, {<Параметры финализации объекта через запятую>}};  таблица с параметрами может отсутствовать
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
 
Цитата
Андрей написал:
Видимо придется по одному действию возвращать в обработку остановки бота и смотреть, что приводит к его закрытию.
  Мне пришлось столкнуться с похожей ситуацией когда в одном из скриптом стал использовать таблицы 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). Финализация выполняется при завершении скрипта по любой причине. Это делается с использованием метатаблицы  финализации.
Ошибка при поиске пиков\впадин кастом индикатора
 
Цитата
VPM написал:
bit.band — чистая побитовая операция на целых, выполняется через С-библиотеку, работает на порядок быстрее, особенно если много итераций.
   Вы это проверяли?
   bit.band   это вызов функции, в теле которой выполняется битовая операция "И". Сам вызов до начала выполнения тела функции это довольно тяжелая операция, выполняющаяся дольше любой арифметической операции.
  В Lua 5.4 соотношение длительности выполнения приблизительно следующее:
  1)  %   =  1
  2)  bit.band  = 4,49
  3)  & (битовая операция "И" вместо bit.band , начиная c Lua  5.3) =  0,63
Ошибка при поиске пиков\впадин кастом индикатора
 
Цитата
nikolz написал:
чтобы считал быстрее
  Можете попробовать использовать ранее выложенный мной, но слегка модифицированный код индикатора 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 по-крупному
 
Протокол начала утренней сессии (типичный случай):
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 часов с начала утренней сессии :smile: .
1. Что делает QUIK 13 часов?
-----
2. Код в любом месте любого скрипта:
   for i = 1, 4000000000 do   end
 "обездвиживает" QUIK на 10 секунд (длительность зависит от производительности ПК), он не отвечает. Я понимаю, что такой код писать нехорошо, но как написан QUIK, что зацикливание в пользовательском скрипте полностью его "обездвиживает"?
3. При переключении индикаторов, QUIK на какое-то время впадает в "ступпор". Можно ли сделать так, чтобы этого не было? Или это нерешаемая задача?
4. Перезапуск QUIKа выполняется долго (в пересчете на БЭСМ-6 ~13 часов :)). Как удалось этого добиться :smile: ?
Ошибка при поиске пиков\впадин кастом индикатора
 
Цитата
nikolz написал:
Если нравится, можете сказать "спасибо".
 Этот индикатор не Kijun-sen.
Вы сравнивали его с исправленным, долго работающим индикатором пользователя Roman Koledin?
Это же делается просто.
Ошибка при поиске пиков\впадин кастом индикатора
 
Цитата
nikolz написал:
попробуйте так:
 Вы проверяли то, что предлагаете?
1. В строке
Цитата
nikolz написал:
if i%Settings.kijun_period==0 then  max_high = H(i); min_low = L(i) end
ошибка, так как Settings.kijun_period = nil.
2. Вместо скользящей вами предлагается "прыгающая" :smile: . Начальные значения каждого периода берутся в качестве экстремумов. Но может быть вы предлагаете свой прыгающий индикатор?
-----------
   Ниже выложен код реализации индикатора 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
Ошибка при поиске пиков\впадин кастом индикатора
 
Цитата
TGB написал:
Надо: if index < kijun_period - 1 then
Не убрал 1. Должно:  if index < kijun_period  then
Ошибка при поиске пиков\впадин кастом индикатора
 
Цитата
Roman Koledin написал:
if index < kijun_period - 1 then
Надо: if index < kijun_period - 1 then.   index начинается с 1.
Индекс запсииси в таблице ордеров
 
Хотелось бы увидеть возражения поддержки.
И снова OnAllTrade
 
Цитата
Acaw написал:
данные нужны в постоянном режиме

Цитата
Nikolay написал:
циклически организовать проверку числа записей и если оно увеличилось, то считывать вновь пришедшие блоки.
Индекс запсииси в таблице ордеров
 
Цитата
Nikolay написал:
Все же пока это происходит только после OnCleanUp, а не вдруг.
 
Цитата
Nikolay написал:
но назвать это ожидаемым - вряд ли.
 ------
 В функции getItem "плавающая" ошибка при работе с ордерами. Не видны проблемы с ее исправлением. Рабочее место QUIK и сервер это продукты ARQA.
Индекс запсииси в таблице ордеров
 
Цитата
Nikolay написал:.
стоит принять за истину, что теперь терминал не гарантирует в таблицах сохранность порядка записей.
  Они "дышат" :smile: .
  Это значит, что функция SearchItems работает некорректно. Она выдает таблицу индексов записей. В какой то момент (например через 3 секунды) эти индексы используются для обращения к записям, а записи могут "разбежаться" :smile:.
----
 Предложение разработчику QUIK:
1) В таблицы QUIK добавить служебное поле номер записи в таблице и использовать его значение для обеспечения сохранности порядка в таблицах.
2)
Цитата
TGB написал:
надо чтобы заявки в таблице появлялись с формированным номером заявки и trans_id;

Поддержка, пожалуйста, "донесите" предложение разработчику.
Вызов getDataSourceInfo() из Init() в Lua индикаторах
 
Цитата
Артем написал:
можно как то иначе?
   В скрипте можно создать любые индикаторы (с полным контролем над ними) с использованием источников (DS), полученных функцией CreateDataSource. Кроме того в ветке https://forum.quik.ru/messages/forum10/message76052/topic5466/#message76052 представлен модуль подключения в скрипте к индикаторам папки LuaIndicators с готовыми индикаторами с сайта разработчика QUIK.
Индекс запсииси в таблице ордеров
 
Очередная ветка на тему таблицы заявок, в каком то смысле, продолжение темы: https://forum.quik.ru/messages/forum10/message78826/topic9187/#message78826

 Пользователям от таблицы заявок (стоп-заявок) надо чтобы:
1) заявки в таблице появлялись с формированным номером заявки и trans_id;
2) индекс заявки, пока она существует обеспечивает прямой доступ к ней и не меняется.
 Как это будет реализовано дело разработчика QUIK и, вообще, нас не интересует.
Сколь угодно быстро, но неправильно работающие программы никому не интересны.
Замечания по реализации в QUIKе обработки заявок (и, наверное стоп-заявок).
 
Цитата
paluke написал:
К примеру, если предполагается, что есть единственный скрипт, работающий с инструментом - все заявки его, trans_id вообще может быть неинтересен.
  С этим частным случаем можно согласиться, но все таки QUIK не "живопырка", используемая только в этом частном случае.
Замечания по реализации в QUIKе обработки заявок (и, наверное стоп-заявок).
 
Цитата
Anton Belonogov написал:
Описанные изменения негативным образом скажутся на скорости получения информации терминалом.
   1. Зачем пользователю быстро видеть "сырые" данные, которые нельзя использовать непосредственно в своем скрипте?
   2. Сам факт многократного обсуждения данной темы пользователями показывает, что в обработке заявок есть проблема.
       Пользователю все равно приходится выполнять ту работу, которая не реализована разработчиком QUIK, а именно, писать фрагмент учитывающий и обрабатывающий записи заявок без trans_id.  Где тут скорость?
Замечания по реализации в QUIKе обработки заявок (и, наверное стоп-заявок).
 
Цитата
Anton Belonogov написал:
Для ускорения передачи информации сервер изначально может отправлять заявки без заполненного trans_id, это не является ошибкой.
  Что может делать в скрипте пользователь с заявкой без заполненного trans_id?
-----
 Есть по крайней мере два варианта реализации того, чтобы пользователь получал заявку всегда с trans_id.
   1. Счетчик выдаваемый функцией getNumberOf увеличивается только после заполнения trans_id.
   2. Для формирования записей заявок создается буфер, в котором все делается как сейчас в таблице, но записи из буфера сохраняются  в таблице заявок только после заполнения trans_id.
Замечания по реализации в QUIKе обработки заявок (и, наверное стоп-заявок).
 
Цитата
Anton Belonogov написал:
По предоставленному описанию не смогли воспроизвести подобную проблему при вызове функции getItem.
   Эта ситуация "плавающая" (я ее увидел один раз, но с распечатанными параметрами доступа к таблице), связанная, возможно, с синхронизацией доступа к записям таблицы. У меня нет кода стабильно воспроизводящего эту ситуацию.

Цитата
Anton Belonogov написал:
1. Отсутствие trans_id на исходной записи заявки - корректное поведение. Причины обсуждались на форуме ранее, рекомендуем ознакомиться, например, с  этой темой .
  Я знаком с этим обсуждением. Там объясняется как сделано сейчас. Но зачем и на основании чего выполняется запись в таблицу заявок без trans_id?  Если на основании созданной пользователем транзакции, то в ней trans_id есть.
Замечания по реализации в QUIKе обработки заявок (и, наверное стоп-заявок).
 
Интересно бы было увидеть ответ поддержки.
limit_kind в таблице depo_limit
 
Цитата
Anton Belonogov написал:
Это взаимоисключающие параметры, сервер транслирует на терминалы только один из них, поэтому смысла в дополнительном параметре для QLua нет.
  Не согласен. Разве  "Дата предстоящих расчетов" рассчитывается без учета "Режима торгов"?
Пожалуйста, объясните какие проблемы возникают у брокера и пользователя, если дополнительно к тому как было (limit_kind - "Режим торгов") транслировалось бы поле (возможно пустое) "Дата предстоящих расчетов"? Может быть разработчик не стал создавать новое поле с целью большой экономии памяти :smile: ?
limit_kind в таблице depo_limit
 
Цитата
TGB написал:
"Дату предстоящих торгов"
  Читать: "Дату предстоящих расчетов"
limit_kind в таблице depo_limit
 
Цитата
Anton Belonogov написал:
limit_kind - это параметр позиции на сервере QUIK, а не параметр инструмента в Торговой системе.Торговые режимы остаются прежними, изменяется только ведение позиций на сервере, что позволяет для каждой позиции видеть даты предстоящих расчетов.
 Почему бы не оставить в покое limit_kind (как было)? В чем была проблема завести новое поле "Дату предстоящих торгов"?
Замечания по реализации в QUIKе обработки заявок (и, наверное стоп-заявок).
 
Цитата
nikolz написал:
Возможно,  причина в том, что запись в таблицу заявок производится после выхода из колбек
    Причина мне не интересна. Я написал как сделать так, чтобы у пользователей было меньше вопросов.
Страницы: 1 2 3 4 5 6 7 8 9 10 11 ... 15 След.
Наверх