Столкнулся с тем, что после аварийного выхода из терминала при его зависании по сторонней причине, исчезают все метки добавленные при помощи функции AddLabel после последнего запуска скрипта. Очень неприятно и в голову ничего не пришло кроме сохранения параметров меток в файл при их создании с последующим удалением и пересозданием каждой при новом запуске. Наверное можно было бы решить эту проблему имея в lua функцию сохранения параметров терминала в файл info.wnd, но увы. Кто-то нашел решение этой проблемы?
Попутно изучая в доках функцию AddLabel на предмет что курили разработчики когда придумали использовать для параметра "Время в формате «ЧЧММСС»..." тип "NUMBER" наехал вот на такую шутку:
Код
local a="09:15:18"
local b=string.gsub(a,":","")
local c=tonumber(b)
local d=tonumber(string.gsub(a,":",""))
message(tostring(c).." "..tostring(d))
Результат: 91518 nil
Кто коллекционирует, дарю )) v.9.8.0.11, Lua 5.3.5
string.gsub возвращает два параметра, поэтому tonumber воспримет второй как базу, что и приводит к nil. Скобки добавить надо, чтобы ограничить одним параметром возвращаемое значение gsub.
А метки да, исчезают. Как я понимаю из-за ошибки создания дампа состояния при падении. Приходится хранить параметры метки в файле состояния скрипта. Впрочем, я предпочитаю все хранить независимо, чтобы всегда иметь возможность при перезапуске проверить и выявить все различия.
Nikolay написал: А метки да, исчезают. Как я понимаю из-за ошибки создания дампа состояния при падении. Приходится хранить параметры метки в файле состояния скрипта. Впрочем, я предпочитаю все хранить независимо, чтобы всегда иметь возможность при перезапуске проверить и выявить все различия.
Там есть еще один прикол - после выпада в дамп и последующего запуска GetLabelParams возвращает параметры метки, хотя на графике ее нет. Приходится их по одной удалять их по возвращаемому uid и создавать с новым из сохраненных параметров.
Kolossi, А нафига ВЫПАДАТЬ в дамп? Лично я сбрасываю дамп на диск раз в 5 минут... нет, вру - даже чаще: раз в 100 секунд, и потери данных здесь будут только если именно в момент сброса дампа Квик и сдохнет. Но вероятность этого прекрасного события вряд ли отличается от нуля, и все данные оказываются хорошо сохранившимися. Ну, разве что в эти 100 секунд что-то произойдёт.
Владимир,я имел ввиду закрытие терминала после его зависания и последующий запуск. А с сохранением жизненно важных переменных и таблиц у меня давно все отлажено.
В итоге я считаю, что отсутствие меток на графике при наличии их параметров в системе в подобной ситуации является багом и подлежит рассмотрению и исправлению в ближайших версиях квика. Но похоже так считаю только я (
Kolossi, Я, во всяком случае, считаю иначе: все эти графики с метками для торговли не нужны от слова совсем, и потому я категорически против любых изменений Квика, который и без того на ладан дышит.
Kolossi, Кому как. Мне, например, для торговли только Lua и нужен. А тема здесь направлена на потенциальное изменение софта Квика. НЕ НАДО ЭТОГО ДЕЛАТЬ!!!
Владимир написал: Kolossi, Кому как. Мне, например, для торговли только Lua и нужен. А тема здесь направлена на потенциальное изменение софта Квика. НЕ НАДО ЭТОГО ДЕЛАТЬ!!!
Как обычно на любом форуме есть человек постоянно лезущий в любую тему "со своим единственно правильным мнением" не обращая внимание на то, что оно никого не интересует. Давайте не будем засорять ветку.
Kolossi, 99% всех веток практически любого форума, не говоря уже про этот, есть чистейший мусор. В частности, Ваша ветка. Несмотря на то, что здесь в достатке специализированных форумов ("Пожелания по развитию функциональных возможностей системы QUIK", "Вопросы по работе с графиками в системе QUIK", "Вопросы по эксплуатации системы QUIK, не выделенные в отдельные темы форума"), народ постоянно лезет в "Программирование на языке Lua" со своими дурацкими пожеланиями, которые "подлежит рассмотрению и исправлению в ближайших версиях квика", хотя софт уже настолько изуродован аналогичными пожеланиями их предшественников, что уже едва справляется со своими первоначальными задачами. Давайте не будем засорять форум.
При аварийном завершении работы терминала QUIK действительно не сохраняется текущий wnd-файл и утрачиваются изменения, внесенные в конфигурацию в ходе последней рабочей сессии. Сохранение текущего wnd-файла с помощью QLua-функции в силу ряда причин не может быть реализовано, и решением описанной проблемы видится именно используемый Вами способ - сохранение параметров в текстовый файл.
Что касается приведенного Вами фрагмента кода, как написал ранее Nikolay, функция string.gsub() возвращает два значения, из-за чего невозможно корректно выполнить преобразование tonumber.
Установил метки, запомнил их ID. Аварийно завершаю терминал. Перезапускаю терминал. Скрипт считывает метки и проверяет их.
Часть меток меняет свой id. Например, было 155 стало 162. Возможно часть меток исчезла, а может и сами как-то переиндексировались. В результате считывая метку, получаем чужие данные.
Но это очень плохо. Если нет гарантий, что id метки неизменен, то надо каждый раз искать, проверять, что метка та же, что и была.
Обязательно нужен метод ПолучитьВсеМетки - возвращает массив с индексами всех меток на указанном графике.
И желательно иметь метод ПриСдвигеМетки. Его, конечно, лучше сделать как регистрируемый колбек на метку, типа RegisterOnMoveLabel(id, chrt_id, func). Вызываемый по событию "MOUSE_RELEASED". Т.е. указателем взяли - отпустили. Сейчас же приходится постоянно опрашивать метку на предмет новых данных - не самое лучшее занятие.
Nikolay написал: Установил метки, запомнил их ID. Аварийно завершаю терминал. Перезапускаю терминал. Скрипт считывает метки и проверяет их.Часть меток меняет свой id. Например, было 155 стало 162. Возможно часть меток исчезла, а может и сами как-то переиндексировались. В результате считывая метку, получаем чужие данные.
Уточните, как именно Вы аварийно завершаете работу терминала? Так же просьба подробно описать последовательность Ваших действий. Для анализа проблемы просьба прислать скрипт с уточнениями нам на quiksupport@arqatech.com со ссылкой на данную ветку форума.
Nikolay написал: И желательно иметь метод ПриСдвигеМетки.
Цитата
Nikolay написал: Обязательно нужен метод ПолучитьВсеМетки
Ваши пожелания зарегистрированы. Мы постараемся рассмотреть их и сообщить Вам результаты анализа. Впоследствии, по результатам анализа, будет приниматься решение о реализации пожеланий в будущих версиях ПО.
Уточните, как именно Вы аварийно завершаете работу терминала? Так же просьба подробно описать последовательность Ваших действий. Для анализа проблемы просьба прислать скрипт с уточнениями нам на quiksupport@arqatech.com со ссылкой на данную ветку форума.
Ок. Раз Вы сами не можете проверить происходит ли переиндексация меток при каждом запуске терминала, вот два скрипта.
Первый добавляет метки:
Код
local path = _G.getScriptPath()
local sleep = _G.sleep
local log_file
local AddLabel = _G.AddLabel
local function init_log()
log_file = io.open(path.."\\add_labels_test.txt", "w")
end
local function close_log()
if io.type(log_file) == 'file' then
log_file:close()
end
log_file = nil
end
local function log_tostring(...)
local n = select('#', ...)
if n == 1 then
return tostring(select(1, ...))
end
local t = {}
for i = 1, n do
t[#t + 1] = tostring((select(i, ...)))
end
return table.concat(t, " ")
end
local function log(...)
if not log_file then return end
log_file:write(tostring(os.date("%c", os.time())).." "..log_tostring(...).."\n");
log_file:flush();
end
function _G.OnStop()
close_log()
end
function _G.main()
init_log()
log('start')
local tag = 'virt_test'
local date = tonumber(os.date('%Y%m%d', os.time())) or 0
local time = tonumber(os.date('%H%M%S', os.time() - 120)) or 0
local label_params = {}
label_params.YVALUE = 172.0
label_params.TEXT = ''
label_params.HINT = ''
label_params.DATE = date
label_params.TIME = time
label_params.FONT_FACE_NAME = 'Arial'
label_params.ALIGNMENT = 'RIGHT'
label_params.FONT_HEIGHT = 3
label_params.TRANSPARENT_BACKGROUND = 1
for i = 1, 100 do
label_params.TEXT = tostring(i)..': |||||||||||||||||||||||||||'
label_params.YVALUE = label_params.YVALUE + 0.1
local l_id = AddLabel(tag, label_params)
log('add label', i, 'id', l_id)
sleep(10)
end
end
Второй читает:
Код
local path = _G.getScriptPath()
local log_file
local GetLabelParams = _G.GetLabelParams
local function init_log()
log_file = io.open(path.."\\check_labels_test.txt", "w")
end
local function close_log()
if io.type(log_file) == 'file' then
log_file:close()
end
log_file = nil
end
local function log_tostring(...)
local n = select('#', ...)
if n == 1 then
return tostring(select(1, ...))
end
local t = {}
for i = 1, n do
t[#t + 1] = tostring((select(i, ...)))
end
return table.concat(t, " ")
end
local function log(...)
if not log_file then return end
log_file:write(tostring(os.date("%c", os.time())).." "..log_tostring(...).."\n");
log_file:flush();
end
function _G.OnStop()
close_log()
end
function _G.main()
init_log()
log('start')
local tag = 'virt_test'
for l_id = 1, 1000 do
local l_params = GetLabelParams(tag, l_id)
if l_params then
log('find label', 'id', l_id, 'text', l_params.text)
end
end
end
Запускаем терминал. Запускаем скурипт, добавляющий метки. Удаляем несколько меток, чтобы образовались дырки в последовательности id меток. Можно еще проще сделать - добавить метка, удалить все метки и заново добавить. В результате id меток будет начинаться не с 1.
Tue Mar 7 13:30:26 2023 start Tue Mar 7 13:30:26 2023 add label 1 id 101.0 Tue Mar 7 13:30:26 2023 add label 2 id 102.0 Tue Mar 7 13:30:26 2023 add label 3 id 103.0 Tue Mar 7 13:30:26 2023 add label 4 id 104.0 Tue Mar 7 13:30:26 2023 add label 5 id 105.0 Tue Mar 7 13:30:26 2023 add label 6 id 106.0 Tue Mar 7 13:30:26 2023 add label 7 id 107.0 Tue Mar 7 13:30:26 2023 add label 8 id 108.0 Tue Mar 7 13:30:26 2023 add label 9 id 109.0
Теперь закрываем терминал, даже не аварийно. Запускаем терминал заново. Запускаем второй скрипт и видим что метки получили индексы с 1, тем самым те индексы, что были получена при добавлении утеряны. Вывод: при каждом запуске терминала происходит переиндексация меток.
Tue Mar 7 13:30:02 2023 start Tue Mar 7 13:30:02 2023 find label id 1 text 1: ||||||||||||||||||||||||||| Tue Mar 7 13:30:02 2023 find label id 2 text 2: ||||||||||||||||||||||||||| Tue Mar 7 13:30:02 2023 find label id 3 text 3: ||||||||||||||||||||||||||| Tue Mar 7 13:30:02 2023 find label id 4 text 4: ||||||||||||||||||||||||||| Tue Mar 7 13:30:02 2023 find label id 5 text 5: ||||||||||||||||||||||||||| Tue Mar 7 13:30:02 2023 find label id 6 text 6: ||||||||||||||||||||||||||| Tue Mar 7 13:30:02 2023 find label id 7 text 7: ||||||||||||||||||||||||||| Tue Mar 7 13:30:02 2023 find label id 8 text 8: |||||||||||||||||||||||||||
Как-то нет никакой обратной реакции. Хоть бы сказали, что да, метки реиндексируются при каждом запуске терминала. Делайте что хотите. Либо все же надо это исправить, например дать возможность искать метки по внешнему индексу, задаваемому при установке метки. Или не применять реиндексацию, а выдавать для новой метки индекс из пула свободных индексов и только когда он пустой увеличивать индекс на 1.
Приносим свои извинения за длительное отсутствие реакции.
Меткам действительно могут переприсваиваться индексы при перезапуске Рабочего места QUIK, идентификаторы удаленных с графика меток не сохраняются - такое поведение корректно.