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

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

Страницы: 1 2 3 4 5 6 7 8 9 10 След.
Может ли такое быть
 
Может такое быть. Был некий стакан с неким значением ask, кто-то согласился на такую цену и ударил по ней рыночной заявкой. Потом участники рынка отозвали некоторые заявки из стакана и поставили новые; сделок при этом не произошло. В результате значение ask стало другим, уменьшилось. Потом кто-то из участников торговли согласился на такую цену и ударил по ней рыночной заявкой. Так может реализоваться описанный Вами выше сценарий.
SetCell crash, Устновка цветов не по порядку вызывает краш Quik а
 
По хорошему, надо, чтобы разработчики терминала ответили на поставленные выше вопросы. Пока что кажется, что это баг терминала, раз не проверяются null при освобождении ресурсов в Вашем случае.
Как заполняется размер таблицы исторических свечей ?
 
Я обычно делаю цикл, который ждёт, пока ds:Size() не станет положительным, после чего работаю с данными, которые там появились. На практике кажется, что приходят сразу все свечи, которые есть в наличии у терминала.
Помогите написать скрипт на актуальном языке Lua
 
Наконец, можно ещё учесть, что скрипт должен работать только по будням в какой-то промежуток времени. Для этого написать в конце конфига:
Код
filename = "D:/last_quotes.txt"
pauseDurationMillis = 10000
sleepDurationMillis = 250
startExportHHMM = 0900
stopExportHHMM = 2300

dofile(getScriptPath() .. "/ParamExportCode.lua")

и изменить код, начиная с OnStop(), в файле с кодом:
Код
local function isExportTime()
    local dt = os.sysdate()
    local hhmm = dt.hour * 100 + dt.min
    return startExportHHMM <= hhmm and hhmm < stopExportHHMM and 1 <= dt.week_day and dt.week_day <= 5
end

function OnStop()
    isInterrupted = true
end

function main()
    message("Export started.", 1)
    requestParams()
    while not isInterrupted do
        if isExportTime() then
            exportQuotes()
        end
        pause(pauseDurationMillis)
    end
    message("Export stopped.", 1)
end
Помогите написать скрипт на актуальном языке Lua
 
С учётом высказанных пожеланий.

1) Создаём два файла. В одном описываются настройки и вызывается второй файл, содержащий код. Оба файла должны лежать в одной папке. Запускать надо ParamExportConfig.lua.

Файл ParamExportConfig.lua:
Код
--- Функция для условного форматирования: до момента hhmm используется format1, после -- format2
local function formatHHMM(hhmm, format1, format2)
    return function()
        local dt = os.sysdate()
        if dt.hour * 100 + dt.min < hhmm then          
            return format1
        else
            return format2
        end
    end
end

-- Настройки для вывода котировок
securities = {
    {
        line = "GAZ ----\n", -- в конце перевод строки
    },
    {
        classCode = "SPBFUT",
        secCode = "BRF3",
        params = {
            { param = "last", format = "BRENT %.2f ", }, -- в конце пробел-разделитель
            { param = "lastChange", format = "OIL %.1f\n", }, -- в конце перевод строки
        },
    },
    {
        classCode = "SPBFUT",
        secCode = "GDZ2",
        params = {
            { param = "last", format = "GOLD %.1f ", },
            { param = "lastChange", format = "%.2f\n", }, 
        },
    },
    { 
        classCode = "TQBR",
        secCode = "GAZP",
        params = { 
            { param = "last", format = "GAZP %.2f ", },
        },
    },
    { 
        classCode = "TQBR",
        secCode = "SBER",
        params = {
            { param = "last", format = "SBER %.2f\n", },
        },
    },
    { 
        classCode = "TQBR",
        secCode = "AFLT",
        params = { 
            { param = "last", format = "AFLT %.2f ", }, 
        },
    },
    { 
        classCode = "TQBR",
        secCode = "GMKN",
        params = {
            { param = "last", format = "GMKN %.0f\n", }, 
        },
    },
    { 
        classCode = "TQBR",
        secCode = "MGNT",
        params = { 
            { param = "last", format = formatHHMM(1837, "MGNT --\n", "MGNT %.1f\n"), }, 
        },
    },
    { 
        classCode = "TQBR",
        secCode = "MOEX",
        params = { 
            { param = "last", format = formatHHMM(1837, "", "MOEX %.2f\n"), }, 
        },
    },
}

filename = "D:/last_quotes.txt"
pauseDurationMillis = 10000
sleepDurationMillis = 250

dofile(getScriptPath() .. "/ParamExportCode.lua")


Файл ParamExportCode.lua:
Код
local isInterrupted = false
local file

local function valueOf(x)
    return type(x) == "function" and x() or x
end

local function requestParams()
    for _, security in ipairs(securities) do
        if type(security.params) == "table" then
            for _, securityParams in ipairs(security.params) do
                if not ParamRequest(security.classCode, security.secCode, securityParams.param) then
                    message("Cannot request: "
                            .. tostring(security.classCode) .. ", "
                            .. tostring(security.secCode) .. ", "
                            .. tostring(securityParams.param), 2)
                end
            end
        end
    end
end

local function exportQuotesForSecurity(security)
    if type(security.line) == "string" then
        file:write(tostring(security.line))
    elseif type(security.params) == "table" then
        for i, securityParams in ipairs(security.params) do
            local paramEx = getParamEx(security.classCode, security.secCode, securityParams.param)
            if paramEx.result == "1" then
                file:write(string.format(valueOf(securityParams.format), paramEx.param_value))
            else
                message("Cannot export: "
                        .. tostring(security.classCode) .. ", "
                        .. tostring(security.secCode) .. ", "
                        .. tostring(securityParams.param), 2)
            end
        end
    end
end

local function exportQuotes()
    file = io.open(filename, "w+")
    if file then
        for _, security in ipairs(securities) do
            exportQuotesForSecurity(security)
        end
        file:close()
    end
end

