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

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

Страницы: 1
Падение QUIK с General Protection Fault, DestroyTable() и Clear() при вызове из функции обратного вызова для обработки событий в таблице
 
Цитата
Sergey Gorokhov написал:
Цитата
Надо не в документации писать, а разбираться с причинами падения.
В сообщении, скриншот которого Вы приводите, сказано о необходимости отправить нам dmp файл.
dmp-файл отправил.

Цитата
Sergey Denegin написал:
Но в версиях до 7.6 ничего подобного никогда не происходило, хотя макрос в части пересоздания таблиц никак не менялся.
Почти согласен: для моего случая до версии 7.6 падение происходило крайне редко - нельзя сказать, что его не было вообще, а с версией 7.6 - это стало действительно проблемой, которую надо решать.
Цитата
vgi написал:
как временное решение может попробовать не уничтожать/создавать таблицу, а скрывать/показывать, очищая/меняя содержимое?
Я нашёл для себя решение - оно меня устраивает. Закрываемая таблица исчезает не мгновенно перед созданием новой, а с небольшой задержкой не более секунды (в основнов цикле стоит Sleep на 1 секунду).
Что касается "очищая/меняя содержимое" - то
1)  вызов Clear() из колбэка также иногда ведёт к падению
2) новая таблица-2 у меня должна иметь другой состав колонок, и, может я не до конца разобрался, но в уже созданной таблице поменять состав колонок возможности нет и нужно только уничтожать и создавать новую
Падение QUIK с General Protection Fault, DestroyTable() и Clear() при вызове из функции обратного вызова для обработки событий в таблице
 
Обнаружил ситуацию, которая изредка приводит к аварийному завершению Квика.

Стояла задача: при клике по строке таблицы-1 требуется таблицу-1 закрыть, а вместо неё открыть новую таблицу-2 (например, провалиться глубже по дереву).
Хоть это мне сразу и показалось не очень красиво, но попробовал сделать эти действия прямо из коллбэка Таблицы-1.
В нём вызывается DestroyTable(1) и создаётся CreateWindow(2)
Написал, потестировал - работает.
Но работает не на 100% хорошо. Через пол-года обнаружилось, что изредка, примерно в 1-2% случаях Квик падает.

(см. рис)


Долго искал, в чём причина.
Решил, что дело в том, что в каких-то редких случаях коллбэк после отработки пытается зачем-то вернуться к своей родительской таблице, которую он сам же только-что уничтожил.
Переписал скрипт так, что коллбэк только создаёт новую таблицу-2, а для старой таблицы-1 делается пометка, по которой уже после отработки коллбэка в основном цикле уничтожается происходит  DestroyTable(1).
Теперь ошибка не проявляется.

Также плохо иногда может заканчиваться вызов из коллбэка  функции Clear(1) для родительской таблицы.

Наверное, если я прав, имеет смысл в документации указать, что не надо из коллбэка вызывать DestroyTable()  и  Clear()  
В новой версии 7.1.2.2 при копировании заявки из таблицы Заявки не копируется флаг ПЕРЕНОСИТЬ ЗАЯВКУ и сама ДАТА
 
Цитата
Siluyano написал:
Антонио  ,будьте любезны, подскажите получается ли у вас корректно перетаскивать заявку на графике с целью изменения цены. Заявку, у которой выставлено «ПЕРЕНОСИТЬ ЗАЯВКУ».
На версии, 7.1.2.2 (по-прежнему с Финамом работаю на этой версии)  корректно перенести не получается - заявка копируется, но "ПЕРЕНОСИТЬ ЗАЯВКУ"  слетает.
А на версии  7.2.0.45  и из таблицы заявок, и с графика заявка переносится корректно с сохранением  "ПЕРЕНОСИТЬ ЗАЯВКУ" .

Т.е. вся проблема в глючности версии 7.1.2.2
В новой версии 7.1.2.2 при копировании заявки из таблицы Заявки не копируется флаг ПЕРЕНОСИТЬ ЗАЯВКУ и сама ДАТА
 
