Не приходит полная версия OnTrade

Страницы: 1
RSS
Не приходит полная версия OnTrade
 
В последнее время несколько раз наблюдал такое: приходит OnTrade, в котором trans_id=0. Я знаю, что это промежуточная версия, поэтому в мой алгоритм вписано игнорировать такие вызовы, ожидая более полных. И почти всегда они приходят. Но в среднем 1-2 раза за день случается так, что полный OnTrade с ненулевым trans_id так и не приходит. В чём может быть причина?
Я мог бы убрать эту дополнительную проверку из своего кода и обрабатывать такие вызовы, в принципе trans_id мне ни для чего не нужен, достаточно brokerref. Но ведь может не прийти что-то более важное. Например бывает, что приходит OnTrade с нулевой комиссией, и сразу после него ещё один OnTrade с заполненной комиссией. Здесь сбоев не было ни разу, но что если он тоже не придёт?
 
Цитата
User12501 написал:
В последнее время несколько раз наблюдал такое: приходит OnTrade, в котором trans_id=0. Я знаю, что это промежуточная версия, поэтому в мой алгоритм вписано игнорировать такие вызовы, ожидая более полных. И почти всегда они приходят. Но в среднем 1-2 раза за день случается так, что полный OnTrade с ненулевым trans_id так и не приходит. В чём может быть причина?
Я мог бы убрать эту дополнительную проверку из своего кода и обрабатывать такие вызовы, в принципе trans_id мне ни для чего не нужен, достаточно brokerref. Но ведь может не прийти что-то более важное. Например бывает, что приходит OnTrade с нулевой комиссией, и сразу после него ещё один OnTrade с заполненной комиссией. Здесь сбоев не было ни разу, но что если он тоже не придёт?
А зачем Вам trans_id в сделке?
-------------------
Поясняю:
Сделка совершается по выставленной заявке. В сделке есть номер заявки,
Номер есть всегда и по нему можно найти эту заявку.
-----------------------------
trans_id - это номер транзакции, по которой уже выставлена заявка.
т е транзакция уже давно исполнена.
Вместо нее есть заявка.
В данном случае и заявка исполнена, вместо нее есть сделка.
Т е  даже заявку нет смысла искать, а уж  trans_id тем более...
 
