В последнее время несколько раз наблюдал такое: приходит OnTrade, в котором trans_id=0. Я знаю, что это промежуточная версия, поэтому в мой алгоритм вписано игнорировать такие вызовы, ожидая более полных. И почти всегда они приходят. Но в среднем 1-2 раза за день случается так, что полный OnTrade с ненулевым trans_id так и не приходит. В чём может быть причина? Я мог бы убрать эту дополнительную проверку из своего кода и обрабатывать такие вызовы, в принципе trans_id мне ни для чего не нужен, достаточно brokerref. Но ведь может не прийти что-то более важное. Например бывает, что приходит OnTrade с нулевой комиссией, и сразу после него ещё один OnTrade с заполненной комиссией. Здесь сбоев не было ни разу, но что если он тоже не придёт?
Пользователь
Сообщений: Регистрация: 30.01.2015
02.02.2026 06:34:47
Цитата
User12501 написал: В последнее время несколько раз наблюдал такое: приходит OnTrade, в котором trans_id=0. Я знаю, что это промежуточная версия, поэтому в мой алгоритм вписано игнорировать такие вызовы, ожидая более полных. И почти всегда они приходят. Но в среднем 1-2 раза за день случается так, что полный OnTrade с ненулевым trans_id так и не приходит. В чём может быть причина? Я мог бы убрать эту дополнительную проверку из своего кода и обрабатывать такие вызовы, в принципе trans_id мне ни для чего не нужен, достаточно brokerref. Но ведь может не прийти что-то более важное. Например бывает, что приходит OnTrade с нулевой комиссией, и сразу после него ещё один OnTrade с заполненной комиссией. Здесь сбоев не было ни разу, но что если он тоже не придёт?
А зачем Вам trans_id в сделке? ------------------- Поясняю: Сделка совершается по выставленной заявке. В сделке есть номер заявки, Номер есть всегда и по нему можно найти эту заявку. ----------------------------- trans_id - это номер транзакции, по которой уже выставлена заявка. т е транзакция уже давно исполнена. Вместо нее есть заявка. В данном случае и заявка исполнена, вместо нее есть сделка. Т е даже заявку нет смысла искать, а уж trans_id тем более...
написал: В последнее время несколько раз наблюдал такое: приходит OnTrade, в котором trans_id=0. Я знаю, что это промежуточная версия, поэтому в мой алгоритм вписано игнорировать такие вызовы, ожидая более полных. И почти всегда они приходят. Но в среднем 1-2 раза за день случается так, что полный OnTrade с ненулевым trans_id так и не приходит. В чём может быть причина? Я мог бы убрать эту дополнительную проверку из своего кода и обрабатывать такие вызовы, в принципе trans_id мне ни для чего не нужен, достаточно brokerref. Но ведь может не прийти что-то более важное. Например бывает, что приходит OnTrade с нулевой комиссией, и сразу после него ещё один OnTrade с заполненной комиссией. Здесь сбоев не было ни разу, но что если он тоже не придёт?
А зачем Вам trans_id в сделке?
Конкретно trans_id мне не нужен. Но если по протоколу он должен прийти, и не приходит, значит что-то пошло не так. В другой раз не прийти может что-то более серьёзное, например комиссия. Или это другое? Вопрос отчасти пересекается с моим предыдущим вопросом про повторные OnTrade ( ). Т.е. по trans_id=0 я пытался фильтровать OnTrade, которые заведомо не последние.
написал: В последнее время несколько раз наблюдал такое: приходит OnTrade, в котором trans_id=0. Я знаю, что это промежуточная версия, поэтому в мой алгоритм вписано игнорировать такие вызовы, ожидая более полных. И почти всегда они приходят. Но в среднем 1-2 раза за день случается так, что полный OnTrade с ненулевым trans_id так и не приходит. В чём может быть причина? Я мог бы убрать эту дополнительную проверку из своего кода и обрабатывать такие вызовы, в принципе trans_id мне ни для чего не нужен, достаточно brokerref. Но ведь может не прийти что-то более важное. Например бывает, что приходит OnTrade с нулевой комиссией, и сразу после него ещё один OnTrade с заполненной комиссией. Здесь сбоев не было ни разу, но что если он тоже не придёт?
А зачем Вам trans_id в сделке?
Конкретно trans_id мне не нужен. Но если по протоколу он должен прийти, и не приходит, значит что-то пошло не так. В другой раз не прийти может что-то более серьёзное, например комиссия. Или это другое? Вопрос отчасти пересекается с моим предыдущим вопросом про повторные OnTrade ( ). Т.е. по trans_id=0 я пытался фильтровать OnTrade, которые заведомо не последние.
Предположу, что он не приходит при выполнении заявки в нескольких сделках, либо в заявках, установленных до за пуска скрипта. Но это лишь предположение.
QUIK clients support
Сообщений: Регистрация: 11.08.2025
03.02.2026 12:05:28
Добрый день.
Уточните, пожалуйста, версию Рабочего места QUIK, которую Вы в данный момент используете? Используется свой скрипт или какие-то готовые библиотеки? По каким именно сделкам не приходят trans_id, можете привести пример? Заполнен ли при этом параметр в Таблице Сделок в Рабочем месте?
Уточните, пожалуйста, версию Рабочего места QUIK, которую Вы в данный момент используете? Используется свой скрипт или какие-то готовые библиотеки? По каким именно сделкам не приходят trans_id, можете привести пример? Заполнен ли при этом параметр в Таблице Сделок в Рабочем месте?
Версия quik 12.6.0.53. Полностью свой скрипт. Например сделка на покупку одной акции SOFL. Последний раз ошибка была 1-го февраля. За короткий промежуток были совершены три абсолютно идентичные сделки по близкой цене: в 17:01:54, в 17:04:15, и в 17:05:29. Все три на покупку одной акции SOFL. По первой и третьей сделкам пришли три функции OnTrade. По второй сделке только одна. Замечу также, что по первой и третьей сделкам вместе с функциями OnTrade приходили также две функции OnOrder, по второй сделке функция OnOrder пришла только одна. Но в эти функции я не заглядывал, не могу сказать, в чём отличие (если это важно - могу заглянуть, всё сохранено). Каких-либо особых событий, предшествовавших этой ошибке, типа разрыва соединения и т.д., не наблюдалось.
Пользователь
Сообщений: Регистрация: 30.01.2015
04.02.2026 05:56:32
, Два вопроса, которые могут дать ответ. 1) С какой задержкой у вас Sleep в main? 2) есть ли у Вас очередь событий?
Пользователь
Сообщений: Регистрация: 26.11.2025
05.02.2026 01:33:09
Цитата
nikolz написал: , Два вопроса, которые могут дать ответ. 1) С какой задержкой у вас Sleep в main?
2) есть ли у Вас очередь событий?
Пользователь
Сообщений: Регистрация: 26.11.2025
05.02.2026 01:35:11
Цитата
nikolz написал: , Два вопроса, которые могут дать ответ. 1) С какой задержкой у вас Sleep в main? 2) есть ли у Вас очередь событий?
1) 585 секунд. 2) Не знаю. А что это?
(Предыдущее сообщение отправилось по ошибке, не ту клавишу нажал).
написал: , Два вопроса, которые могут дать ответ. 1) С какой задержкой у вас Sleep в main? 2) есть ли у Вас очередь событий?
1) 585 секунд. 2) Не знаю. А что это?
(Предыдущее сообщение отправилось по ошибке, не ту клавишу нажал).
Тогда вероятнее всего Вы просто теряете сообщения, когда по заявке совершаются несколько сделок относительно быстро. Если надо принять все то сделайте очередь сообщений. один из примеров есть в документации на библиотеку QLUA Другой есть в моей теме на форуме по универсальному обработчику событий
написал: , Два вопроса, которые могут дать ответ. 1) С какой задержкой у вас Sleep в main? 2) есть ли у Вас очередь событий?
1) 585 секунд. 2) Не знаю. А что это?
(Предыдущее сообщение отправилось по ошибке, не ту клавишу нажал).
Тогда вероятнее всего Вы просто теряете сообщения, когда по заявке совершаются несколько сделок относительно быстро.
Непонятно. Насколько я знаю, все функции OnTrade приходят в одном потоке, т.е. даже если две сделки совершились строго одновременно, функции по ним вызовутся последовательно, и их невозможно потерять.
Кроме того, в приведённом примере интервал между сделками несколько секунд. Это не быстро. Быстро - это когда десятки сделок в секунду. Я такое видел, и мой скрипт их успешно обрабатывает.
написал: , Два вопроса, которые могут дать ответ. 1) С какой задержкой у вас Sleep в main? 2) есть ли у Вас очередь событий?
1) 585 секунд. 2) Не знаю. А что это?
(Предыдущее сообщение отправилось по ошибке, не ту клавишу нажал).
Тогда вероятнее всего Вы просто теряете сообщения, когда по заявке совершаются несколько сделок относительно быстро.
Непонятно. Насколько я знаю, все функции OnTrade приходят в одном потоке, т.е. даже если две сделки совершились строго одновременно, функции по ним вызовутся последовательно, и их невозможно потерять.
Кроме того, в приведённом примере интервал между сделками несколько секунд. Это не быстро. Быстро - это когда десятки сделок в секунду. Я такое видел, и мой скрипт их успешно обрабатывает.
Если правильно вас понял, то Вы обрабатываете все события внутри колбеков. Т е Вы тормозите терминал QUIK на время работы вашего скрипта. Да, в этом случае события вероятно вы не пропустите. Но это лишь предположение, Судя по установленной Вами задержки, и в этом случае найдутся способные написать такой скрипт.
Пользователь
Сообщений: Регистрация: 26.11.2025
09.02.2026 19:40:13
Сегодня опять случилась эта бяка. За секунду произошли четыре транзакции, по трём из них полная версия OnTrade (с ненулевым trans_id) не пришла. Видимо придётся убрать из скрипта эту дополнительную проверку. Но вообще факт неприятный.
Не видя вашего кода, сложно что-то сказать, но попробуйте сделать sleep(50) и посмотрите что будет. С задержкой 585000 ваш код в main практически отключен. Это так вами задумано?
Не видя вашего кода, сложно что-то сказать, но попробуйте сделать sleep(50) и посмотрите что будет. С задержкой 585000 ваш код в main практически отключен. Это так вами задумано?
В main выполняется очень маленькая и незначительная часть кода: обновление таблиц и проверка согласованности количества акций. Т.е. я держу текущее количество акций в отдельной переменной, и после каждой OnTrade обновляю эту переменную. Раз в 10 минут из main проверяю, что значение переменной равно текущему количеству акций, полученному напрямую. Таким образом и отлавливаю потерянные OnTrade. Весь остальной код, как здесь уже упоминали, выполняется прямо в колбэк-функциях.
Sleep(50) при таком подходе никак не поможет и ни на что не повлияет.
И вообще здесь ошибка от моего кода ну вообще никак не зависит. Код функции OnTrade в общих чертах выглядит так:
function OnTrade(trd) всю таблицу trd записать в текстовый файл проверить поле brokerref, если там не то, что мне нужно - return проверить завершённость OnTrade (trans_id!=0, наличие комиссии и т.д.), если незавершённый - return выполнение основных действий end
Таким образом, до начала проверок и основного кода, ВСЕ trd сохраняются в текстовый файл. И если возникает подозрение об ошибке, я захожу в этот текстовый файл и нахожу все trd с данным trd_num. И вот по ним я вижу, что полная версия таблицы с trans_id !=0 не приходила.
Пользователь
Сообщений: Регистрация: 26.11.2025
09.02.2026 20:37:27
Замечу также, что ошибка возникает крайне редко. Я выше писал - 1-2 раза в день, но это было преувеличение. На самом деле вот сегодня она случилась трижды, а до этого в последний раз была 1-го февраля. При том что мой код работает ежедневно и выполняет сотни транзакций в день. Если бы бяка была в моём коде, она бы вылезала чаще.
Пользователь
Сообщений: Регистрация: 02.01.2026
09.02.2026 20:57:14
User12501, по каким классам инструментов наблюдается? В самой таблице сделок trans_id есть?
Пользователь
Сообщений: Регистрация: 15.06.2023
09.02.2026 21:05:58
Просто разбираюсь с тем же самым, и вот что удалось выяснить не который слой ошибок. Почему роботы закрываются "просто так" и как это фиксят в проп-торговле? Это класс ошибок, который случается даже с идеально спроектированными системами. И причина всегда одна: > Расхождение между биржевой реальностью и состоянием в QUIK!
Вот конкретные механизмы (примеры).
1. Главная причина: Асинхронность данных в QUIK. Здесь помним QUIK — это клиент терминал, а не биржа!
Время в QUIK ~= Время на бирже local q_time = -- локальное время QUIK local e_time = -- время биржи (если доступно) Разница может быть ~ 0.1-5 секунд, а то и более!
Что происходит: 1. Биржа. Цена прошла стоп > стоп сработал; 2. QUIK (через 0.5-2 сек). Получил тик > показал в стакане; 3. Робот. Увидел в стакане > решил "стоп сработал"; 4. Но, Стоп уже сработал на бирже, а в QUIK ещё не отобразился. Результат: робот пытается отменить уже исполненный стоп > получает ошибку! --------------------------------
2. "Призрачные" стопы в QUIK. QUIK показывает активный стоп. stop_order = getItem("stop_orders", index) if stop_order.flags == 1 then -- Считаем активным -- Но на бирже он мог уже сработать! end
Это случается при: * Лаге данных (биржа > шлюз брокера > QUIK); * Частичном исполнении (часть уже исполнилась, QUIK ещё не обновил qty); * Ошибках протокола (QUIK не получил подтверждение удаления). --------------------------------
3. Классический кейс рассинхрона. Таймлайн (реальный): [00:00.000] Цена Bid = 100 000 (на бирже) [00:00.100] Цена достигает стопа 100 000 [00:00.150] Биржа исполняет стоп [00:00.300] QUIK получает обновление стакана [00:00.350] Робот видит Bid = 100 000 > думает "стоп ещё не сработан" [00:00.400] Робот пытается изменить стоп > ошибка
Пользователь
Сообщений: Регистрация: 12.05.2020
09.02.2026 22:27:45
Цитата
User12501 написал: Таким образом, до начала проверок и основного кода, ВСЕ trd сохраняются в текстовый файл.
1. Всю обработку вы делаете в служебном потоке коллбека (отличным от потока main). Этот поток в QUIK один и он обслуживает все запущенные скрипты QUIK. Когда он занят вашей обработкой он перестает выполнять свои служебные функции, в том числе, обработку вновь возникающих данных по сделкам. Если нет служебной очереди внутри QUIK, то возможны потери возникающих данных. В вашем варианте желательно как можно быстрее выполнять коллбек, например, записывая trd в очередь между коллбеком и потоком main (со sleep(50) ), в котором выполнять остальную обработку таблицы trd. Вариант реализации очереди выложен мной в соседней ветке пользователя VPM. 2. Если вам нужны данные по сделкам, то их можно получать готовыми из таблицы QUIK trade с помощью функции getItem. Зачем вы отрабатываете "сырые" коллбеки OnTrade?
Пользователь
Сообщений: Регистрация: 26.11.2025
12.02.2026 17:42:37
Цитата
Йцукен написал: , по каким классам инструментов наблюдается? В самой таблице сделок trans_id есть?
Я использую только класс TQBR, стандартную торговлю акциями, если вы об этом спрашивали. В таблице сделок да, trans_id есть. Но возможно именно у тех сделок, о которых речь, не было. Не проверял, в следующий раз как случится - посмотрю.
написал: Таким образом, до начала проверок и основного кода, ВСЕ trd сохраняются в текстовый файл.
1. Всю обработку вы делаете в служебном потоке коллбека (отличным от потока main). Этот поток в QUIK один и он обслуживает все запущенные скрипты QUIK. Когда он занят вашей обработкой он перестает выполнять свои служебные функции, в том числе, обработку вновь возникающих данных по сделкам. Если нет служебной очереди внутри QUIK, то возможны потери возникающих данных. В вашем варианте желательно как можно быстрее выполнять коллбек, например, записывая trd в очередь между коллбеком и потоком main (со sleep(50) ), в котором выполнять остальную обработку таблицы trd. Вариант реализации очереди выложен мной в соседней ветке пользователя VPM. 2. Если вам нужны данные по сделкам, то их можно получать готовыми из таблицы QUIK trade с помощью функции getItem. Зачем вы отрабатываете "сырые" коллбеки OnTrade?
Я наблюдал, что даже в тех случаях, если коллбек содержал прямую задержку (я в качестве эксперимента ставил 500 мс), это не приводило к потере данных. Т.е. если даже десять транзакций в секунду выполняются, да, обработка функций от них растягивается на 5 сек, но в итоге они все обработаны. В тех случаях, когда наблюдались потерянные данные, таких сверхбыстрых вызовов не было, т.е. кажется, причина в другом. Но на всякий случай сейчас я все дополнительные задержки в коллбеках убрал, и они реально выполняются мгновенно. Посмотрим, будет ли ошибка повторяться.
Предложенная вами очередь событий сильно усложнит код, поэтому без слишком явной необходимости мне не хотелось бы так делать. Такая очередь наверное нужна, если код использует тяжёлые вычисления типа машинного обучения и т.д. У меня ничего такого нет.
Пользователь
Сообщений: Регистрация: 15.06.2023
12.02.2026 21:11:44
User12501, Скажите на русском читаете, если нет, то какие слова Вам не понятны
Цитата
VPM написал: Просто разбираюсь с тем же самым, и вот что удалось выяснить не который слой ошибок. Почему роботы закрываются "просто так" и как это фиксят в проп-торговле? Это класс ошибок, который случается даже с идеально спроектированными системами. И причина всегда одна: > Расхождение между биржевой реальностью и состоянием в QUIK!
Вот конкретные механизмы (примеры).
1. Главная причина: Асинхронность данных в QUIK. Здесь помним QUIK — это клиент терминал, а не биржа!
Время в QUIK ~= Время на бирже local q_time = -- локальное время QUIK local e_time = -- время биржи (если доступно) Разница может быть ~ 0.1-5 секунд, а то и более!
Что происходит: 1. Биржа. Цена прошла стоп > стоп сработал; 2. QUIK (через 0.5-2 сек). Получил тик > показал в стакане; 3. Робот. Увидел в стакане > решил "стоп сработал"; 4. Но, Стоп уже сработал на бирже, а в QUIK ещё не отобразился. Результат: робот пытается отменить уже исполненный стоп > получает ошибку! --------------------------------
2. "Призрачные" стопы в QUIK. QUIK показывает активный стоп. stop_order = getItem("stop_orders", index) if stop_order.flags == 1 then -- Считаем активным -- Но на бирже он мог уже сработать! end
Это случается при: * Лаге данных (биржа > шлюз брокера > QUIK); * Частичном исполнении (часть уже исполнилась, QUIK ещё не обновил qty); * Ошибках протокола (QUIK не получил подтверждение удаления). --------------------------------
3. Классический кейс рассинхрона. Таймлайн (реальный): [00:00.000] Цена Bid = 100 000 (на бирже) [00:00.100] Цена достигает стопа 100 000 [00:00.150] Биржа исполняет стоп [00:00.300] QUIK получает обновление стакана [00:00.350] Робот видит Bid = 100 000 > думает "стоп ещё не сработан" [00:00.400] Робот пытается изменить стоп > ошибка
Пользователь
Сообщений: Регистрация: 15.06.2023
12.02.2026 21:14:40
Это маленькая толика, возможных ситуаций, довьёт еще свои. и будем обсуждать Ваши, подход ваш так себе.
Пользователь
Сообщений: Регистрация: 26.11.2025
13.02.2026 10:11:48
Цитата
VPM написал: , Скажите на русском читаете, если нет, то какие слова Вам не понятны
Цитата
Более-менее все слова понятны, только непонятно, как они связаны с моим вопросом.
Пользователь
Сообщений: Регистрация: 30.01.2015
13.02.2026 11:14:59
Цитата
User12501 написал: Сегодня опять случилась эта бяка. За секунду произошли четыре транзакции, по трём из них полная версия OnTrade (с ненулевым trans_id) не пришла. Видимо придётся убрать из скрипта эту дополнительную проверку. Но вообще факт неприятный.
Когда делал тесты системы выставления заявок по лучшей цене, то наблюдал подобные эффекты. Как я понял это происходи тогда, когда заявка сразу исполняется встречной. В этом случае приходит сообщение что она и выставилаcь и исполнилась все в одном. При этом OnTransReply тоже содержит всю информацию о заявке. -------------------- Мне собственно безразлично такие ситуации, так как без разницы сколько раз поступили события по транзакции,заявке или сделке.
Пользователь
Сообщений: Регистрация: 12.05.2020
13.02.2026 14:43:13
И все таки:
Цитата
TGB написал: 2. Если вам нужны данные по сделкам, то их можно получать готовыми из таблицы QUIK trade с помощью функции getItem. Зачем вы отрабатываете "сырые" коллбеки OnTrade?
Пользователь
Сообщений: Регистрация: 12.05.2020
13.02.2026 14:45:36
Вопрос задан User12501.
Пользователь
Сообщений: Регистрация: 30.01.2015
14.02.2026 06:52:41
, Покажите как Вы реализовали ОnTrade. Возможно будет понятнее причина.
Пользователь
Сообщений: Регистрация: 15.06.2023
14.02.2026 10:12:02
"В последнее время несколько раз наблюдал такое: приходит OnTrade, в котором trans_id=0. Я знаю, что это промежуточная версия, поэтому в мой алгоритм вписано игнорировать такие вызовы, ожидая более полных. И почти всегда они приходят. Но в среднем 1-2 раза за день случается так, что полный OnTrade с ненулевым trans_id так и не приходит. В чём может быть причина?" Ответ очевиден может.
Ситуация, которую вы описываете, связана не с багом в вашем коде, а с особенностями того, как QUIK и брокерский шлюз доставляют информацию о сделках. Подобную ошибку в событийной модели допускают даже грамотные, опытные разработчики на QUIK. Используя "умную заявку" (один trans_id=const на весь жизненный цикл инструмента, для 3 таблиц) в своих подходах, отлавливал такую же проблему.
Почему полный OnTrade может не прийти? То, что за день теряется 1-2 полных события, — это тревожный, но, к сожалению, не уникальный случай для распределенных систем.
Вот наиболее вероятные причины:
* Потеря пакетов на сетевом уровне: Система QUIK и брокерский шлюз обмениваются большим количеством данных. В условиях нестабильной сети или высокой нагрузки пакет со вторым, полным, событием мог быть просто потерян.
* Сбои в очередях событий QUIK: В самом терминале или на стороне брокерского шлюза есть очереди событий. При переполнении или внутреннем сбое часть событий может быть отброшена, не доходя до вашего скрипта.
* Особенности логики брокерского шлюза: Хотя это менее вероятно, существует возможность, что в редких случаях логика шлюза, отправляющего два события (служебное и полное), дает сбой, и второе событие не генерируется.
Наверняка список можно расширить.
Пользователь
Сообщений: Регистрация: 30.01.2015
14.02.2026 13:04:19
По-моему мнению причина в том, что trans_id - это идентификатор транзакции. Главное в этой фразе что это ТРАНЗАКЦИЯ. И это транзакция на выставление заявки. Т е это не id заявки и не id сделки. Поэтому вполне допускаю, что сервер QUIK не посылает повторно сообщение о сделке, если все параметры сделки уже переданы. Нет смыла тратить время на передачу id. Возможно это происходит если сделки совершаются с малым интервалом. Тогда второе сообщение по первой сделки просто затирается сообщением по второй. Но в любом случае отслеживать id транзакции в сообщениях по сделке это нонсенс.
Пользователь
Сообщений: Регистрация: 26.11.2025
15.02.2026 03:55:34
Цитата
VPM написал: "В последнее время несколько раз наблюдал такое: приходит OnTrade, в котором trans_id=0. Я знаю, что это промежуточная версия, поэтому в мой алгоритм вписано игнорировать такие вызовы, ожидая более полных. И почти всегда они приходят. Но в среднем 1-2 раза за день случается так, что полный OnTrade с ненулевым trans_id так и не приходит. В чём может быть причина?" Ответ очевиден может.
Ситуация, которую вы описываете, связана не с багом в вашем коде, а с особенностями того, как QUIK и брокерский шлюз доставляют информацию о сделках. Подобную ошибку в событийной модели допускают даже грамотные, опытные разработчики на QUIK. Используя "умную заявку" (один trans_id=const на весь жизненный цикл инструмента, для 3 таблиц) в своих подходах, отлавливал такую же проблему.
Почему полный OnTrade может не прийти? То, что за день теряется 1-2 полных события, — это тревожный, но, к сожалению, не уникальный случай для распределенных систем.
Вот наиболее вероятные причины:
* Потеря пакетов на сетевом уровне: Система QUIK и брокерский шлюз обмениваются большим количеством данных. В условиях нестабильной сети или высокой нагрузки пакет со вторым, полным, событием мог быть просто потерян.
* Сбои в очередях событий QUIK: В самом терминале или на стороне брокерского шлюза есть очереди событий. При переполнении или внутреннем сбое часть событий может быть отброшена, не доходя до вашего скрипта.
* Особенности логики брокерского шлюза: Хотя это менее вероятно, существует возможность, что в редких случаях логика шлюза, отправляющего два события (служебное и полное), дает сбой, и второе событие не генерируется.
Наверняка список можно расширить.
Ну у меня trans_id не const, а как раз уникальный для каждой заявки. А в остальном - ок, в целом я и сам догадывался, что причина либо в потерянных пакетах (хотя если используется протокол TCP, они должны были быть отправлены повторно), либо во внутренних сбоях quik. Видимо ничего здесь не сделать, придётся учитывать вероятность такой ошибки в коде.
Пользователь
Сообщений: Регистрация: 02.01.2026
15.02.2026 08:58:46
Цитата
User12501 написал: Но возможно именно у тех сделок, о которых речь, не было. Не проверял, в следующий раз как случится - посмотрю.
Вот с этого и надо было начинать. Какой ACTION указан у транзакции, сделки по которым без trans_id?
Пользователь
Сообщений: Регистрация: 15.06.2023
15.02.2026 11:49:16
Цитата
User12501 написал: Видимо ничего здесь не сделать, придётся учитывать вероятность такой ошибки в коде.
Ну почему ни чего? Можно попробовать, двухэтапную обработку с таймаутом, решение более надежно. Ваша текущая проверка на trans_id верна, но её просто недостаточно для гарантированной обработки всех сделок. Попробуйте, внедрение кэша с таймаутом — это стандартный паттерн для работы с асинхронными и ненадежными потоками событий?
Пользователь
Сообщений: Регистрация: 02.01.2026
15.02.2026 12:39:12
Цитата
TGB написал: Зачем вы отрабатываете "сырые" коллбеки OnTrade?
Но вы так-то тоже "сырые" колбэки и получаете соответствующие проблемы, которые потом закрываете "костылями".
Пользователь
Сообщений: Регистрация: 12.05.2020
15.02.2026 13:23:37
Цитата
Йцукен написал: Но вы так-то тоже обрабатываете "сырые" колбэки и получаете соответствующие проблемы, которые потом закрываете "костылями".
В моих роботах единственный обрабатываемый коллбек это OnTransReply по той причине, что в нем есть информация о возможных причинах отказа в выставлении заявки. При этом я предполагаю, что он может теряться и отслеживаю в таймере выставление заявки по времени, проверяя таблицу заявок (orders соответственно stop_orders). Если заявка не появилась в соответствующей таблице в течении 120 секунд, то это ошибка в выставлении и есть ветка отработки этой ошибки. Все остальное, включая случаи необходимости получения текущих данных таблиц текущих торгов и тд. я беру из таблиц QUIK, кешируя для быстрого доступа индексы используемых таблиц. Признаком изменения состояния таблиц (исключая orders, stop_orders) является изменение длины, которую можно получать функцией getNumberOf. Признаком возможных изменений в существующих записях orders и stop_orders является изменение длины таблицы сделок. Вообще, для торговли надо знать состояние своего счета и какую то картину рынка. Все это можно получить из таблиц QUIK и я не вижу смысла возни с коллбеками.
Пользователь
Сообщений: Регистрация: 27.01.2017
15.02.2026 13:41:27
Цитата
TGB написал: В моих роботах единственный обрабатываемый коллбек это OnTransReply по той причине, что в нем есть информация о возможных причинах отказа в выставлении заявки. При этом я предполагаю, что он может теряться и отслеживаю в таймере выставление заявки по времени, проверяя таблицу заявок (orders соответственно stop_orders). Если заявка не появилась в соответствующей таблице в течении 120 секунд, то это ошибка в выставлении и есть ветка отработки этой ошибки. Все остальное, включая случаи необходимости получения текущих данных таблиц текущих торгов и тд. я беру из таблиц QUIK, кешируя для быстрого доступа индексы используемых таблиц. Признаком изменения состояния таблиц (исключая orders, stop_orders) является изменение длины, которую можно получать функцией getNumberOf. Признаком возможных изменений в существующих записях orders и stop_orders является изменение длины таблицы сделок. Вообще, для торговли надо знать состояние своего счета и какую то картину рынка. Все это можно получить из таблиц QUIK и я не вижу смысла возни с коллбеками.
Я использую такой же подход. Тем более что сканировать таблицы необходимо в любом случае при старте скрипта.
Правда такой подход уже сложнее реализовывать, если данные гоняются через socket в алгоритмы, написанные не на lua. Необходимо реализовывать свой колбек на стороне socket сервера, организованного также через сравнение числа записей. А также колбеки по изменению данных в записи таблицы, например, флага состояния или баланса.
написал: Но вы так-то тоже обрабатываете "сырые" колбэки и получаете соответствующие проблемы, которые потом закрываете "костылями".
В моих роботах единственный обрабатываемый коллбек это OnTransReply по той причине, что в нем есть информация о возможных причинах отказа в выставлении заявки. При этом я предполагаю, что он может теряться и отслеживаю в таймере выставление заявки по времени, проверяя таблицу заявок (orders соответственно stop_orders). Если заявка не появилась в соответствующей таблице в течении 120 секунд, то это ошибка в выставлении и есть ветка отработки этой ошибки. Все остальное, включая случаи необходимости получения текущих данных таблиц текущих торгов и тд. я беру из таблиц QUIK, кешируя для быстрого доступа индексы используемых таблиц. Признаком изменения состояния таблиц (исключая orders, stop_orders) является изменение длины, которую можно получать функцией getNumberOf. Признаком возможных изменений в существующих записях orders и stop_orders является изменение длины таблицы сделок. Вообще, для торговли надо знать состояние своего счета и какую то картину рынка. Все это можно получить из таблиц QUIK и я не вижу смысла возни с коллбеками.
Ну говорить про этот подход и не сказать про его ограниченность, как минимум не корректно. Для простых систем да. А если у вас несколько стратегий на разных инструментах, таблицы обновляются асинхронно. Вы не можете гарантировать, что в момент принятия решения о новой сделке все кеши консистентные, то есть согласованные. Особенно остро это проявляется при работе с лимитами риска, вам нужно точно знать суммарную позицию, а она может временно «плавать» из‑за задержек обновления разных таблиц.
Ну или просто банально OnTransReply может потеряться. Вы ждёте 120 секунд — это огромный интервал. За это время рынок может уйти далеко, а вы всё ещё не знаете, исполнилась ли заявка. В результате вы можете пропустить возможность или, наоборот, ошибочно считать, что заявка не прошла, и повторить отправку (что приведёт к дублированию)?
Пользователь
Сообщений: Регистрация: 12.05.2020
15.02.2026 14:15:06
Цитата
Nikolay написал: Правда такой подход уже сложнее реализовывать, если данные гоняются через socket в алгоритмы, написанные не на lua.
У меня есть простая функциональность создания собственных событий в виде таблиц событий, в которые записываются функции с их параметрами при подписке на событие. Если надо, то при наступлении в скрипте события, например, появления каких то данных выполняется запуск всех функций таблицы соответствующей такому событию.
Это ваш выбор. Но я написал о другом. Ваш подход также не исключает получения "сырых", как вы выразились, колбэков по заявкам / сделкам. Просто вы получаете их гораздо реже в силу того, что, как правило, колбэки с заполненными параметрами идут сразу следом за частично заполненными. Часто в ту же миллисекунду. Поэтому в таблице вы уже видите все параметры. Но это не исключает вероятности получения "сырых" данных, о чём вы и написали в этой теме: Ваш подход мне понятен, и он имеет свои плюсы. Но что на счёт рыночных данных по инструментам? Колбэки OnParam и OnQuote сообщают, когда произошло изменение. Как вы определяете эти изменения?
Пользователь
Сообщений: Регистрация: 12.05.2020
15.02.2026 14:45:20
1.
Цитата
VPM написал: Ну или просто банально OnTransReply может потеряться. Вы ждёте 120 секунд — это огромный интервал.
Кто вас заставляет ждать 120 сек.? Ждите 1 млс. И, вообще, возитесь с коллбеками сколько хотите . Для вас чем сложнее, тем лучше.
Я знаю как делать сложные системы не теоретически. И один из основных принципов их создания это не делать лишних движений. Несделанное, во-первых, не ломается, а во вторых, супер эффективно, так как не требует ресурсов. С тем подходом к созданию роботов, который использует Nikolay и я не видно проблем создания сложных роботов. Кстати, хотя я стараюсь находить и использовать простые решения, робот у меня не сильно простой. Во всяком случае он полностью автономный. Я, конечно, смотрю что он делает, но уже давно он работает месяцами без моего вмешательства.
Пользователь
Сообщений: Регистрация: 15.06.2023
15.02.2026 14:52:28
TGB, Описаный Вами подход не хуже и не лучше — он просто другой. Он проще и для многих задач работает, а может даже и оптимален.
Но если задача стоит построить систему, которая должна быть математически корректной, отказоустойчивой и масштабируемой, без событийной модели и формальных инвариантов не обойтись. Потому что её поведение можно доказать на реальной торговле на любых объёмах и с любыми стратегиями, а не просто протестировать!
Могу привести еще недостатки Вашего подхода, но прислушаюсь к совету
Цитата
TGB написал: Несделанное, во-первых, не ломается, а во вторых, супер эффективно, так как не требует ресурсов.
Пользователь
Сообщений: Регистрация: 12.05.2020
15.02.2026 15:18:45
Цитата
Йцукен написал: Это ваш выбор. Но я написал о другом.Ваш подход также не исключает получения "сырых", как вы выразились, колбэков по заявкам / сделкам.Просто вы получаете их гораздо реже в силу того, что, как правило, колбэки с заполненными параметрами идут сразу следом за частично заполненными.
1. Читайте:
Цитата
TGB написал: В моих роботах единственный обрабатываемый коллбек это OnTransReply
2. Вы проверяли задержку между коллбэком с заполненными параметрами и появлением записи в таблице? Если нет, то проверьте.
Цитата
Йцукен написал: Колбэки OnParam и OnQuote сообщают, когда произошло изменение. Как вы определяете эти изменения?
1. Я OnQuote не пользуюсь. QUIK не предназначен для высокочастотной торговли. Из стакана вам приходит история с задержкой как минимум 2-3 сек. и ваша реакция, скорее всего, тоже > 2 сек. Хотелось увидеть реальные доходные стратегии в таких условиях. 2. Если мне нужны какие то данные из текущей таблицы торгов, то я их читаю в цикле, с нужным мне периодом (у меня есть возможность создавать такие циклы, кроме основного) и фильтрую, чтобы не было повторов, по параметру VOLTODAY. Получается не хуже по результату и эффективности использования ПК, чем при использовании OnParam.
Пользователь
Сообщений: Регистрация: 27.01.2017
15.02.2026 15:22:25
Цитата
VPM написал: , Описаный Вами подход не хуже и не лучше — он просто другой. Он проще и для многих задач работает, а может даже и оптимален.
Но если задача стоит построить систему, которая должна быть математически корректной, отказоустойчивой и масштабируемой, без событийной модели и формальных инвариантов не обойтись. Потому что её поведение можно доказать на реальной торговле на любых объёмах и с любыми стратегиями, а не просто протестировать!
Могу привести еще недостатки Вашего подхода, но прислушаюсь к совету
Вы исходите из того, что колбек в Квике - это гарантированное событие. Но это не так. Одно это уже заставляет просто даже не смотреть в их сторону. Потом скорость и асинхронность - я не очень понимаю этот довод, т.к. это тоже не гарантирует получения консистентных данных. Смотрим в сторону CAP теоремы. Колбек может прийти как до момента, когда Вам надо принять решение, а может после (а в подходе с ручным контролем можете сами опросить данные прямо в необходимый момент). Если хотите больше гарантий, то, как минимум, необходимо строить систему, учитывающую команды всех скриптов, принимать решение с их учетом, например, учитывать транзакции по которым еще не получены ответы и данные по деньгам уже некорректны. Но даже если скрипт один, в момент принятия решения Вы не знаете о своем портфеле точной информации, банально потому, что данные которые видите - это прошлое. Настоящее оно на сервере биржи и приедет к вам через некую задержку. Поэтому для некоторых систем уменьшение задержек на 1 млс - стоит того, чтобы проложить отдельное оптоволокно сквозь горы.
Пользователь
Сообщений: Регистрация: 12.05.2020
15.02.2026 15:34:43
Цитата
VPM написал: которая должна быть математически корректной, отказоустойчивой и масштабируемой, без событийной модели и формальных инвариантов не обойтись.Потому что её поведение можно доказать на реальной торговле на любых объёмах и с любыми стратегиями, а не просто протестировать!
Зачем вы используете, не первый раз громкие понятия. от которых, похоже, очень далеки? Вы сделали в математике открытие: "доказать на реальной торговле" . Вам это надо опубликовать в научном журнале.
Пользователь
Сообщений: Регистрация: 15.06.2023
15.02.2026 15:37:13
TGB, Дело несколько в другом. Действительно, колбэки в QUIK не являются гарантированными, и любая система, работающая с реальной биржей, сталкивается с задержками, потерями и недетерминизмом. CAP-теорема здесь работает в полную силу, в распределённой системе, где биржа — это внешний, неподконтрольный нам узел.
Однако, из этого не следует, что событийно-ориентированная архитектура бессмысленна?
Напротив, она предназначена именно для того, чтобы жить в мире, где события могут теряться, приходить не в том порядке или с задержкой. Разница между вашим подходом (опрос таблиц + OnTransReply) и событийной моделью не в том, что событийная модель предполагает надёжность колбэков, а в том, как она обрабатывает неопределённость!
Пользователь
Сообщений: Регистрация: 15.06.2023
15.02.2026 15:45:49
TGB, А какие слова для Вас не понятны? Повторюсь, безопасность счёта можно доказать математически, событийная модель с инвариантами и реконсиляцией — единственный известный путь.
Пользователь
Сообщений: Регистрация: 12.05.2020
15.02.2026 15:47:01
Цитата
VPM написал: как она обрабатывает неопределённость!
Мне, кажется, что обычно всем желательна определенность, особенно в сфере финансов, а вы жаждете приключений .Такое тоже бывает.
Пользователь
Сообщений: Регистрация: 12.05.2020
15.02.2026 15:50:40
Цитата
VPM написал: безопасность счёта можно доказать математически
Определите что такое безопасность счета и приведите математическое доказательство (можете посоветоваться с ИИ).