local function pause(durationMillis)
    while durationMillis > 0 and not isInterrupted do
        sleep(math.min(durationMillis, sleepDurationMillis))
        durationMillis = durationMillis - sleepDurationMillis
    end
end

function OnStop()
    isInterrupted = true
end

function main()
    message("Export started.", 1)
    requestParams()
    while not isInterrupted do
        exportQuotes()
        pause(pauseDurationMillis)
    end
    message("Export stopped.", 1)
end


2) Добавлена функция для реализации форматирования в зависимости от времени formatHHMM. В примере конфига для MGNT выводим прочерк до указанного момента времени и цену в остальное время, для MOEX не выводим ничего (пустая строка) до указанного момента и цену в остальное время. Возможно, придётся доработать эту функцию, чтобы указать время перехода с format2 на format1 (сейчас это полночь). В os.sysdate() используется локальное время компа.

3) По-моему, этого кода должно быть достаточно для реализации всех пожеланий. Пробуйте.
Помогите написать скрипт на актуальном языке Lua
 
Цитата
nikolz написал:
Я бы вообще бы вынес описание инструментов в текстовый файл,
чтобы можно было менять набор не зная луа и не редактируя скрипт.
К этому уже всё идёт. :)
Помогите написать скрипт на актуальном языке Lua
 
В предыдущем скрипте можно упростить описание массива инструментов: префиксы, суффиксы, разделители, переводы строки и название инструмента поместить в строку format. Так получается компактнее. Функционал не должен пострадать. Неудобство может возникнуть только если придётся экранировать какие-либо символы в названии инструмента (скажем, если в названии присутствует знак процента или ещё что-то в этом рода).

Код
local securities = {
    {
        classCode = "SPBFUT",
        secCode = "BRF3",
        params = {
            { param = "last", format = "BRENT %.2f ", }, -- название пишем прямо в строке format, в конце добавляем пробел
            { param = "lastChange", format = "OIL %.1f\n", }, -- тут в конце строки format добавляем перевод строки
        },
    },
    {
        classCode = "SPBFUT",
        secCode = "GDZ2",
        params = {
            { param = "last", format = "GOLD %.1f ", },
            { param = "lastChange", format = "%.2f\n", }, 
        },
    },
    { 
        classCode = "TQBR",
        secCode = "GAZP",
        params = { 
            { param = "last", format = "GAZP %.2f ", }, -- в конце пробел, чтобы отделить от следующего инструмента 
        },
    },
    { 
        classCode = "TQBR",
        secCode = "SBER",
        params = {
            { param = "last", format = "SBER %.2f\n", }, -- в конце перевод строки
        },
    },
    { 
        classCode = "TQBR",
        secCode = "AFLT",
        params = { 
            { param = "last", format = "AFLT %.2f ", }, 
        },
    },
    { 
        classCode = "TQBR",
        secCode = "GMKN",
        params = {
            { param = "last", format = "GMKN %.0f\n", }, 
        },
    },
}

local filename = "D:/last_quotes.txt"
local pauseDurationMillis = 10000
local sleepDurationMillis = 250
local isInterrupted = false
local file

local function requestParams()
    for _, security in ipairs(securities) do
        for _, securityParams in ipairs(security.params) do
            if not ParamRequest(security.classCode, security.secCode, securityParams.param) then
                message("Не удалось заказать: "
                    .. tostring(security.classCode) .. ", "
                    .. tostring(security.secCode) .. ", "
                    .. tostring(securityParams.param), 2)
            end
        end
    end
end

local function exportQuotesForSecurity(security)
    for i, securityParams in ipairs(security.params) do
        local paramEx = getParamEx(security.classCode, security.secCode, securityParams.param)
        if paramEx.result == "1" then
            file:write(string.format(securityParams.format, paramEx.param_value))
        else
            message("Не удалось экспортировать: "
                .. tostring(security.classCode) .. ", "
                .. tostring(security.secCode) .. ", "
                .. tostring(securityParams.param), 2)
        end
    end
end

local function exportQuotes()
    file = io.open(filename, "w+")
    if file then
        for _, security in ipairs(securities) do
            exportQuotesForSecurity(security)
        end
        file:close()
    end
end

local function pause(durationMillis)
    while durationMillis > 0 and not isInterrupted do
        sleep(math.min(durationMillis, sleepDurationMillis))
        durationMillis = durationMillis - sleepDurationMillis
    end
end

function OnStop()
    isInterrupted = true
end

function main()
    message("Скрипт экспорта котировок запущен.", 1)
    requestParams()
    while not isInterrupted do
        exportQuotes()
        pause(pauseDurationMillis)
    end
    message("Скрипт экспорта котировок остановлен.", 1)
end

Помогите написать скрипт на актуальном языке Lua
 
При использовании скрипта надо обращать внимание, что в файле с кодом используется кодировка CP1251, иначе вместо русских букв будут кракозябры. Либо всё по-английски писать:
Cannot request parameter:
Cannot export:
Script started.
Script stopped.
Помогите написать скрипт на актуальном языке Lua
 
Наблюдаем в прямом эфире рождение чёткого ТЗ от заказчика :)

Цитата
Как переформатировать вывод что бы бумаги с доп секцией lastchange  оставить на отдельной строке, а "обычные" акции сделать по две на строку  как в примере ниже:

Примерно так:

Код
local securities = {
    {
        classCode = "SPBFUT",
        secCode = "BRF3",
        params = {
            { prefix = "", name = "BRENT", delimiter = " ", param = "last", format = "%.2f", suffix = " ", },
            { prefix = "", name = "OIL", delimiter = " ", param = "lastChange", format = "%.1f", suffix = "\n", }, 
        },
    },
    {
        classCode = "SPBFUT",
        secCode = "GDZ2",
        params = {
            { prefix = "на всякий случай :) ", name = "GOLD", delimiter = " ", param = "last", format = "%.1f", suffix = " ", },
            { prefix = "", name = "золото", delimiter = " ", param = "lastChange", format = "%.2f", suffix = "\n", }, 
        },
    },
    { 
        classCode = "TQBR",
        secCode = "GAZP",
        params = { 
            { prefix = "", name = "GAZP", delimiter = " ", param = "last", format = "%.2f", suffix = " ", }, 
        },
    },
    { 
        classCode = "TQBR",
        secCode = "SBER",
        params = {
            { prefix = "", name = "SBER", delimiter = " ", param = "last", format = "%.2f", suffix = "\n", }, 
        },
    },
    { 
        classCode = "TQBR",
        secCode = "AFLT",
        params = { 
            { prefix = "", name = "AFLT", delimiter = " ", param = "last", format = "%.2f", suffix = " ", }, 
        },
    },
    { 
        classCode = "TQBR",
        secCode = "GMKN",
        params = {
            { prefix = "", name = "GMKN", delimiter = " ", param = "last", format = "%.0f", suffix = "\n", }, 
        },
    },
}

local filename = "D:/last_quotes.txt"
local pauseDurationMillis = 10000
local sleepDurationMillis = 250
local isInterrupted = false
local file

local function requestParams()
    for _, security in ipairs(securities) do
        for _, securityParams in ipairs(security.params) do
            if not ParamRequest(security.classCode, security.secCode, securityParams.param) then
                message("Не удалось заказать: "
                    .. tostring(security.classCode) .. ", "
                    .. tostring(security.secCode) .. ", "
                    .. tostring(securityParams.param), 2)
            end
        end
    end
end

local function exportQuotesForSecurity(security)
    for i, securityParams in ipairs(security.params) do
        local paramEx = getParamEx(security.classCode, security.secCode, securityParams.param)
        if paramEx.result == "1" then
            file:write(
                securityParams.prefix or "",
                securityParams.name or "",
                securityParams.delimiter or " ",
                string.format(securityParams.format, paramEx.param_value), 
                securityParams.suffix or "")
        else
            message("Не удалось экспортировать: "
                .. tostring(security.classCode) .. ", "
                .. tostring(security.secCode) .. ", "
                .. tostring(securityParams.param), 2)
        end
    end
end

local function exportQuotes()
    file = io.open(filename, "w+")
    if file then
        for _, security in ipairs(securities) do
            exportQuotesForSecurity(security)
        end
        file:close()
    end
end

local function pause(durationMillis)
    while durationMillis > 0 and not isInterrupted do
        sleep(math.min(durationMillis, sleepDurationMillis))
        durationMillis = durationMillis - sleepDurationMillis
    end
end

function OnStop()
    isInterrupted = true
end

function main()
    message("Скрипт экспорта котировок запущен.", 1)
    requestParams()
    while not isInterrupted do
        exportQuotes()
        pause(pauseDurationMillis)
    end
    message("Скрипт экспорта котировок остановлен.", 1)
end

Помогите написать скрипт на актуальном языке Lua
 
Цитата
Скрипт в второй редакции просто отличный, компактный. Работает очень быстро.

С чего бы ему медленно работать, тут же все очень быстро происходит.

Цитата
Не такой популярный язык LUA, обзвонил всех знакомых кто в IT, ни кто  этот язык не знает... интуитивно  обычной логикой тоже наскоком его не  понять.

По-хорошему, конечно, надо бы почитать книгу какую-то по этому языку. Жаль, что с IT окружением не задалось.

Код
local securities = {
    { 
        classCode = "TQBR",
        secCode = "SBER",
        params = {
            { name = "SBER", param = "last", format = "%.2f", }, 
            { name = "Сбер", param = "lastChange", format = "%.1f", }, 
        },
    },
    { 
        classCode = "TQBR",
        secCode = "GAZP",
        params = { 
            { name = "GAZP", param = "last", format = "%.2f", }, 
        },
    },
    {
        classCode = "SPBFUT",
        secCode = "BRF3",
        params = {
            { name = "BR", param = "last", format = "%.2f", },
            { name = "OIL", param = "lastChange", format = "%.2f", }, 
        },
    },
}

local filename = "D:/last_quotes.txt"
local pauseDurationMillis = 10000
local sleepDurationMillis = 100
local isInterrupted = false
local file

local function requestParams()
    for _, security in ipairs(securities) do
        for _, securityParams in ipairs(security.params) do
            ParamRequest(security.classCode, security.secCode, securityParams.param)
        end
    end
end

local function exportQuotesForSecurity(security)
    for i, securityParams in ipairs(security.params) do
        local paramEx = getParamEx(security.classCode, security.secCode, securityParams.param)
        if paramEx.result == "1" then
            if i > 1 then
                file:write(" ")
            end
            file:write(securityParams.name, " ", string.format(securityParams.format, paramEx.param_value))
        end
    end
    file:write("\n")
end

local function exportQuotes()
    file = io.open(filename, "w+")
    if file then
        for _, security in ipairs(securities) do
            exportQuotesForSecurity(security)
        end
        file:close()
    end
end

local function pause(durationMillis)
    while durationMillis > 0 and not isInterrupted do
        sleep(math.min(durationMillis, sleepDurationMillis))
        durationMillis = durationMillis - sleepDurationMillis
    end
end

function OnStop()
    isInterrupted = true
end

function main()
    requestParams()
    while not isInterrupted do
        exportQuotes()
        pause(pauseDurationMillis)
    end
end

Помогите написать скрипт на актуальном языке Lua
 
Цитата
Пробовал сам так сделать, но пока не работает...

Беда...

Код
local securities = {
  { classCode = "TQBR", secCode = "SBER", },
  { classCode = "TQBR", secCode = "GAZP", },
  { classCode = "SPBFUT", secCode = "LKZ2", }
}

local param = "last"
local filename = "D:/last_quotes.txt"
local pauseDurationMillis = 10000
local sleepDurationMillis = 100
local isInterrupted = false
local file

local function requestParams()
    for _, security in ipairs(securities) do
        ParamRequest(security.classCode, security.secCode, param)
    end
end

local function exportQuote(security)
    local paramEx = getParamEx(security.classCode, security.secCode, param)
    if paramEx.result == "1" then
        file:write(security.secCode, " ", tostring(paramEx.param_value), "\n")
    end
