В этой статье расскажу о некоторых интересных проблемах, с которыми встретился в процессе написания торгового робота облигациями.
Для контекста — схема робота была приведена в
этой статье.
Отправка тысяч заявок — это долго
В виду того, что на Мосбирже на рынке облигаций (и не только) заявки не переносятся через ночь, каждое утро надо выставлять в стакан на продажу то, что напокупал ранее.
Когда речь идёт о выставлении тысяч заявок через Quik, невольно сталкиваешься с тем, что это:
— долго;
— возможно дорого (чревато платежами за большой напор заявок).
В самом начале я отправлял заявки синхронной функцией TRANS2QUIK_SEND_SYNC_TRANSACTION. Этого было вполне достаточно на малых объёмах. Но на большем объёме стало туговато.
Синхронная отправка:

Все заявки выставляются за 6.5 минут, более половины времени аукциона открытия. А можно быстрее?
Решение простое — переключаемся на асинхронную отправку функцией TRANS2QUIK_SEND_ASYNC_TRANSACTION. Но тут есть другие проблемы:
— коллбэк асинхронной отправки не содержит пользовательский transaction_id;
— следовательно, коллбэк я не жду, и между асинхронной отправкой заявки и появлением её в таблице заявок (в любом статусе) может пройти много времени, и тогда робот может отправить эту заявку более одного раза.
Хорошо, в таком случае будем кешировать отправленные transaction_id в память на какое-то короткое время, чтобы не отправлять лишний раз.
Асинхронная отправка:
45 секунд. Всё круто, да? Нет, т.к. в логах Quik видно: «Превышено максимальное количество транзакций 50 в интервале 1 сек».
Пу-пу-пуууу, а на некоторых тарифах такое превышение конвертируется в заработок брокера.
Ясно. Введём рейтлимит отправки.
Асинхронная отправка с рейтлимитом:

2 минуты. Есть пространство для роста.
Наверное, можно предположить, что, имея прямое подключение до серверов биржи, можно было бы не выполнять все эти приседания. Но, учитывая свои объёмы и доходность, платить за такой доступ смысла не вижу.
ask, который я покупаю — мой же ордер на продажу
Допустим, алгоритм настроен так, что свободные средства тратятся на покупку инструмента с наибольшим потенциалом доходности на данный момент.
Для этого сканируются все стаканы и выбирается самый доходный ask. И бывает так, что самый доходный ask — это моя жа заявка:
Помимо тщетных попыток купить самого себя, навскидку есть следующие варианты:
— Ждать. Т.е., беря приведённый выше пример, ждать удовлетворения всех моих завок до 98.38 (если эта цена к тому моменту тоже будет лучшей среди всех стаканов) либо ждать чей-то более доходный ask (в этом или другом стакане). Для простоты опустим случай, когда на лучшей цене находится моя заявка вместе с чьей-то ещё, и я не знаю, кто в голове очереди (на одной цене заявки выстроены в очередь, в хронологическом порядке их поступления на биржу).
— Пропускать этот инструмент и переходить к другому стакану в соответствии с доходностью ask-ов. Но тут есть другая проблема — тогда я упускаю лучшую в моменте доходность.
— Перемещать выше в стакане этот свой лучший ask. Но тут есть другая проблема — перемещение в стакане не является атомарным с т.з. всей моей системы (либо я ещё не придумал, как сделать это атомарным), т.е. в процессе может, например, оборваться связь и, как следствие, в БД и в стакане будут разные состояния (и синхронизировать их — значит сильно усложнять вещи, а где тонко, там и рвётся).
Есть ещё варианты, но для простоты опущу их. Пока я выбрал первый вариант — ждать.
Робот иногда начинает сливать
Эта проблема относится не к Quik, а сугубо к кривизне рук, но всё равно поведаю о ней, т.к. забавно.
Покупай дешевле, продавай дороже — что может пойти не так?
На скриншоте видно, как робот покупает выше, продаёт ниже — это гайзенбаг, возникает раз в несколько месяцев, и его я пока ещё не исправил (а может и исправил, но не подозреваю об этом). Кстати, в поисках проблемного места мне не помогли даже железные друзья.
Уход в минус по деньгам
Источником истины по деньгам является Quik (его таблица depo_limits), и обновления по ней могут доезжать не сразу, что иногда приводит к перерасходу свободных средств и уходу в небольшой минус.
Наивное решение — получать состояние счёта в самом начале торгового дня, увеличивать/уменьшать при торговле на своей стороне и опираться на то, что получается в итоге. Но это решение не подходит, т.к. тут надо как-то учитывать поступления купонов, амортизаций, пополнения счёта и т.п., а это большая сложнота. Надо как можно проще.
На данный момент эта проблема пока не решена, а точнее — когда ушёл в минус (а это бывает редко и на чуть-чуть), подкидываю денег или продаю парочку лотов руками.
Медленная работа робота в целом
Это стало ощущаться ещё до проблем с долгой отправкой заявок на премаркете (описал выше).
Если в одном инстансе Quik открыть кучу инструментов (стаканы, таблицы), то всё в нём работает ооочень меееедленно, в т.ч. медленно работают потоки робота.
Решение простое — вынести робота на отдельный инстанс Quik, где открыть максимум окошко с запущенными скриптами.
Данная публикация является личным мнением автора. Мнение владельца сайта может не совпадать с мнением автора.
— Есть фронтраннеры, как бы смешно это не звучало для рынка облигаций.
— Это усложнение алгоритма и ведения позиции (в контексте моей системы).
Но опять же, любое решение — это компромисс. И я даже соглашусь с Вами, что робот странный в контексте и понимании другого человека.
Один из вариантов набора позиции (его и описал в данной статье) — робот всегда старается купить самый доходный на данный момент инструмент. И может такое произойти, что в стакане этого инструмента самая доходная лимитка на продажу — моя же. Хоть это и не одно и то же, но другие трейдеры писали о кросс-сделках в своих алгоритмах на срочном рынке.Есть розетки с таймером. Выключаем розетку, заведя таймер на достаточное кол-во времени для выключения ноутбука.
Да, это крайнее решение.
Понятнее не стало, но опять же — дело хозяйское.
А для ноутбука лучше купить умный нажиматель кнопок, чем умную розетку. Ну если кнопка у ноута достаточно удобно для нажимателя расположена.
Как бы Вы вели позицию при условии обязательной продажи всех лотов до даты погашения/оферты? Не воспримите как пассивную агрессию. Мне действительно интересно.Вы не поверите! О нажимателе кнопок хотел написать где-то в следующих статьях.
Между делом — нынешний нажиматель не захотел управляться через хаб удалённо. Но да, замечание ценное, спасибо!