coredumped
coredumped личный блог
Вчера в 07:57

Проблемы алготорговли облигациями в Quik

В этой статье расскажу о некоторых интересных проблемах, с которыми встретился в процессе написания торгового робота облигациями.
Для контекста — схема робота была приведена в этой статье.

Отправка тысяч заявок — это долго

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

В самом начале я отправлял заявки синхронной функцией TRANS2QUIK_SEND_SYNC_TRANSACTION. Этого было вполне достаточно на малых объёмах. Но на большем объёме стало туговато.

Синхронная отправка:
Проблемы алготорговли облигациями в Quik
Все заявки выставляются за 6.5 минут, более половины времени аукциона открытия. А можно быстрее?

Решение простое — переключаемся на асинхронную отправку функцией TRANS2QUIK_SEND_ASYNC_TRANSACTION. Но тут есть другие проблемы:
  — коллбэк асинхронной отправки не содержит пользовательский transaction_id;
  — следовательно, коллбэк я не жду, и между асинхронной отправкой заявки и появлением её в таблице заявок (в любом статусе) может пройти много времени, и тогда робот может отправить эту заявку более одного раза.
 Хорошо, в таком случае будем кешировать отправленные transaction_id в память на какое-то короткое время, чтобы не отправлять лишний раз.

Асинхронная отправка:
Проблемы алготорговли облигациями в Quik

45 секунд. Всё круто, да? Нет, т.к. в логах Quik видно: «Превышено максимальное количество транзакций 50 в интервале 1 сек».
Пу-пу-пуууу, а на некоторых тарифах такое превышение конвертируется в заработок брокера.
Ясно. Введём рейтлимит отправки.

Асинхронная отправка с рейтлимитом:
Проблемы алготорговли облигациями в Quik
2 минуты. Есть пространство для роста.

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

ask, который я покупаю — мой же ордер на продажу

Допустим, алгоритм настроен так, что свободные средства тратятся на покупку инструмента с наибольшим потенциалом доходности на данный момент.
Для этого сканируются все стаканы и выбирается самый доходный ask. И бывает так, что самый доходный ask — это моя жа заявка:
Проблемы алготорговли облигациями в Quik

Помимо тщетных попыток купить самого себя, навскидку есть следующие варианты:
— Ждать. Т.е., беря приведённый выше пример, ждать удовлетворения всех моих завок до 98.38 (если эта цена к тому моменту тоже будет лучшей среди всех стаканов) либо ждать чей-то более доходный ask (в этом или другом стакане). Для простоты опустим случай, когда на лучшей цене находится моя заявка вместе с чьей-то ещё, и я не знаю, кто в голове очереди (на одной цене заявки выстроены в очередь, в хронологическом порядке их поступления на биржу).
— Пропускать этот инструмент и переходить к другому стакану в соответствии с доходностью ask-ов. Но тут есть другая проблема — тогда я упускаю лучшую в моменте доходность.
— Перемещать выше в стакане этот свой лучший ask. Но тут есть другая проблема — перемещение в стакане не является атомарным с т.з. всей моей системы (либо я ещё не придумал, как сделать это атомарным), т.е. в процессе может, например, оборваться связь и, как следствие, в БД и в стакане будут разные состояния (и синхронизировать их — значит сильно усложнять вещи, а где тонко, там и рвётся).

Есть ещё варианты, но для простоты опущу их. Пока я выбрал первый вариант — ждать.

Робот иногда начинает сливать

Эта проблема относится не к Quik, а сугубо к кривизне рук, но всё равно поведаю о ней, т.к. забавно.
Покупай дешевле, продавай дороже — что может пойти не так?
Проблемы алготорговли облигациями в Quik

На скриншоте видно, как робот покупает выше, продаёт ниже — это гайзенбаг, возникает раз в несколько месяцев, и его я пока ещё не исправил (а может и исправил, но не подозреваю об этом). Кстати, в поисках проблемного места мне не помогли даже железные друзья.

Уход в минус по деньгам

Источником истины по деньгам является Quik (его таблица depo_limits), и обновления по ней могут доезжать не сразу, что иногда приводит к перерасходу свободных средств и уходу в небольшой минус.
Наивное решение — получать состояние счёта в самом начале торгового дня, увеличивать/уменьшать при торговле на своей стороне и опираться на то, что получается в итоге. Но это решение не подходит, т.к. тут надо как-то учитывать поступления купонов, амортизаций, пополнения счёта и т.п., а это большая сложнота. Надо как можно проще.
На данный момент эта проблема пока не решена, а точнее — когда ушёл в минус (а это бывает редко и на чуть-чуть), подкидываю денег или продаю парочку лотов руками.

Медленная работа робота в целом

Это стало ощущаться ещё до проблем с долгой отправкой заявок на премаркете (описал выше).
Если в одном инстансе Quik открыть кучу инструментов (стаканы, таблицы), то всё в нём работает ооочень меееедленно, в т.ч. медленно работают потоки робота.
Решение простое — вынести робота на отдельный инстанс Quik, где открыть максимум окошко с запущенными скриптами.
Данная публикация является личным мнением автора. Мнение владельца сайта может не совпадать с мнением автора.
11 Комментариев
  • Karabas
    Вчера в 08:10
    Робот обод и болты получилось
  • Vkt
    Вчера в 08:23
    Странный робот как по мне. Несколько тысяч заявок (зачем?) и ситуации когда робот хочет купить у самого себя. Понятно, что хозяин — барин, но я бы с логикой разбирался. И в комментах к предыдущей статье не понятно как поможет умная розетка перезагрузить ноутбук. У него ж батарейка есть, а это по сути встроенный бесперебойник.
  • Vkt
    Вчера в 10:01

    Понятнее не стало, но опять же — дело хозяйское.

    А для ноутбука лучше купить умный нажиматель кнопок, чем умную розетку. Ну если кнопка у ноута достаточно удобно для нажимателя расположена.

  • john_doe
    Вчера в 15:57
    quik крайне сомнительное решение для алготрейда. Насколько знаю, до сих пор нет штатной функции переподключения при разрыве связи, это приходится делать сторонними костылями, имитирующими клик по кнопкам и ввод пароля. И не всегда при перебоях получится переподключиться, т.к. сессия на стороне quik может подвиснуть.

    Если не секрет, почему не смотрели в сторону openapi/gRPC от брокеров?

Активные форумы
Что сейчас обсуждают

Старый дизайн
Старый
дизайн