end

local function exportQuotes()
    file = io.open(filename, "w+")
    if file then
        for _, security in ipairs(securities) do
            exportQuote(security)
        end
        file:close()
    end
end

local function pause(durationMillis)
    while durationMillis > 0 and not isInterrupted do
        sleep(math.min(durationMillis, sleepDurationMillis))
        durationMillis = durationMillis - sleepDurationMillis
    end
end

function OnStop()
    isInterrupted = true
end

function main()
    requestParams()
    while not isInterrupted do
        exportQuotes()
        pause(pauseDurationMillis)
    end
end

Помогите написать скрипт на актуальном языке Lua
 
Без разницы, я использую 5.4.1.
Помогите написать скрипт на актуальном языке Lua
 
Можно начать вот с этого примера, который сохраняет цену last для GAZP в файл в корне диска D:

Код
local classCode = "TQBR"
local secCode = "GAZP"
local param = "last"
local filename = "D:/" .. classCode .. "_" .. secCode .. ".txt"
local pauseDurationMillis = 10000
local sleepDurationMillis = 100
local isInterrupted = false

local function printValue(value)
    local file = io.open(filename, "w+")
    if file then
        file:write(tostring(value))
        file:close()
    end
end

local function exportParam()
    local paramEx = getParamEx(classCode, secCode, param)
    if paramEx.result == "1" then
        printValue(paramEx.param_value)
    end
end

local function pause(durationMillis)
    while durationMillis > 0 and not isInterrupted do
        sleep(math.min(durationMillis, sleepDurationMillis))
        durationMillis = durationMillis - sleepDurationMillis
    end
end

function OnStop()
    isInterrupted = true
end

function main()
    ParamRequest(classCode, secCode, param)
    while not isInterrupted do
        exportParam()
        pause(pauseDurationMillis)
    end
end
Quik для Astra Linux
 
Цитата
Anton Belonogov написал:
_sk_, добрый день.
Цитата
1) Производительность каких-то операций ввода-вывода терминала сильно падает (видно, как заметно медленнее прокачиваются все обезличенные сделки). Не знаю, эмулятор ли тут виноват или сам терминал так написано, но факт есть. Если будет не SSD, а HDD использоваться -- всё ещё хуже.
Уточните, пожалуйста, помимо проблем с обезличенными сделками, проявляется ли каким-либо еще образом снижение производительности?
Рекомендуем Вам выполнить следующие настройки:
- Основные настройки (F9) / Программа / Получение данных: Интервал обновления данных с текущим состоянием - Запрашивать данные раз в 1 сек.;
- Основные настройки (F9) / Программа / Получение данных / Котировки : Формировать список обновляемых инструментов и параметров - "умным" заказом данных;
- Основные настройки (F9) / Программа / Сохранение данных: Сохранять для получаемых инструментов и параметров - Только данные, отражающие текущее состояние.
Просьба сообщить, помогут ли данные настройки решить проблему низкой производительности.
Цитата
2) Есть баг в функции os.sysdate(), который проявляется ТОЛЬКО под wine. Выглядит как будто иногда (раз на несколько тысяч вызовов) не учитывается временной пояс. Вроде, можно с этим программно бороться внутри QLua-скриптов, но не факт, что только в скриптах эта проблема вылезает.
Просим Вас подробнее описать данную проблему, а также прислать скриншоты и скрипт, при выполнении которого наблюдается указанное поведение. Фалйы можно направить на нашу почту  quiksupport@arqatech.com .
Цитата
3) Иногда есть проблемы со свечными графиками. Они перестают получать новые свечи, пока не перезакажешь данные. Возможно, что причиной является п.2.
Уточните, пожалуйста, речь идет о графиках, созданных с помощью QLua, или об обычных графиках? Пришлите, пожалуйста, скриншот данной проблемы.
Цитата
4) Если одновременно запускать несколько скриптов, то заметно раньше появится проблема производительности. Она и под Windows есть, а под Linux вылезает ещё быстрее.
Уточните, пожалуйста, какие скрипты запускаются? Как именно проявляется проблема производительности?

Что касается разработки QUIK для ОС Linux, в настоящий момент мы не можем поделиться какими-либо новыми сведениями по этой теме. Если данное ПО будет выпущено, соответствующая новость появится  на сайте:  https://arqatech.com/ru/about/news/

Не знаю, зачем я это пишу, ведь вряд ли что-то изменится.

1) При запуске в терминале десятка торговых скриптов, которые примерно раз в секунду выводят данные в таблицы, созданные с помощью QLua  имеющие размеры порядка 10 столбцов и 20-50 строк, приводят к тормозам. Проблема в том, что операции на отрисовку графического интерфейса встают в общую очередь в терминале, при этом возникает live lock.

2) Скриншот делать бессмысленно. Код примерно такой:
Код
function main()  while true do    local t1 = os.time()    local dt = os.sysdate()
    local t2 = os.time(dt)    if math.abs(t1 - t2) > 1 then        message(tostring(t1) .. "; " .. tostring(t2), 2)
    end
  end
end
Под Windows таких проблем нет. В описанном мною выше эмуляторе wine под Ubuntu 20.04 есть.


3) Речь идёт о свечных графиках внутри терминала. У нас такие ошибки были, в основном, на графиках акций СПБиржи.

4) См. п.1. Проблема производительности в том, что отзывчивость GUI падает.
Quik для Astra Linux
 
Под "Астрой" не пробовал устанавливать связку wine + QUIK, а вот под Ubuntu 20.04 пробовал связку  wine 7.0 + QUIK 9.5.0.42.

Использовалась виртуалка под QEMU/KVM с образом диска на SSD и относительно неплохим процессором Ryzen 3600 на хост-системе.

Есть следующие проблемы:

1) Производительность каких-то операций ввода-вывода терминала сильно падает (видно, как заметно медленнее прокачиваются все обезличенные сделки). Не знаю, эмулятор ли тут виноват или сам терминал так написано, но факт есть. Если будет не SSD, а HDD использоваться -- всё ещё хуже.

