Блог им. HOME

Коллбэки своими руками. Личный опыт.


              Не знаю, может, я такой бестолковый или возраст наложил свою замшелую лапу на мозг, но какое-то время назад (что-то около 2018 года) пропало желание экспериментировать с коллбэками (типа, OnTransReply, OnOrders  и прочие) в QUIK’е. Наверное, это — полезные инструменты, но у меня как-то не сложились отношения с ними. То не приходят, то задваиваются, то приходят не вовремя и пачками за все пропущенные периоды. Как-то ненадежно, в общем.

              Периодически отслеживаю на форуме ARQA, но время идет, а проблема, похоже не решается, т.к. много вопросов задаются пользователями, а действенных советов не прибавляется.

              В общем, в том далеком уже году бросил я это занятие и решил заменить терминальные коллбэки своими собственными суррогатами. Время показало, что эти «суррогаты» неплохо себя зарекомендовали, а бот нормально их переваривает.

              В конце поста приложу логическую блок-схему «суррогата», которая может показаться излишне сложной для неподготовленного ума, но, прошу поверить, что дело того стоит:

  • Нет задваивания заявок,
  • Абсолютно стало «побоку» на действия брокера, когда у вас внезапно, «в самый интересный и ответственный момент», отваливается терминал («удаленный хост разорвал соединение…» или «вы уже работаете в системе…»), а бот продолжает генерить команды по работе с ордерами (выдача новых или перемещение неисполненных),
  • Даже в случае продолжительного дисконнекта и фактической потери ботом части рынка, после восстановления коннекта бот сразу встает в нужную позицию. Да, потери и убытки возможны, но зато не теряется смысл стратегии.
  • Исключение ситуаций, когда «вы не можете снять заявку…» или «вы не можете выставить заявку…».

 

Идея такова:

  1. Разбить «жизнь» заявки на этапы,
  2. Ввести процедуры верификации каждого этапа (собственно, это и есть «суррогаты» коллбэков»),
  3. Задать критерии начала и окончания каждого этапа с передачей заявки или состояния бота последовательно от начала её «жизни» до логического завершения (реализации), а также возврат бота в состояние готовности «0», т.е. на отработку самой стратегии.
  4. Завести регистры учета параметров и состояний ордеров, однозначно позволяющие управлять (регистрировать, разрешать реализацию этапа, блокировать этап или активность бота в части выдачи новых заявок).
  5. Создание механизма СИНХРОНИЗАЦИИ действий бота с информационным потоком терминала, построенный по принципу «ПО СОБЫТИЯМ», т.е. бот выполняет каждое последующее действие ТОЛЬКО ПОСЛЕ ПОСТУПЛЕНИЯ ОЧЕРЕДНОЙ ЗАКОНОМЕРНОЙ порции информации.

 

 

Для целей реализации создан инструмент ТРИГГЕРОВ, переключающих последовательно СТАДИИ РЕАЛИЗАЦИИ ордеров. Таких этапов – 4:

ОСНОВНОЙ РЕЖИМ – генерация системных ордеров по стратегии (выдача заявки, проверка её состояния с помощью test.bit-операции), 

РЕЖИМ ЗАВИСШИХ ОРДЕРОВ – реализация перемещаемых ордеров в случае, если заявка не реализована и «висит» в стакане дольше, чем время реакции ТС, назначенное параметром Sleep (по умолчанию, 10 секунд).

РЕЖИМ ОТЛОЖЕННЫХ ОРДЕРОВ – реализация заявок, не прошедших контроль терминала (ошибки, сбои и т.д.) в первый раз.

РЕЖИМ ВЫРАВНИВАНИЯ ПОЗИЦИЙ – процедура выравнивания позиции в терминале с РАСЧЕТНОЙ ПОЗИЦИЕЙ, хранящейся в системе Управленческого Учета бота в соответствии со стратегией.

 

Алгоритм (кратко):

В начале цикла расчетов бота, а также на каждой стадии «жизни» заявки, проверяются состояния триггеров, записанные в реестрах. Так определяется этап «жизни» заявки, её параметры и наличие блокировок по ней.

Эти состояния сверяются с параметрами из соответствующих QUIK-таблиц: Таблица лимитов, Таблица Заявок, Таблица Сделок. Эти сверки производятся с помощью bit.test-функции (ссылка на google-диске: простенький калькулятор bit-значений в виде excel-файла приложен).

Когда состояние заявки соответствует целевому, регистр триггера разблокируется.

 

Блок-схема «суррогата» (в коде занимает около 200 строк):

 Коллбэки своими руками. Личный опыт.
(ссылка на ЯДиск, если не читается)

Может, это избыточная доработка, но я другого выхода из ситуаций, вытекающих из нечеткостей работы QUIK’а и из произвола брокера, не нашел.

Возможны другие варианты? Пишите, обменивайтесь решениями. Полагаю, будет всем полезно.

 

На вопросы по теме отвечаю. Попытки потроллить пресекаю.

| ★2
8 комментариев

Очень давно, почти сразу перестал использовать колбеки. Подход как для чтения данных с датчиков как в системах реального времени — самое надежное решение. Опять же мы же про деньги говорим, а не про картинки с котиками.

 