По совету Imersio Arrigo скачал с сайта новую версию 7.2.0.45. Подключился к Финаму, который с клиентами работает ещё на 7.1.2.2.
И действительно, описанная проблема не проявилась.
При копировании заявки  со сроком  -  срок теперь корректно копируется.
Аварийное завершение работы Квик 7.1.2.2 при попытке заменить инструмент на графике
 
По совету  Imersio Arrigo  скачал с сайта новую версию 7.2.0.45. Подключился к Финаму, который с клиентами работает ещё на 7.1.2.2.
И действительно, описанная проблема не проявилась.
При клике на пустую легенду графика теперь даётся возможность Заменить инструмент.

Попутно отмечу, что и другая проблема со сроком при копировании заявки  https://forum.quik.ru/messages/forum1/message15409/topic1704/#message15409  тоже перестала проявляться.
Аварийное завершение работы Квик 7.1.2.2 при попытке заменить инструмент на графике
 
А разве будет она у меня работать, когда у брокера на сервере пока ещё старая версия стоит?
Аварийное завершение работы Квик 7.1.2.2 при попытке заменить инструмент на графике
 
Может, в новой версии уже исправлено - но проверить это не могу.
Аварийное завершение работы Квик 7.1.2.2 при попытке заменить инструмент на графике
 
Добрый день!
В Финаме в данный момент подключена версия 7.1.2.2. Более новые версии они пока тестируют.
Проблема такова. Есть график по опциону, который давно истёк.
Хочу я в этом графике Заменить инструмент с истекшего, на какой-нибудь рабочий.
Правый клик мыши по Легенде -  и Квик стабильно подвисает.
См. рис   http://joxi.ru/4AkeQLGCMGP3Ym
В новой версии 7.1.2.2 при копировании заявки из таблицы Заявки не копируется флаг ПЕРЕНОСИТЬ ЗАЯВКУ и сама ДАТА
 
Я работаю через Финам. Они версию 7.2 только тестируют, клиентам пока не предлагают.
Так что проверить мою проблему в данный момент невозможно. Будем ждать.
В новой версии 7.1.2.2 при копировании заявки из таблицы Заявки не копируется флаг ПЕРЕНОСИТЬ ЗАЯВКУ и сама ДАТА
 
Не смог разобраться, как сюда на форум вставлять картинки.
Вот ссылка на картинку с моим вопросом
В новой версии 7.1.2.2 при копировании заявки из таблицы Заявки не копируется флаг ПЕРЕНОСИТЬ ЗАЯВКУ и сама ДАТА
 
Добрый день!
До последних обновлений при вводе новой заявки на основании уже имеющейся в таблице Заявки или из стакана при клике по "своей"  заявке  открываемое окно ввода новой заявки автозаполнялось всеми значениями из исходной заявки.
В новой же версии независимо от того: установлена ли в исходной заявке галочка  ПЕРЕНОСИТЬ ЗАЯВКУ или нет - в окно ввода заявки эта галочка не попадает.
Это баг или фича?
В стандартных настройках  ничего по этому вопросу не нашёл.
Очень прошу вернуть поведение копирования заявки к тому, как было всегда.
Длина поля brokerref в таблице ЗАЯВКИ, Превышен размер поля ввода
 
Цитата
quio пишет:
Необходимо самому указать код клиента перед комментарием.

Т.е. "//qwe" - будет ошибка о превышении длины, "код клиента//qwe" - заявка выставится нормально
По моей практике - не так!
Могу сказать, что не только в Финаме, а и у других брокеров, скрипт с комментарием без кода клиента обрабатывается нормально.
Если комментарий задать из скрипта, то он на Сервер попадёт как есть, а если вводить интерактивно руками, то в комментарии появятся символ /, т.к. в форме комментарий задаётся с помощью двух полей ввода, и между ними образуется этот /.
Длина поля brokerref в таблице ЗАЯВКИ, Превышен размер поля ввода
 