2) Есть баг в функции os.sysdate(), который проявляется ТОЛЬКО под wine. Выглядит как будто иногда (раз на несколько тысяч вызовов) не учитывается временной пояс. Вроде, можно с этим программно бороться внутри QLua-скриптов, но не факт, что только в скриптах эта проблема вылезает.

3) Иногда есть проблемы со свечными графиками. Они перестают получать новые свечи, пока не перезакажешь данные. Возможно, что причиной является п.2.

4) Если одновременно запускать несколько скриптов, то заметно раньше появится проблема производительности. Она и под Windows есть, а под Linux вылезает ещё быстрее.

По совокупности проблем мы не смогли запустить серьёзный алготрейдинг в связке linux + wine. Так, по мелочи можно, чтобы сэкономить на лицензиях для Windows.


В целом, конечно, хотелось бы терминал для Linux хоть в каком-то нативном виде.
Медленный вывод в таблицы QLua через SetCell
 
Ясно. Спасибо за попытку.
Медленный вывод в таблицы QLua через SetCell
 
Выскажу гипотезу, почему так получается с низкой скоростью отрисовки, и немного порассуждаю. Возможно, что я не прав.

Скрипты вызывают функцию SetCell в потоке main, а отрисовку терминал должен делать в потоке коллбэков, поэтому сразу несколько скриптов синхронизируются на одном мониторе. Вызовов SetCell, на самом деле, много (циклы и одновременно запущенные скрипты) и из-за этой постоянно требующейся синхронизации имеем тормоза.

Можно как-то снижать затраты на синхронизацию. Например, если бы была удобная возможность дать из потока main задачу для исполнения в потоке коллбэков, можно было бы реализовать отрисовку таблицы большим блоком, который выполнился бы быстрее, чем куча мелких задач. Что-то типа executeAsCallback на этом форуме уже обсуждали (https://forum.quik.ru/messages/forum10/message50396/topic5983/#message50396)

Но если просто починят SetCell, чтобы эта и, возможно, аналогичные функции стали существенно быстрее, тоже будет хорошо.
Медленный вывод в таблицы QLua через SetCell
 
Спасибо за ответ.

Раз вы смогли увидеть медленную отрисовку Lua-таблиц, это уже очень хорошо, т.к. обозначенную в посте проблему можно реально воспроизвести и постараться устранить.

Когда я писал про повышенную нагрузку на CPU, то имел в виду, что процесс терминала QUIK загружает ПО МАКСИМУМУ одно ядро процессора, хотя современное железо должно справляться с такой интенсивностью вывода на экран с меньшей нагрузкой. Я не знаю, сколько ядер в машине, на которой сделаны прилагаемые скриншоты, но 11.2% уже близко к границе для 8-ядерного компьютера (100% / 8 ядер = 12.5%).

Предлагаю считать, что если разобраться с медленной отрисовкой, то и проблема, которую я обозначил как повышенная нагрузка на CPU, будет решена.
[BUG] Повышенная загрузка CPU при большом количестве функций в скрипте
 
Просьба к разработчикам терминала написать адекватные ответы на вопросы, поднятые по существу этой темы.
Медленный вывод в таблицы QLua через SetCell
 
Я видел, что как минимум 2 представителя "Арки" читали эту тему. Хотелось бы увидеть ответ на заданный вопрос.
Откуда лучше взять тиковые данные в Lua?
 
Первый ответ на Ваш вопрос в теме был корректным.

ТТТ -- это аббревиатура от "Таблица текущих торгов".
Обезличенные сделки в квике
 
Вам была продемонстрирована наглядная иллюстрация качества работы техподдержки.
Медленный вывод в таблицы QLua через SetCell
 
При использовании приведённых ниже демонстрационных скриптов наблюдается повышенная нагрузка на CPU и медленный вывод содержимого в таблицы QLua. При этом вывод в заголовки окон этих таблиц производится нормально. Просьба проверить оптимальность реализации отрисовки содержимого таблиц. Используется светлая тема терминала 9.3.3.3, на тёмной не проверялось, наверное, ещё хуже будет.

В течение 7 дней можно скачать нужные демо-файлы по ссылке: https://dropmefiles.com/cNAAw  Описание приводится ниже.

Файлы RunDemo1.lua, ...m RunDemo9.lua каждый имеет свои настройки и запускают общий файл Demo.lua. Каждый скрипт выводит окно и периодически с некоторым таймаутом, заданным в Demo.lua, обновляет свою таблицу на экране. Скрипты надо запускать одновременно.

Просьба к разработчикам ответить на вопрос: считается ли такая скорость отрисовки нормальной или её стоит оптимизировать?

Файл Demo.lua:
Код
---
--- Настройки заданы в переменной config, которая к моменту запуска уже определена.
---

local interrupted = false
local tableId
local timeout = 20 -- можно уменьшать, чтобы проблема стала более явной
local nRow = 30 -- количество строк в таблице, можно увеличивать, чтобы проблема стала более явной
local nCol = 10 -- количество столбцов в таблице, можно увеличивать, чтобы проблема стала более явной

function OnInit(scriptPath)
    tableId = AllocTable()
    for colId = 1, nCol do
        AddColumn(tableId, colId, "#" .. colId, true, QTABLE_STRING_TYPE, 20)
    end
end

function OnStop()
    interrupted = true
    local tId = tableId
    tableId = nil
    if tId then
        DestroyTable(tId)
    end
end

function updateTable()
    if tableId == nil then
        return
    end
    if IsWindowClosed(tableId) then
        CreateWindow(tableId)
        SetWindowPos(tableId, config.x, config.y, config.dx, config.dy)
        for rowId = 1, nRow do
            InsertRow(tableId, rowId)
        end
    end
    local dt = os.date(" %Y-%m-%d %X", os.time())
    SetWindowCaption(tableId, config.name .. dt)
    for rowId = 1, nRow do
        for colId = 1, nCol do
            SetCell(tableId, rowId, colId, dt)
        end
    end
end

function main()
    while not interrupted do
        updateTable()
        sleep(timeout)
    end
end



Файл RunDemo1.lua:
Код
---
--- Этот скрипт нужно запустить.
---

config = {
    name = "RunDemo1",
    x = 0,
    y = 0,
    dx = 1400,
    dy = 100,
}
dofile(getScriptPath() .. "/Demo.lua")

Файл RunDemo2.lua:
Код
---
--- Этот скрипт нужно запустить.
---

config = {
    name = "RunDemo2",
    x = 0,
    y = 100,
    dx = 1400,
    dy = 100,
}
dofile(getScriptPath() .. "/Demo.lua")

Содержимое файлов 3-9 аналогично, отличаются только y-координаты окна.
[BUG] Повышенная загрузка CPU при большом количестве функций в скрипте
 
Цитата
Упомянутый код демонстрирует проблему в QUIK 9.3.1.11. В QUIK 9.3.3.3 QLua 5.4 эта конкретная проблема устранена.
Это хорошо. Полагаю, что разработчики это тоже подтвердили бы, если бы провели разбор проблемы качественно.

Цитата
...  если в колбеках, есть обращение к функциям API QLua, то все запущенные  скрипты рабочего места QUIK, могут выстраиваться в очередь к  синхронизуемым ресурсам QUIK (по которым в ранних версиях QUIK, возможно  синхронизации вообще не было), что эквивалентно их работе в одном  потоке.

Вот как раз похоже на такое поведение. Конкретно у меня в коллбэках минимальные действия и очереди, передающие данные в main, но в самом main остаётся периодический вывод информации в таблицы (имеются в виду окна, создаваемые из скриптов), а их отрисовка опять идёт через поток коллбэков и начинаются тормоза.

Цитата
Правильно я понимаю, что у Вас три терминала КВИК работают и каждый сделал по 12 потоков, а у Вас всего 8 ядер ?

Нет. В процессоре всего имеется 8 ядер. Каждый из 3-х терминалов грузит полностью одно ядро процессора (архитектура терминала такая). Дополнительная нагрузка собственно от Lua минимальна. Основная беда, похоже, с тем, как отрабатывают функции QLua, заставляющие терминал что-то отрисовывать. Что-то там внутри терминала с синхронизациями при доступе к общим ресурсам не так. Пока неясно, как бы это в явном виде продемонстрировать.
[BUG] Повышенная загрузка CPU при большом количестве функций в скрипте
 
Для снижения нагрузки на терминал пришлось позакрывать все свечные графики (порядка 8 штук), собрать все инструменты в одну ТТТ, выключить там цветовые настройки, а также закрыть стаканы. Кажется, что несколько легче стало. Выходит, что отрисовка графики дополнительно сильно замедляет работу (похоже, что есть там какое бутылочное горлышко в виде одной общей очереди на всё). Трудно обеспечивать тысячи сделок в течение торгового дня.
[BUG] Повышенная загрузка CPU при большом количестве функций в скрипте
 
Дополню, что при этом нагрузка на ядро процессора (i7-9700K) максимальная (100% / 8 ядер = 12.5%).
[BUG] Повышенная загрузка CPU при большом количестве функций в скрипте
 
Daniil Pozdnyakov, плохо, что не нашли причину. Конкретно в последние 2 дня из-за большой активности торгов на рынке у нас терминалы 9.3.3.3, где запущено много скриптов, тормозят: время сервера внизу в статус строке отстаёт от реального времени на несколько секунд. Ненормально это.

Вам же даже код привели, который демонстрирует проблему.
https://forum.quik.ru/messages/forum10/message60158/topic6953/#message60158

Настоятельная просьба провести изучение более внимательно с использованием реалистичных нагрузок.
Установка QUIK на Linux под Wine, Проблемы с актуальными на сегодняшний день версиями
 
Цитата
отсутствие linux версии Quik говорит лишь об адекватности кодеров в ARQA, ну или менеджмента хотя бы :)