Это Вы, наверно, еще не ловили искажение индексов таблицы ордеров после вызова колбека OnCleanUp, который брокер вызывает после принудительного разрыва соединения. Писал про это forum.quik.ru/forum10/topic9201/

avatar
nicknh, не ловил, честно))
Но мне не нужно проверять поле на наличие ВСЕХ граблей. Мне достаточно наступить на пару-другую, коими и оказались приведенные в тексте коллбеки.
Но я предполагал, что возможны и такие «подарки», что привели Вы.
Я уже не первый пост упоминаю о Системе Управленческого (внутреннего) Учета в моем боте. Он ведет все параметры торгов автономно, периодически сравнивая с QUIK'ом, но имея при этом приоритет.
Бот только транслирует данные УУ в терминал.

ЗЫ: в смысле «считывания показателей датчиков» мы с Вами, в принципе, соратники.
avatar
Идея такова:

Поздравляю!
Вы заново изобрели такую важную и полезную штуку как «транзакция».
avatar
Synthetic, а Вы не поняли сути. Поздравляю.
Дело не в названии.
Дело в том, что боты «крутят» циклы «по времени», а я предложил — «по событиям». Разница, конечно, не очевидна… Но до тех пор, пока событие происходит в пределах времени «прокрутки» бота. Как только событие «опоздает», возникнет некий эксцесс непонимания ботом ситуации.
avatar
боты «крутят» циклы «по времени», а я предложил — «по событиям»

Извините. Вы просто выражаетесь своеобразно. Мы то вот так привыкли…
event-driven programming — парадигма программирования, в которой выполнение программы определяется событиями.
avatar
Synthetic, спасибо за корректность обращения!))
Да, я не являюсь профессиональным программистом и потому не знаю соответствующего сленга.

avatar
Каждый выбирает свою дорогу. Я тоже отказался от событийной модели достаточно быстро, и перешел на «циклы». Но везде есть свои плюсы и минусы. Когда у вас на одном ноуте одновременно работает пол сотни задач (задача = алгоритм + инструмент), то встает вопрос оптимизации ресурсов. И цикличная модель, в этом плане, мне нравится больше. Первые версии системы сжирали более 95% ресурсов CPU, и начинали тормозить всюд систему. Дальнейшие доработки занчительно снизили нагрузку, и ноут, кторому уже больше 10-ти лет, спокойно справляется с задачей торговой станции. Но я не занимаюсь HFT, и у меня достаточно ресурсоемкие алгоритмы, в части проводимых расчетов. Так что мне такой подход подходит, но он может оказаться не применим для некоторых других видов торговли.
Данные о транзакциях и заявках храню в файлах. Это защищает от сбоев, и позволяет легко восстанавливать работу после «перезагрузки».
Пример файла (под одну «задачу»):

<?xml version=«1.0»?>
<DealParam xmlns:xsi=«www.w3.org/2001/XMLSchema-instance» xmlns:xsd=«www.w3.org/2001/XMLSchema»>
<startTime>2025-08-18T18:37:14.5925157+03:00</startTime>
<lifeTimeDeal />
<posOperation>Open</posOperation>
<operation>Buy</operation>
<status>Closed</status>
<orderNumbers>
<long>69592992656</long>
</orderNumbers>
<securityCode>GAZP</securityCode>
<mailTo>v.hohlov@hotmail.com</mailTo>
<robotMode>work</robotMode>
<code_ts>InvestPortfolio.work</code_ts>
<signal>Portfolio.Buy.Buy.137,17</signal>
<positionID>InvestmentGAZPInvest.Bokovik.Long</positionID>
<targetQty>1</targetQty>
<limitMaxOrderQty>0</limitMaxOrderQty>
<qtytrades>1</qtytrades>
<old_toolqty>1180</old_toolqty>
<toolqty>1190</toolqty>
<transactionID>0</transactionID>
<targetPrice>137.18</targetPrice>
<limitPriceDeviation>0.2</limitPriceDeviation>
<price_trades>137.17</price_trades>
<price_entrance>132.32</price_entrance>
<stoploss>0</stoploss>
<takeprofit>0</takeprofit>
<takeprofit2>0</takeprofit2>
</DealParam>

В конечном итоге, я считаю, что важно не слишком усложнять процессы. Чем проще все реализовано, тем стабильнее и быстрее работает. Возникающие в процессе эксплуатации ошибки/сбои и т.п. конечно же ведут к доработкам, которые обычно усложняют процессы. И тут важно не переборщить

avatar
Prophetic, справедливое замечание, спасибо!
avatar

Читайте на SMART-LAB:
Фото
DXY у ключевой поддержки: шорт-сквиз или новый этап распродажи?
Индекс доллара DXY плавно дрейфует в область месячного минимума в районе 98,50. Однако ослабление доллара на FX неравномерно: EURUSD стоит около...
Фото
🎭 За кулисами ноября: итоги
В прошлом месяце вложения физлиц в ценные бумаги выросли на 36% . В облигации было инвестировано 115,6 млрд , в паи фондов — 31,1 млрд....
Портрет клиента Займера
За 11 лет работы к нам обратилось более 20 млн россиян. Кто же является типичным заемщиком Займера? 🔎 Посмотрим данные за ноябрь этого года. 🔶...

теги блога Eugene Bright

....все тэги



UPDONW
Новый дизайн