Цитата
Sergey Gorokhov пишет:
Здравствуйте,
В транзакции указывается не brokerref а CLIENT_CODE
Согласно документации:
CLIENT_CODE - 20-ти символьное составное поле, может содержать код клиента и текстовый комментарий с тем же разделителем, что и при вводе заявки вручную. Параметр используется только для групповых транзакций. Необязательный параметр
Сергей:
1) Что значит В транзакции указывается не brokerref а CLIENT_CODE?  Т.е. не нужно указывать brokerref, а нужно CLIENT_CODE?
У меня задаётся ни то, и ни другое, а (по Вашему же научению) так:

Код
trans_params={
   ["TRANS_ID"]=trans_id,
   ["Комментарий"]=cl,
   ["ACTION"]="Ввод заявки",
   ["CLASSCODE"]=class,
   ["Тип"]="Лимитированная",
   ["Условие исполнения"]="Поставить в очередь",
   ["Класс"]=class,
   ["Инструмент"]=seccode,
   ["Количество"]=tostring(quantity),
   ["Цена"]=tostring(price),
   ['К/П']=operation,
   ["Торговый счет"]=account
   }
res=sendTransaction(trans_params)
 
И нормально работает. Только вот Комментарий более 20 символов не прошёл, потому и возник вопрос.



2) Из какой документации цитата : CLIENT_CODE - 20-ти символьное составное поле,...  ?

На сайте скачал из   http://arqatech.com/ru/support/files/    Документация по языку LUA в QUIK и примерыzip, 2.3 МБ
Там QLUA.chm  и Интерпретатор языка Lua.pdf  - в них про 20 символов ничего нет.
Опционы, Баланс, теоретическая цена
 
Цитата
Вад пишет:
Позже я прочел эту тему, но так и не понял как быть.. что же прописать в коде чтобы исключить дублирование?

Я решил проблему так:   OnTrade
Всё нормально работает.
Длина поля brokerref в таблице ЗАЯВКИ, Превышен размер поля ввода
 
Увлекся длинными содержательными комментариями при выставлении заявок и получил ответ от Сервера:
Неправильно указано значение для поля "Комментарий" - [Превышен размер поля ввода]

Можно, конечно, экспериментально найти максимальную длину поля brokerref.
Но хотелось бы узнать это из первых уст.

И почему бы не указать это в документации:

Описание параметров Таблицы заявок:
Параметр         Тип Описание
order_num NUMBER     Номер заявки в торговой системе
flags                  NUMBER     Набор битовых флагов
brokerref           STRING       Комментарий, обычно: <код клиента>/<номер поручения>
QUIK (версия 7.0.1.5), function OnTrade(trade), трехкратный вызов на одно событие.
 
А в этом моём нештатном случае, когда к одному счёту оказались по ошибке подключены 2 разных квика разных версий, существует способ из анализа таблиц узнать скриптом Квика1, что та или иная заявка выставлена не этим, а другим Квиком2?
В заявках виден UID и UID снявшего заявку. Но они одинаковы у Квика1 и Квика2.
Отличия косвенные я заметил только в том, что Квик1 (версия 7) проставляет id, а Квик2 версии 6 оставляет это поле пустым.
Может быть, ещё какие-то признаки есть?
Хотелось бы сделать в скрипте дополнительную "защиту от дурака".
QUIK (версия 7.0.1.5), function OnTrade(trade), трехкратный вызов на одно событие.
 
Пишу в догонку: вопрос снимается.
Оказалось, к одному и тому же счёту было подключено 2 скрипта с квиков разных версий, расположенных на разных серверах и действия скриптов дублировались.
Сорри!
QUIK (версия 7.0.1.5), function OnTrade(trade), трехкратный вызов на одно событие.
 
Сегодня тема множественных колл-бэков в моём скрипте раскрылась с новой стороны.

