Надо не в документации писать, а разбираться с причинами падения. В сообщении, скриншот которого Вы приводите, сказано о необходимости отправить нам dmp файл.
dmp-файл отправил.
Цитата
Sergey Denegin написал: Но в версиях до 7.6 ничего подобного никогда не происходило, хотя макрос в части пересоздания таблиц никак не менялся.
Почти согласен: для моего случая до версии 7.6 падение происходило крайне редко - нельзя сказать, что его не было вообще, а с версией 7.6 - это стало действительно проблемой, которую надо решать.
Цитата
vgi написал: как временное решение может попробовать не уничтожать/создавать таблицу, а скрывать/показывать, очищая/меняя содержимое?
Я нашёл для себя решение - оно меня устраивает. Закрываемая таблица исчезает не мгновенно перед созданием новой, а с небольшой задержкой не более секунды (в основнов цикле стоит Sleep на 1 секунду). Что касается "очищая/меняя содержимое" - то 1) вызов Clear() из колбэка также иногда ведёт к падению 2) новая таблица-2 у меня должна иметь другой состав колонок, и, может я не до конца разобрался, но в уже созданной таблице поменять состав колонок возможности нет и нужно только уничтожать и создавать новую
Обнаружил ситуацию, которая изредка приводит к аварийному завершению Квика.
Стояла задача: при клике по строке таблицы-1 требуется таблицу-1 закрыть, а вместо неё открыть новую таблицу-2 (например, провалиться глубже по дереву). Хоть это мне сразу и показалось не очень красиво, но попробовал сделать эти действия прямо из коллбэка Таблицы-1. В нём вызывается DestroyTable(1) и создаётся CreateWindow(2) Написал, потестировал - работает. Но работает не на 100% хорошо. Через пол-года обнаружилось, что изредка, примерно в 1-2% случаях Квик падает.
(см. рис)
Долго искал, в чём причина. Решил, что дело в том, что в каких-то редких случаях коллбэк после отработки пытается зачем-то вернуться к своей родительской таблице, которую он сам же только-что уничтожил. Переписал скрипт так, что коллбэк только создаёт новую таблицу-2, а для старой таблицы-1 делается пометка, по которой уже после отработки коллбэка в основном цикле уничтожается происходит DestroyTable(1). Теперь ошибка не проявляется.
Также плохо иногда может заканчиваться вызов из коллбэка функции Clear(1) для родительской таблицы.
Наверное, если я прав, имеет смысл в документации указать, что не надо из коллбэка вызывать DestroyTable() и Clear()
Siluyano написал: Антонио ,будьте любезны, подскажите получается ли у вас корректно перетаскивать заявку на графике с целью изменения цены. Заявку, у которой выставлено «ПЕРЕНОСИТЬ ЗАЯВКУ».
На версии, 7.1.2.2 (по-прежнему с Финамом работаю на этой версии) корректно перенести не получается - заявка копируется, но "ПЕРЕНОСИТЬ ЗАЯВКУ" слетает. А на версии 7.2.0.45 и из таблицы заявок, и с графика заявка переносится корректно с сохранением "ПЕРЕНОСИТЬ ЗАЯВКУ" .
По совету Imersio Arrigo скачал с сайта новую версию 7.2.0.45. Подключился к Финаму, который с клиентами работает ещё на 7.1.2.2. И действительно, описанная проблема не проявилась. При копировании заявки со сроком - срок теперь корректно копируется.
По совету Imersio Arrigo скачал с сайта новую версию 7.2.0.45. Подключился к Финаму, который с клиентами работает ещё на 7.1.2.2. И действительно, описанная проблема не проявилась. При клике на пустую легенду графика теперь даётся возможность Заменить инструмент.
Добрый день! В Финаме в данный момент подключена версия 7.1.2.2. Более новые версии они пока тестируют. Проблема такова. Есть график по опциону, который давно истёк. Хочу я в этом графике Заменить инструмент с истекшего, на какой-нибудь рабочий. Правый клик мыши по Легенде - и Квик стабильно подвисает. См. рис http://joxi.ru/4AkeQLGCMGP3Ym
Я работаю через Финам. Они версию 7.2 только тестируют, клиентам пока не предлагают. Так что проверить мою проблему в данный момент невозможно. Будем ждать.
Добрый день! До последних обновлений при вводе новой заявки на основании уже имеющейся в таблице Заявки или из стакана при клике по "своей" заявке открываемое окно ввода новой заявки автозаполнялось всеми значениями из исходной заявки. В новой же версии независимо от того: установлена ли в исходной заявке галочка ПЕРЕНОСИТЬ ЗАЯВКУ или нет - в окно ввода заявки эта галочка не попадает. Это баг или фича? В стандартных настройках ничего по этому вопросу не нашёл. Очень прошу вернуть поведение копирования заявки к тому, как было всегда.
quio пишет: Необходимо самому указать код клиента перед комментарием.
Т.е. "//qwe" - будет ошибка о превышении длины, "код клиента//qwe" - заявка выставится нормально
По моей практике - не так! Могу сказать, что не только в Финаме, а и у других брокеров, скрипт с комментарием без кода клиента обрабатывается нормально. Если комментарий задать из скрипта, то он на Сервер попадёт как есть, а если вводить интерактивно руками, то в комментарии появятся символ /, т.к. в форме комментарий задаётся с помощью двух полей ввода, и между ними образуется этот /.
Sergey Gorokhov пишет: Здравствуйте, В транзакции указывается не brokerref а CLIENT_CODE Согласно документации: CLIENT_CODE - 20-ти символьное составное поле, может содержать код клиента и текстовый комментарий с тем же разделителем, что и при вводе заявки вручную. Параметр используется только для групповых транзакций. Необязательный параметр
Сергей: 1) Что значит В транзакции указывается не brokerref а CLIENT_CODE? Т.е. не нужно указывать brokerref, а нужно CLIENT_CODE? У меня задаётся ни то, и ни другое, а (по Вашему же научению) так:
Увлекся длинными содержательными комментариями при выставлении заявок и получил ответ от Сервера: Неправильно указано значение для поля "Комментарий" - [Превышен размер поля ввода]
Можно, конечно, экспериментально найти максимальную длину поля brokerref. Но хотелось бы узнать это из первых уст.
И почему бы не указать это в документации:
Описание параметров Таблицы заявок: Параметр Тип Описание order_num NUMBER Номер заявки в торговой системе flags NUMBER Набор битовых флагов brokerref STRING Комментарий, обычно: <код клиента>/<номер поручения>
А в этом моём нештатном случае, когда к одному счёту оказались по ошибке подключены 2 разных квика разных версий, существует способ из анализа таблиц узнать скриптом Квика1, что та или иная заявка выставлена не этим, а другим Квиком2? В заявках виден UID и UID снявшего заявку. Но они одинаковы у Квика1 и Квика2. Отличия косвенные я заметил только в том, что Квик1 (версия 7) проставляет id, а Квик2 версии 6 оставляет это поле пустым. Может быть, ещё какие-то признаки есть? Хотелось бы сделать в скрипте дополнительную "защиту от дурака".
Пишу в догонку: вопрос снимается. Оказалось, к одному и тому же счёту было подключено 2 скрипта с квиков разных версий, расположенных на разных серверах и действия скриптов дублировались. Сорри!
Сегодня тема множественных колл-бэков в моём скрипте раскрылась с новой стороны.
Напомню, выше я публиковал, что в обработчике OnTradeDo(trade) делаю проверку, чтобы исключить повторную обработку одной и той же сделки. Т.е. в ответ на сделку происходит выставление гарантированно только одной ответной заявки. Сегодня этот уже 10 дней стабильно работающий в версии 7 скрипт в ответ на отсылку одной транзакции sendTransaction(trans_params) получает в ответ выставленными ДВЕ одинаковые заявки, с незначительными отличиями: номер заявки, выставлена (мкс) и id. Причём в одной из них поле id заполнено, а в другой нет.
Задваивание происходит иногда. Когда задваивания не происходит, то единственная новая заявка имеет пустое поле id.
См. рис: Парные заявки по одной транзакции На рисунке показаны 2 пары задвоенных заявок в ответ на один в каждом случае вызов sendTransaction(trans_params)
По своим логам я уверен, что был один и только один вызов sendTransaction(trans_params)
До 7-й версии Квика ничего подобного со скриптом не случалось. Что делать и как с этим бороться?
Сегодня с утра в версиях Квика 6 и 7 по-разному отображаются статус торговой сессии для инструментов срочного рынка, например RIZ5 Это версия 6
А это в то же время версия 7
В версии 6 статус Торгуется, а в версии 7 статус Приостановлена. Соответственно, скрипт в версии 7 не работает, т.к. ему видится, что сессия по фьючерсу сейчас не идёт.
Столкнулся с таким фактом, что Функция find() не находит строку в самой себе Мой пример:
Код
k="Строка-Демо"
while k:len()>1 do
t=k:find(k)
ToLog("Поиск подстроки "..k.." в самой себе даёт "..tostring(t))
k=k:sub(1,-2)
end
Получаем:
Код
Поиск подстроки Строка-Демо в самой себе даёт nil
Поиск подстроки Строка-Дем в самой себе даёт nil
Поиск подстроки Строка-Де в самой себе даёт nil
Поиск подстроки Строка-Д в самой себе даёт nil
Поиск подстроки Строка- в самой себе даёт 1
Поиск подстроки Строка в самой себе даёт 1
Поиск подстроки Строк в самой себе даёт 1
Поиск подстроки Стро в самой себе даёт 1
Поиск подстроки Стр в самой себе даёт 1
Поиск подстроки Ст в самой себе даёт 1
Заменим Строка-Демо на Строка-Лом
Код
Поиск подстроки Строка-Лом в самой себе даёт nil;
Поиск подстроки Строка-Ло в самой себе даёт nil;
Поиск подстроки Строка-Л в самой себе даёт nil;
Поиск подстроки Строка- в самой себе даёт 1;
Поиск подстроки Строка в самой себе даёт 1;
Поиск подстроки Строк в самой себе даёт 1;
Смотрю в документацию по find(): -- Ищет вхождение подстроки в строку и возвращает индекс начала вхождения, или nil, если совпадение не найдено -- В строке поиска можно использовать регулярные выражения
Получается, что если в моей строке содержится "-" и далее символ, то это рассматривается как регулярное выражение? Если да, то как использовать find() или что-то вместо неё, чтобы подстрока интерпретировалась как подстрока, а не рег.выражение?
Добрый день! При работе со скриптами в Квике с несколькими вкладками есть неудобство. Если открытие скрипта происходит прямо при старте программы автоматически, а не руками запуском из Доступных скриптов, то окно скрипта открывается сразу на всех, а не на одной вкладке. Это иногда неудобно, и приходится по-новой чётко задавать на какой одной вкладке окно скрипта отображать. До версии 7 это можно было делать правым кликом мыши по окну и открывался единственный пункт контекстного меню "Переместить на вкладку" В седьмой версии контекстного меню нет вообще, поэтому приходится делать гораздо больше действий: Окна --- Переместить окно на вкладку --- Клик по вкладке. Когда окон разных скриптов открыто много (у меня, например, их шесть), то процедура утомительна. Поэтому предложения: 1. Как минимум: вернуть контекстное меню на окна скриптов с пунктом "переместить на вкладку" 2. И/ИЛИ для пункта меню Окна --- Переместить окно на вкладку назначить Горячую клавишу 3. Для полного блеска нужно, чтобы открываемое при старте Квика окно скрипта открывалось в той вкладке, где оно было в последний раз, а не на всех вкладках.
А есть способ узнать координаты нижней правой точки, видимой в окне Квика? Т.е. чтобы координаты моего открываемого из скрипта окна подобрать так, чтобы оно полностью было видимо, а не заползало за правую или нижнюю границу окна Квика?
Для моего случая действительно проблема не одного, а нескольких повторных событий OnTrade решилась довольно легко, путём объявления новой таблицы TradesFinished и небольшой вставки в начало обработки События OnTrade
Код
function OnTradeDo(trade) --обработка события "OnTrade произошла сделка"
local m, y
y=tostring(trade.trade_num).."="..tostring(trade.order_num)
if TradesFinished[y] then --таблица с уже обработанными Трейдами за последние N минут
m="Событие OnTrade для trade_num= "..trade.trade_num..' order_num= '..trade.order_num.." уже обрабатывалось "
m=m..tostring(os.clock() - TradesFinished[y]).." сек назад. Повторно НЕ ОБРАБАТЫВАЕМ!!!"
ToLog(m)
return
end
TradesFinished[y]=os.clock() -- запомним, чтоб повторно не обрабатывать
.... --Далее идёт сама обработка события (как было до версии 7)
end
Если сделки частые, то с определенной периодичностью таблицу TradesFinished можно очищать от отметок, устаревших более чем на N минут.
Старатель пишет: Если вы получаете данные через getParamEx, то заказывать их через CreateDataSource нет смысла, поскольку заказываемые параметры должны быть по-любому в списках принимаемых параметров, независимо от вызова этой функции CreateDataSource.
Мой практический опыт подтверждает это утверждение. Если требуется последнее (текущее) значение параметра из ТТП, то getParamEx выдаёт это значение без предварительного заказа потока через CreateDataSource. Я не проверял на всех Параметрах, но полтора десятка точно использовал.
Т.е. получается так: 1) Если требуется получить только текущее значение параметра ТТП, то достаточно использовать getParamEx без предварительного CreateDataSource, вне зависимости отображён этот параметр в ТТП или нет. 2) Если требуется история значения параметра, то требуется CreateDataSource, дождаться ненулевой длины потока, и затем уже читать значения из полученных баров. 3) В вышеприведённом скрипте от Sergey Gorokhov создание потоков требуется лишь для того, чтобы назначить КолБэк и с помощью КолБэка подсвечивать строки, по которым данные обновились.
Антонио пишет: Видим, что потоки в переменных не сохраняются, а какое-то время живут как локальные переменные. При выходе из скрипта потоки не закрываются с помощью DS:close(). Вопрос 1 : Это нормально не хранить и не закрывать после себя потоки ?
А зачем закрывать? Мы потом с этими данными работаем.
Я имею в виду закрывать не сразу, пока данные нужны для работы, а по окончании работы перед выходом из скрипта, например в OnStop(), Не нужно разве заботиться, чтобы почистить за собой мусор? Если скрипт завершится с незакрытыми потоками, а Квик продолжит работу, разве не останется захваченной и недоступной для других процессов память ? Или при завершении скрипта вся память под объекты скрипта автоматически и без пропусков "подчистится"?
p.s. Спасибо за ответы, многое прояснилось из того, на что даже намёка нет в документации.
Вопросы по CreateDataSource Беру скрипт для расчёта греков опционов, предложенный Sergey Gorokhov в #11 21.07.2015 14:48:09 (https://forum.quik.ru/messages/forum10/message7203/topic748/#message7203) Т.е. код именем разработчика рассматривается как образцовый. Запустил, работает, но остаются вопросы: 1) Для каждого опциона (а это могут быть десятки и сотни) открываются три потока:
Код
--заказ данных
CreateDataSourceEX(BaseClassCode,T.Optionbase,"settleprice") --цена базового актива
CreateDataSourceEX(ClassCode,T.SecCode,"strike") -- страйк
CreateDataSourceEX(ClassCode,T.SecCode,"volatility") --волатильность
...
function CreateDataSourceEX(Class,Sec,Par)
local ds,err = CreateDataSource(Class, Sec, INTERVAL_TICK, Par)
if ds==nil then
message("Ошибка при получении параметра "..Par..":\n"..err, 3)
return false
else
ds:SetEmptyCallback()
while ds:Size()==0 do
sleep(100)
end
return true
end
end
Видим, что потоки в переменных не сохраняются, а какое-то время живут как локальные переменные. При выходе из скрипта потоки не закрываются с помощью DS:close(). Вопрос 1: Это нормально не хранить и не закрывать после себя потоки ?
2) Часть параметров в скрипте запрашивается без создания потока, они комментируются как статичные
Т.е. по непонятным мне причинам Страйк рассматривается как более изменчивая величина (по сути, она никогда не изменяется), чем кол-во дней до Экспирации (изменяется каждый вечер) Вопрос 2: Как узнать способ обращения к ПАРАМЕТРу? Есть ли список ПАРАМЕТРОВ, для которых обязательно/необязательно перед первым обращением создавать поток?
3) В функции, создающей поток, используется тиковый интервал INTERVAL_TICK.
Код
function CreateDataSourceEX(Class,Sec,Par)
local ds,err = CreateDataSource(Class, Sec, INTERVAL_TICK, Par)
if ds==nil then
message("Ошибка при получении параметра "..Par..":\n"..err, 3)
return false
else
ds:SetEmptyCallback()
while ds:Size()==0 do
sleep(100)
end
return true
end
end
Посчитал, что тиковые данные очень трафико-ёмкие, изменил на интервал INTERVAL_H1. После этого скрипт не запустился, погрязнув в слипах(100) при ожидании открытия потоков Вопрос 3: Поток с интервалом INTERVAL_TICK почему открывается быстрее и действительно ли для расчёта греков надо использовать именно тиковый интервал, не увеличит ли это катастрофически трафик и память?