Цитата
nikolz написал:
Цитата
User12501 написал:
В последнее время несколько раз наблюдал такое: приходит OnTrade, в котором trans_id=0. Я знаю, что это промежуточная версия, поэтому в мой алгоритм вписано игнорировать такие вызовы, ожидая более полных. И почти всегда они приходят. Но в среднем 1-2 раза за день случается так, что полный OnTrade с ненулевым trans_id так и не приходит. В чём может быть причина?
Я мог бы убрать эту дополнительную проверку из своего кода и обрабатывать такие вызовы, в принципе trans_id мне ни для чего не нужен, достаточно brokerref. Но ведь может не прийти что-то более важное. Например бывает, что приходит OnTrade с нулевой комиссией, и сразу после него ещё один OnTrade с заполненной комиссией. Здесь сбоев не было ни разу, но что если он тоже не придёт?
А зачем Вам trans_id в сделке?
Конкретно trans_id мне не нужен. Но если по протоколу он должен прийти, и не приходит, значит что-то пошло не так. В другой раз не прийти может что-то более серьёзное, например комиссия. Или это другое?
Вопрос отчасти пересекается с моим предыдущим вопросом про повторные OnTrade ( https://forum.quik.ru/forum10/topic9419/ ). Т.е. по trans_id=0 я пытался фильтровать OnTrade, которые заведомо не последние.
 
Цитата
User12501 написал:
Цитата
nikolz написал:
 
Цитата
User12501  написал:
В последнее время несколько раз наблюдал такое: приходит OnTrade, в котором trans_id=0. Я знаю, что это промежуточная версия, поэтому в мой алгоритм вписано игнорировать такие вызовы, ожидая более полных. И почти всегда они приходят. Но в среднем 1-2 раза за день случается так, что полный OnTrade с ненулевым trans_id так и не приходит. В чём может быть причина?
Я мог бы убрать эту дополнительную проверку из своего кода и обрабатывать такие вызовы, в принципе trans_id мне ни для чего не нужен, достаточно brokerref. Но ведь может не прийти что-то более важное. Например бывает, что приходит OnTrade с нулевой комиссией, и сразу после него ещё один OnTrade с заполненной комиссией. Здесь сбоев не было ни разу, но что если он тоже не придёт?
 А зачем Вам trans_id в сделке?
Конкретно trans_id мне не нужен. Но если по протоколу он должен прийти, и не приходит, значит что-то пошло не так. В другой раз не прийти может что-то более серьёзное, например комиссия. Или это другое?
Вопрос отчасти пересекается с моим предыдущим вопросом про повторные OnTrade (  https://forum.quik.ru/forum10/topic9419/  ). Т.е. по trans_id=0 я пытался фильтровать OnTrade, которые заведомо не последние.
Предположу, что он не приходит при выполнении заявки в нескольких сделках, либо в заявках, установленных до за пуска скрипта. Но это лишь предположение.
 
Добрый день.

Уточните, пожалуйста, версию Рабочего места QUIK, которую Вы в данный момент используете? Используется свой скрипт или какие-то готовые библиотеки? По каким именно сделкам не приходят trans_id, можете привести пример? Заполнен ли при этом параметр в Таблице Сделок в Рабочем месте?
 
Цитата
Oleg Kuzembaev написал:
Добрый день.

Уточните, пожалуйста, версию Рабочего места QUIK, которую Вы в данный момент используете? Используется свой скрипт или какие-то готовые библиотеки? По каким именно сделкам не приходят trans_id, можете привести пример? Заполнен ли при этом параметр в Таблице Сделок в Рабочем месте?
Версия quik 12.6.0.53. Полностью свой скрипт. Например сделка на покупку одной акции SOFL. Последний раз ошибка была 1-го февраля. За короткий промежуток были совершены три абсолютно идентичные сделки по близкой цене: в 17:01:54, в 17:04:15, и в 17:05:29. Все три на покупку одной акции SOFL. По первой и третьей сделкам пришли три функции OnTrade. По второй сделке только одна. Замечу также, что по первой и третьей сделкам вместе с функциями OnTrade приходили также две функции OnOrder, по второй сделке функция OnOrder пришла только одна. Но в эти функции я не заглядывал, не могу сказать, в чём отличие (если это важно - могу заглянуть, всё сохранено). Каких-либо особых событий, предшествовавших этой ошибке, типа разрыва соединения и т.д., не наблюдалось.  
 
User12501,
Два вопроса, которые могут дать ответ.
1) С какой задержкой у вас Sleep в main?
2) есть ли у Вас очередь событий?
 
Цитата
nikolz написал:
User12501 ,
Два вопроса, которые могут дать ответ.
1) С какой задержкой у вас Sleep в main?


2) есть ли у Вас очередь событий?
 
Цитата
nikolz написал:
User12501 ,
Два вопроса, которые могут дать ответ.
1) С какой задержкой у вас Sleep в main?
2) есть ли у Вас очередь событий?
1) 585 секунд.
2) Не знаю. А что это?

(Предыдущее сообщение отправилось по ошибке, не ту клавишу нажал).  
 
Цитата
User12501 написал:
Цитата
nikolz написал:
 User12501  ,
Два вопроса, которые могут дать ответ.
1) С какой задержкой у вас Sleep в main?
2) есть ли у Вас очередь событий?
1) 585 секунд.
2) Не знаю. А что это?

(Предыдущее сообщение отправилось по ошибке, не ту клавишу нажал).  
Тогда вероятнее всего Вы просто теряете сообщения, когда по заявке совершаются несколько сделок относительно быстро.
Если надо принять все то сделайте очередь сообщений.  один из примеров есть в документации на библиотеку QLUA
Другой есть в моей теме на форуме по универсальному обработчику событий
 
Цитата
User12501 написал:
585 секунд
  У вас sleep(585000)???
 
Цитата
nikolz написал:
Цитата
User12501 написал:
 
Цитата
nikolz  написал:
  User12501   ,
Два вопроса, которые могут дать ответ.
1) С какой задержкой у вас Sleep в main?
2) есть ли у Вас очередь событий?
 1) 585 секунд.
2) Не знаю. А что это?

(Предыдущее сообщение отправилось по ошибке, не ту клавишу нажал).  
Тогда вероятнее всего Вы просто теряете сообщения, когда по заявке совершаются несколько сделок относительно быстро.
Непонятно. Насколько я знаю, все функции OnTrade приходят в одном потоке, т.е. даже если две сделки совершились строго одновременно, функции по ним вызовутся последовательно, и их невозможно потерять.