Отсутствие линукс-версии терминала говорит о том, что не хватает ресурсов у разработчиков на это. Выбрали бы в самом начале разработки терминала язык Java -- имели бы кроссплатформенный вариант сегодня, правда непонятно с каким качеством.
Цитата
- сам Линус сотрудник Intel
Дезинформация. Вот инфомация из Википедии.

С 1997 по 2003 год Линус работал в известной компании Transmeta. После этого организовал Open Source Development Labs. В данный момент работает в The Linux Foundation (с 2007), где занимается разработкой ядра Linux.
Установка QUIK на Linux под Wine, Проблемы с актуальными на сегодняшний день версиями
 
На мой взгляд, актуальный терминал и под Windows работает так себе в смысле производительности для конкретно моих задач, связанных с алготрейдингом через lua-скрипты.

Под Wine 6.0.2 терминал как-то работает (с некоторыми глюками) и ещё более заметным падением производительности, из-за которого мне не удалось перейти на Linux с Windows в трейдинге. Может, Wine 7 как-то улучшит ситуацию (ещё не пробовал под ним запускать).

Антон выше прав, что наиболее реально -- это (попробовать) собрать терминал под ARM-версию Windows. Остальное нереально, у "Арки" нет на это ресурсов.

Жаль, что достойный конкурентов терминала нет на российском рынке, может от этого повысилось бы качество.
Как из скрипта открыть окно на нужной вкладке?
 
Никак, но пожелание такое уже регистрировали, скорее всего.
[BUG] Повышенная загрузка CPU при большом количестве функций в скрипте
 
Очень хочется увидеть ответ от разработчиков по поводу изучения данной проблемы, хотя бы после новогодних праздников. Ниже описывается пример, как большое количество таблиц может появляться в реальной программе.

Предположим, что скрипту нужно хранить в памяти для работы 3000 свечей (сколько отдаёт сервер при запросе данных по ликвидным инструментам) по 10 инструментам и 5 таймфреймам. Время свечи QLua отдаёт в виде таблицы