Напомню,    выше я публиковал, что в обработчике OnTradeDo(trade) делаю проверку, чтобы исключить повторную обработку одной и той же сделки.
Т.е. в ответ на сделку происходит выставление гарантированно только одной ответной заявки.
Сегодня этот уже 10 дней стабильно работающий в версии 7 скрипт в ответ на отсылку одной транзакции sendTransaction(trans_params)
получает в ответ выставленными ДВЕ одинаковые заявки, с незначительными отличиями: номер заявки, выставлена (мкс) и id. Причём в одной из них поле id заполнено, а в другой нет.

Задваивание происходит иногда.
Когда задваивания не происходит, то единственная новая заявка имеет пустое поле id.


См. рис:   Парные заявки по одной транзакции
На рисунке показаны 2 пары задвоенных заявок в ответ на один в каждом случае вызов sendTransaction(trans_params)

По своим логам я уверен, что был один и только один вызов sendTransaction(trans_params)

До 7-й версии Квика ничего подобного со скриптом не случалось.
Что делать и как с этим бороться?
Статус торговой сессии в версии 7, Ошибка статуса
 
Да, в ТТП все колонки отображаются как обычно, цена и время последней сделки меняются. Актуально всё, кроме статуса торговой сессии.

Позвонил в техподдержку Брокера, посоветовали перезаказать данные заново.

Помогло.
Проблема решена.
Но причина возникновения эта сбоя так и не выяснилась.
Статус торговой сессии в версии 7, Ошибка статуса
 
Сегодня с утра в версиях Квика 6 и 7 по-разному отображаются статус торговой сессии для инструментов срочного рынка, например RIZ5
Это версия 6





А это в то же время версия 7




В версии 6 статус Торгуется, а в версии 7 статус Приостановлена.
Соответственно, скрипт в версии 7 не работает, т.к. ему видится, что сессия по фьючерсу сейчас не идёт.

Брокер ФИНАМ
Или это вопрос к брокеру?
Неожиданное поведение функции find(), Функция find() не находит строку в самой себе
 
Спасибо, сработало!
Значит, не в ту документацию смотрел:))
Неожиданное поведение функции find(), Функция find() не находит строку в самой себе
 
Вопрос не по Квику, а по QLUA

Столкнулся с таким фактом, что Функция 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() или что-то вместо неё, чтобы подстрока интерпретировалась как подстрока, а не рег.выражение?
Несколько мониторов и getposition
 
Цитата
Sergey Gorokhov пишет:

Готовы зарегистрировать пожелание на добавление такой функции
Да, пожалуйста, зарегистрируйте пожелание.
При активной работе с окнами из скрипта это очень полезная вещь.
QUIK версия 7.0.1.5 Предложения, Предложения по неудобствам нового меню версии 7.
 
Добрый день!
При работе со скриптами в Квике с несколькими вкладками есть неудобство.
Если открытие скрипта происходит прямо при старте программы автоматически, а не руками запуском из Доступных скриптов, то окно скрипта открывается сразу на всех, а не на одной вкладке.
Это иногда неудобно, и приходится по-новой чётко  задавать на какой одной вкладке окно скрипта отображать.
До версии 7 это можно было делать правым кликом мыши по окну и открывался единственный пункт контекстного меню "Переместить на вкладку"
В седьмой версии контекстного меню нет вообще, поэтому приходится делать гораздо больше действий: Окна   --- Переместить окно на вкладку  --- Клик по вкладке.
Когда окон разных скриптов открыто много (у меня, например, их шесть), то процедура утомительна.
Поэтому предложения:
1. Как минимум: вернуть контекстное меню на окна скриптов с пунктом "переместить на вкладку"
2. И/ИЛИ для пункта меню  Окна   --- Переместить окно на вкладку  назначить Горячую клавишу
3. Для полного блеска нужно, чтобы открываемое при старте Квика окно скрипта открывалось в той вкладке, где оно было в последний раз, а не на всех вкладках.
Несколько мониторов и getposition
 