Кроме того, в приведённом примере интервал между сделками несколько секунд. Это не быстро. Быстро - это когда десятки сделок в секунду. Я такое видел, и мой скрипт их успешно обрабатывает.  
 
Цитата
TGB написал:
Цитата
User12501 написал:
585 секунд
   У вас sleep(585000)???
Да. Примерно 10 минут.  
 
Цитата
User12501 написал:
Цитата
nikolz написал:
 
Цитата
User12501  написал:
 
Цитата
 nikolz   написал:
   User12501    ,
Два вопроса, которые могут дать ответ.
1) С какой задержкой у вас Sleep в main?
2) есть ли у Вас очередь событий?
  1) 585 секунд.
2) Не знаю. А что это?

(Предыдущее сообщение отправилось по ошибке, не ту клавишу нажал).  
 Тогда вероятнее всего Вы просто теряете сообщения, когда по заявке совершаются несколько сделок относительно быстро.
Непонятно. Насколько я знаю, все функции OnTrade приходят в одном потоке, т.е. даже если две сделки совершились строго одновременно, функции по ним вызовутся последовательно, и их невозможно потерять.

Кроме того, в приведённом примере интервал между сделками несколько секунд. Это не быстро. Быстро - это когда десятки сделок в секунду. Я такое видел, и мой скрипт их успешно обрабатывает.  
Если правильно вас понял, то Вы обрабатываете все события внутри колбеков.
Т е Вы тормозите терминал QUIK на время работы вашего скрипта.
Да, в этом случае события вероятно вы не пропустите. Но это лишь предположение,
Судя по установленной Вами задержки,  и в этом случае найдутся способные  написать такой скрипт.
 
Сегодня опять случилась эта бяка. За секунду произошли четыре транзакции, по трём из них полная версия OnTrade (с ненулевым trans_id) не пришла. Видимо придётся убрать из скрипта эту дополнительную проверку. Но вообще факт неприятный.  
 
Цитата
User12501 написал:
Да. Примерно 10 минут.
   Не видя вашего кода, сложно что-то сказать, но попробуйте сделать  sleep(50)  и посмотрите что будет.
С задержкой 585000 ваш код в main практически отключен. Это так вами задумано?
 
Цитата
TGB написал:
Цитата
User12501 написал:
Да. Примерно 10 минут.
    Не видя вашего кода, сложно что-то сказать, но попробуйте сделать  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 не приходила.  
 
Замечу также, что ошибка возникает крайне редко. Я выше писал - 1-2 раза в день, но это было преувеличение. На самом деле вот сегодня она случилась трижды, а до этого в последний раз была 1-го февраля. При том что мой код работает ежедневно и выполняет сотни транзакций в день. Если бы бяка была в моём коде, она бы вылезала чаще.  
 
User12501, по каким классам инструментов наблюдается?
В самой таблице сделок trans_id есть?
 
Просто разбираюсь с тем же самым, и вот что удалось выяснить не который слой ошибок. Почему роботы закрываются "просто так" и как это фиксят в проп-торговле?
Это класс ошибок, который случается даже с идеально спроектированными системами. И причина всегда одна: > Расхождение между биржевой реальностью и состоянием в 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] Робот пытается изменить стоп > ошибка
 
Цитата
User12501 написал:
Таким образом, до начала проверок и основного кода, ВСЕ trd сохраняются в текстовый файл.
   1. Всю обработку вы делаете в служебном потоке коллбека (отличным от потока main). Этот поток в QUIK один и он обслуживает все запущенные скрипты QUIK. Когда он занят вашей обработкой он перестает выполнять свои служебные функции, в том числе, обработку вновь возникающих данных по сделкам. Если нет служебной очереди внутри QUIK, то возможны потери возникающих данных. В вашем варианте желательно как можно быстрее выполнять коллбек, например, записывая trd в очередь между коллбеком и потоком main (со sleep(50) ), в котором выполнять остальную обработку таблицы trd. Вариант реализации очереди выложен мной в соседней ветке пользователя VPM.
   2. Если вам нужны данные по сделкам, то их можно получать готовыми из таблицы QUIK trade с помощью функции getItem. Зачем вы отрабатываете "сырые" коллбеки OnTrade?
Страницы: 1
Читают тему
Наверх