Код
datetime = { year = 2021, month = 12, day = 30, hour = 11, min = 0, sec = 0, ms = 0, mcs = 0, ... }

Соответственно, сразу же имеем 3000 * 10 * 5 = 150 000 таблиц. А если скриптов несколько, то можно ещё на порядок увеличить количество таблиц в памяти.

Конечно, конкретно здесь можно закодировать дату в виде строки "2021-12-30T11:00:00.000" или вообще числом 20211230110000000 для эффективности, но придётся писать код для выделения из этого числа отдельных полей, и арифметика даты/времени станет неудобной.

В общем, просьба к разработчикам дать обратную связь, а то уже нехорошо выглядит такая техподдержка. Хоть пообещайте что-нибудь, как обычно.
Профилирование терминала QUIK на стороне пользователей
 
Поскольку пользователи жалуются, что терминал тормозит, а МосБиржа запрещает разработчикам терминала тестирование в реальных условиях, то предлагаю сделать специальный режим работы терминала, который можно включить по желанию пользователя для профилирования. Пусть в этом режиме собирается нужная статистика по времени работы, количеству вызовов функций и пр. внутри терминала, чтобы её можно было бы потом отправить разработчикам для анализа. Важно сделать вывод результата работы в понятном текстовом виде, чтобы пользователь понимал, что именно он отправляет разработчикам, и не переживал по поводу конфиденциальности. Думаю, что тогда получится выявить много узких мест.

Если уже сейчас имеется способ запуска терминала под какого-то рода отладчиком с профилированием, тогда дайте знать, как это сделать. Для java есть, к примеру visualvm с мониторингом кучи, тредов, сборщика мусора и профилированием.
Таблица сделок, номер заявки превращается в число e+
 
Вместо string.format() используйте tostring(), чтобы не портилось 19-значное целое число.
Отладка QUIK 9.3
 
Сделал такой тест на Windows и под эмулятором Wine:

Код
function main()
    message("Started at " .. os.date(), 1)
    local count = 0
    for i = 0, getNumberOf("all_trades") - 1 do
        local item = getItem("all_trades", i)
        if item then
            count = count + 1
        end
    end
    message("Ended at " .. os.date(), 1)
    message("Count = " .. tostring(count))
end

Получились такие результаты: при 1.55 млн. обезличенных сделок Windows отрабатывает за 9 секунд, а Linux за 22 секунды, что приемлемо для вызова getItem(). А вот почему в 10 раз медленнее исполняется полный скрипт -- пока непонятно.
Квик выдает не правильное направление сделки в таблице всех сделок на срочном рынке
 
Цитата
Старатель написал:
Цитата
Александр написал:
я уже пытаюсь 7 недель выяснить
Это легко сделать самостоятельно, отправив рыночную заявку и проверив направление вашей сделки в ТОС.
Я вчера тоже хотел эту мысль в качестве ответа написать, а потом по предоставленным автором темы файлам понял, что расхождения весьма нечастые. Дорого будет так проверять.
Отладка QUIK 9.3
 
Ради интереса запустил QUIK 9.3.3.3 под эмулятором Wine (winehq stable 6.0.2) в виртуалке Ubuntu 21.10. Увидел, что медленно работает скрипт экспорта биржевых данных, причём та его часть, которая из тиков, накопленных за несколько часов с начала торговой сессии, в оперативной памяти формирует свечные данные. Ввода-вывода в этом фрагменте кода вообще никакого нет. Скорость в одном из замеров примерно в 10 раз медленнее, чем в случае Windows на аналогичном по скорости процессоре. Как мне кажется, это указывает на какое-то совсем тормозное место внутри терминала, которое в эмуляторе совсем проседает.

В коде в цикле по всем обезличенным сделкам есть обращение к функции getItem:
Код
for i = 0, getNumberOf("all_trades") - 1 do
     local item = getItem("all_trades", i)

редкое обращение к getSecurityInfo(classCode, secCode).lot_size, результаты которого кэшируются, а в остальном идёт работа с оперативной памятью (много таблиц, представляющих собой свечные данные 1-минутного таймфрейма по всем тикерам из классов акций (Т+2) и фьючерсов (без опционов)).

Код функции, которая работает медленно, ниже.
Скрытый текст
[BUG] Повышенная загрузка CPU при большом количестве функций в скрипте
 
Цитата
Daniil Pozdnyakov написал:
Цитата
Старатель написал:
Демонстрационный скрипт:
    Скрытый текст        
Код
      local   n   =     50000  
  for   i   =     1  , n   do  
  _G[  "f"    ..  i]   =     function   ()   end  
  end  

  local   class   =     "SPBFUT"  
  local   sec   =     "SiZ1"  
  local   param   =   {"BIDDEPTHT",  "OFFERDEPTHT" }

  local   run   =     true  
  function    OnStop ()
  run   =     nil  
  end  

  function    main ()
  assert(  Subscribe_Level_II_Quotes  (class, sec))
    for   i   =     1  ,   #  param   do  
    ParamRequest(class, sec, param[i])
    end  
    while   run   do     sleep  (  500  )   end  
    Unsubscribe_Level_II_Quotes  (class, sec)
    for   i   =     1  ,   #  param   do  
    CancelParamRequest(class, sec, param[i])
    end  
  end  

  function    OnQuote (class_code, sec_code)   end  
  function    OnParam (class_code, sec_code)   end  
  function    OnAllTrade (alltrade)   end      
 
QUIK 9.3.1.11, Lua 5.4
Открыто, как минимум одно окно: стакан ликвидного инструмента.
Конечно, никто не запускает скрипты с тысячами функций, но при нескольких запущенных скриптах с десятками функций при высокой активности на бирже получаем нихилую загрузку CPU.

ЗЫ: У кого "один скрипт на все случаи жизни" с парой функций, может игнорировать эту тему.
Без флуда!

Здравствуйте!
Ваше письмо получено, проблема изучается. Постараемся в ближайшее время дать ответ.