А есть способ узнать координаты нижней правой точки, видимой в окне Квика? Т.е. чтобы координаты моего открываемого из скрипта окна подобрать так, чтобы оно полностью было видимо, а не заползало за правую или нижнюю границу окна Квика?

Чтобы моё окно открылось так:


А не так:  
QUIK (версия 7.0.1.5), function OnTrade(trade), трехкратный вызов на одно событие.
 
Для моего случая действительно проблема не одного, а нескольких повторных событий 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 минут.
CreateDataSource
 
Цитата
Старатель пишет:
Если вы получаете данные через getParamEx, то заказывать их через CreateDataSource нет смысла, поскольку заказываемые параметры должны быть по-любому в списках принимаемых параметров, независимо от вызова этой функции CreateDataSource.

Мой практический опыт подтверждает это утверждение. Если требуется последнее (текущее) значение параметра из ТТП, то getParamEx выдаёт это значение без предварительного заказа потока через CreateDataSource. Я не проверял на всех Параметрах, но полтора десятка точно использовал.

Т.е. получается так:
1) Если требуется получить только текущее значение параметра ТТП, то достаточно использовать getParamEx без предварительного CreateDataSource, вне зависимости отображён этот параметр в ТТП или нет.
2) Если требуется история значения параметра, то требуется  CreateDataSource, дождаться ненулевой длины потока, и затем уже читать значения из полученных баров.
3) В вышеприведённом скрипте от Sergey Gorokhov  создание потоков требуется лишь для того, чтобы назначить КолБэк и  с помощью КолБэка подсвечивать строки, по которым данные обновились.


Всё правильно в моих выводах?
CreateDataSource
 
Цитата
Sergey Gorokhov пишет:
Цитата
Антонио пишет:
Видим, что потоки в переменных не сохраняются, а какое-то время живут как локальные переменные.
При выходе из скрипта потоки не закрываются с помощью DS:close().
Вопрос 1 : Это нормально не хранить и не закрывать после себя потоки ?
А зачем закрывать? Мы потом с этими данными работаем.
Я имею в виду закрывать не сразу, пока данные нужны для работы, а по окончании работы перед выходом из скрипта, например в OnStop(),
Не нужно разве заботиться, чтобы почистить за собой мусор?
Если скрипт завершится с незакрытыми потоками, а Квик продолжит работу, разве не останется захваченной и недоступной для других процессов память ?
Или при завершении скрипта вся память под объекты скрипта  автоматически и без пропусков "подчистится"?


p.s.  Спасибо за ответы, многое прояснилось из того, на что даже намёка нет в документации.
Подскажите какая функция читает "доску опционов" ?, доска опционов
 
Вопрос к  Sergey Gorokhov

На другой ветке (#105  03.11.2015 19:52:13  ), посвящённой  CreateDataSource , я задал три вопроса по Вашему скрипту...
CreateDataSource
 
Вопросы по 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) Часть параметров в скрипте запрашивается без создания потока, они комментируются как статичные

Код
T["DAYS_TO_MAT_DATE"] = getParamEx(ClassCode,SecCode,"DAYS_TO_MAT_DATE").param_value 

Для других параметров (они комментируются как динамичные) сначала создаются потоки, а затем запрашиваются данные

Код
CreateDataSourceEX(ClassCode,T.SecCode,"strike")
...
T.["strike"] = getParamEx(ClassCode,T.SecCode,"strike").param_value+0,
Т.е. по непонятным мне причинам Страйк рассматривается как  более изменчивая величина (по сути, она никогда не изменяется), чем кол-во дней до Экспирации (изменяется каждый вечер)
Вопрос 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 почему открывается быстрее и действительно ли для расчёта греков надо использовать именно тиковый интервал, не увеличит ли это катастрофически трафик и память?
Страницы: 1
Наверх