Подскажите, занимаются ли разработчики терминала сейчас этой проблемой или пока есть более приоритетные задачи? Интересует, по крайней мере, диагноз: удалось ли уже увидеть проблему производительности в этом нагрузочном тесте?
[BUG] Повышенная загрузка CPU при большом количестве функций в скрипте
 
Цитата
TGB написал:
Цитата
Старатель написал:
Имеет ли этот пункт отношение к обсуждаемой здесь теме?
   Тест комментария 55 в QUIK 9.3.3.3 (QLua 5.4) выполняется столько же как и в QUIK 8.13.1.16 (QLua 5.4)
Если производительность вернулась, то это хорошо. Значит представители "Арки" в курсе проблемы, но не сознались.

Вспоминается шутка про проприетарные форматы файлов. Их спецификации не раскрывают не потому, что там есть какие-то секретные ноу-хау, а потому, что стыдно.
[BUG] Повышенная загрузка CPU при большом количестве функций в скрипте
 
Уважаемая техподдержка, с вашей стороны уже очень некрасиво выглядит долгая реакция на адекватные сообщения в этой теме.
Отладка QUIK 9.3
 
Новая версия вышла.

ftp://ftp.quik.ru/public/updates/9.3/quik_9.3.3_upd.zip

Изменения:

Медленная работа Рабочего места QUIK в некоторых случаях при запуске или во время работы.
Некорректное построение таблицы котировок в некоторых случаях.
[BUG] Повышенная загрузка CPU при большом количестве функций в скрипте
 
Интересно, почему до сих пор техподдержка никак себя не проявила в этой теме? В заголовке ведь явно указано [BUG]. Похоже, придётся специальную тему в "Пожеланиях..." создать для ускорения реакции.
[BUG] Повышенная загрузка CPU при большом количестве функций в скрипте
 
Деградация производительности мешает утром, когда происходит подключение к срочному рынку и заново приходят все обезличенные сделки с вечерней сессии. Если скрипты реагируют на соответствующие коллбэки и скриптов много, то происходят жуткие тормоза даже на современном железе. Конкретно у меня, несмотря на то, что реакция на обезличенные сделки минимальная, обезличенные сделки прогружаются минут десять с включенными скриптами и раз в 10 быстрее с выключенными. Судя по загрузке процессора (Core i7 9700K), упираемся именно в него. Уверенность в том, что в терминале есть какая-то жуткая неэффективность в этом месте, почти стопроцентная.

Убедительная просьба к техподдержке донести до разработчиков информацию по данной проблеме. Старатель предоставил описание тестового стенда, который даже на QUIK Junior демонстрирует деградацию производительности терминала в 2 раза по сравнению в более ранними версиями.
[BUG] Повышенная загрузка CPU при большом количестве функций в скрипте
 
Проверил у себя на компьютере. Вот 3 картинки: до запуска скрипта, после запуска скрипта и после запуска скрипта, где размер массива ещё увеличен в 10 раз. Видно, что загрузка процессора вырастает до максимума.

Просьба к техподдержке передать информацию разработчикам и написать соответствующее сообщение в этой теме.



 
[BUG] Повышенная загрузка CPU при большом количестве функций в скрипте
 
Думаю, что очень актуальный вопрос поднят. Спасибо топик-стартеру за демонстрацию проблемы. От разработчиков терминала ждём пояснений.
Основные библиотеки для QLua 5.4.1
 
Перевыложил: https://dropmefiles.com/Xxi8c
Баг - объём на последней минутке задваивается.
 
У меня есть вот такое объяснение, почему описанная проблема возникает.

У терминала есть свечной график за прошлый день. При подключении к серверу с утра в терминал приходят данные по обезличенным сделкам вчерашней вечерней сессии на срочном рынке. При этом терминал начинает обновлять свечи, но делает это "интеллектуально": при поступлении очередной обезличенной сделки, если она не относится к последней свече, он пропускает её (считает, что уже не надо использовать эту информацию), а вот про последнюю свечу терминал не может сказать, учтены данные или нет. По этой причине последняя свеча, всё-таки, обновляется. На ценовой рейндж H - L это не влияет, значение C станет опять правильным, когда все обезличенные сделки пройдут. Страдает только объём, который, понятное дело, удваивается.

Если такое объяснение корректно, то долгие разборки разработчиков с данной проблемой означают, что в текущей архитектуре приложения нельзя устранить такую неполадку.
Как запретить брокеру изменять настройки quik?, Обезличенные сделки
 
Как будто у вас файл, куда записываются настройки -- это не тот файл, откуда они потом читаются. Проверьте, что у вас прописано в Настройках клиентского места: Программа - Файлы настроек. Либо файл с настройками read only. Брокер ни при чём, поверьте.
Отладка QUIK 9.3
 
Вот пример загрузки CPU, которую process explorer выводит. При этом процессор Intel Core i7-9700K слабым не назовёшь, а загрузка ядра близка к максимуму 12.5%
 
Отладка QUIK 9.3
 
Ещё вижу повышенное использование процессора в QUIK 9.3. Не подскажет ли кто, как можно при работающем терминале понять, что именно забирает на себя ресурсы CPU? Типа какого-то профилировщика запустить?

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

Со своей стороны заметил, что есть "узкое место" с выводом данных в таблицы, созданные QLua. Как будто внутри терминала избыточная синхронизация в этом месте. Причём заголовок окна обновляется быстро, а содержимое таблиц -- медленно (при специальном нагрузочном тесте). Я уже снизил количество строк в таблицах и интенсивность вывода, но, похоже, что всё равно затык в этом месте. Для ориентира по нагрузке: в терминале открыто 45 окон (обычные и созданные QLua).
Основные библиотеки для QLua 5.4.1
 
Согласен с написанным выше. Не жду ничего особенно ни от lua, ни от разработчиков терминала. Антон правильно сказал в другой теме:
https://forum.quik.ru/messages/forum10/message59543/topic6791/#message59543
Страницы: 1 2 3 4 5 6 7 8 9 10 След.
Наверх