История создания одного HFT-робота

Автор: Кондратенко Юрий

Статья про высокочастотные роботы, про сложности и технические аспекты их создания на примере конкретного робота. Обзор технологий для HFT-трейдинга и их стоимость.

 

 

История эта началась осенью 2010 года. Разработкой торговых стратегий я занимаюсь давно, но в основном на таймфреймах выше 15 минут. Про высокочастотный трейдинг (high frequency trading, HFT) много слышал, но сам не пробовал. И вот, изучая результаты участников конкурса ЛЧИ 2010, в голове появилась крамольная мысль – они смогли и у меня получится. Вообще про конкурс биржи РТС надо сказать отдельно. Это превосходный рекламный трюк! Согласно закону больших чисел из 1 322 участников даже по чистой случайности должны найтись несколько роботов, которые покажут ошеломляющую доходность (привет Н. Талебу), не говоря уже про действительно хорошие наработки. И время то какое выбрано – осень, пора высокой волатильности. Тот факт, что 63% участников по итогам оказались ниже стартовой отметки, остается за кадром.

Технологии

Итак, не испытывая особых иллюзий, а любопытства ради, взялся за дело. Для начала надо было определиться с платформой для написания робота. Программы технического анализа, наподобие Omega Research, для этих целей не годились в силу больших задержек получения данных и исполнения приказов. В то же время, покупать доступ к шлюзу и выделенный сервер, на первом этапе не хотелось. Поэтому в качестве торговой платформы были выбраны следующие программы: торговый терминал QUIK плюс собственная программа на C#. QUIK зарекомендовал себя стабильной работой и наличием открытого API (application program interface) для подачи заявок. На языке C# остановился в силу предубежденья, что программы на С-языках родные Windows и работают быстрее. Хотя первоочередное значение, конечно же, имеет качество алгоритма, я не язык реализации. Данные из программы QUIK было решено выводить по ODBC в базу данных MySQL – бесплатную СУБД со всем необходимым функционалом. И сразу ответ тем, кто успел подумать, что DDE в сто раз круче – в данной конфигурации робота, преимущество которые дает прямой вывод данных в память – несущественно. Итак, схема будущего робота изображена на рисунке 1.

Рисунок 1. Схема взаимодействия робота с программами

Торговый терминал QUIK получает от биржи поток с котировками. В частности нас будет интересовать последняя сделка. Далее он транслирует эти данные с минимальной задержкой в базу данных MySQL. Робот с интервалом 100 миллисекунд (10 раз в секунду) забирает из базы данных новые тики и анализирует их. В случае необходимости подает приказы на покупку либо продажу в QUIK и отслеживает факт исполнения заявок. Все просто и надежно.

Алгоритм робота

Алгоритм робота – это самая главная часть. Хотя для HFT-робота не меньшую роль играет и способ исполнение заявок. Известно, что на рынках присутствует следующая закономерность – чем выше таймфрем, тем выше персистентность («трендовость») последовательности цен, то есть за ростом цены, скорее всего, будет следовать рост, за падением – падение цены. Верно и обратно, на более мелких разрешениях графиков будет преобладать антиперсистентность изменения цен – подъем и спад будут чередоваться. В частности, большую часть времени инструмент будет находиться в интервале между лучшей ценой покупки (бидом) и лучшей ценой продажи (аском). Поэтому логично предположить, что высокочастотные роботы по своей сути должны быть контртрендовые – покупать при падении и продавать на росте. Самый примитивный HFT-робот, который «пылесосит» спред, – это алгоритм одновременного выставления двух заявок покупки и продаж фьючерс на индекс РТС с разницей в 10 пунктов внутри спреда. Такой алгоритм имеет крайне низкую эффективность, так как во-первых, 10 пунктов – это примерная стоимость комиссионных для такой сделки, во-вторых, любое движение против уже открытой позиции приносит счету убыток в несколько раз больше 10 пунктов.

Инструментом для торговли был выбран фьючерс на индекс РТС – самый популярный и, пожалуй, единственный кандидат на нашем рынке для этой цели. В качестве исходной информации для анализа взяли поток тиков (сделок). В спокойный день количество тиков по фьючерсу на РТС составляет более полумиллиона.

В качестве тестового алгоритма решено было взять следующую стратегию. Ждем формирования локального максимума\минимума цены. Если цена падает от максимума на Y пунктов – покупаем, выросла от текущего минимума на Х пунктов – закрываем позицию, X <= Y – параметры системы. Стоплосс в размере 150 пунктов.

Предварительное тестирование системы на тиковых данных нарисовало в воображении лазурный берег, яхту и много чего. Финансовый результат «Грааля» по итогу дня колебался от 15 000 до 20 000 пунктов фьючерса РТС при комиссии биржи 2 руб./контракт и комиссии брокера 0.5 руб./контракт. Количество сделок около 3 000 штук в день, что соответствует в среднем одной сделке раз в 15 секунд. Но поскольку весь мой прошлый опыт на рынке говорил о том, что легких денег на бирже не бывает, осталось всего ничего - запрограммировать бота и убедиться в этом.

Архитектура робота

После первых тестов в режиме реальных торгов стало ясно, что архитектура роботов для крупных таймфреймов абсолютно не пригодна для высокочастотных роботов. Общий принцип роботов на «макроуровне» - есть теоретическая стратегия, которая генерирует сигналы, и есть блок программы, который эти сигналы исполняет. На «микроуровне» события развиваются столь стремительно, что программа еще не знает о том, зарегистрирована поданная заявка на вход или нет, а система выдает уже сигнал на выход. Поэтому стандартная «синхронная последовательность»: получил сигнал – отправил заявку на биржу – получил подтверждение выставления/исполнения, - здесь не работает.

Разработчик стоит перед выбором: (а) использовать «синхронный подход», ждать исполнения ордера и пропускать часть сигналов; (б) действовать «асинхронно», накидывая заявки в рынок, не дожидаясь отчета биржи об их исполнении. Второй способ представляется оптимальным в расчете на то, что большая часть ордеров будет исполнена. При использовании «асинхронного» подхода возникает другая проблема – соответствие реального остатка на счете с теоретическим остатком торговой системы. Значит, надо выбирать моменты для сверки и корректировки остатка на счете, что также представляется не тривиальным вопросом, когда это делать – перед входом, после входа либо во время сделки. Общий подход для решения подобных задач должен быть следующий.

Повышение сложности алгоритма не должно увеличивать общие риски робота.

В контексте данной задачи, пробовать сверять остатки во время сделки, когда активна заявка на выход, более рискованно, чем два других варианта, так как можем получить не актуальные данные по остаткам. Опытным путем был выбран следующий критерий сверки остатков – после выхода из позиции с задержкой в 2-3 секунды, чтобы дать QUIK обновить остатки по счету. При проектировании высокочастотных роботов следует помнить, что мы работаем с информацией, которая очень быстро меняется и, зачастую, при принятии решения может быть уже устаревшей. Для повышения качества алгоритма можно отслеживать логические цепочки событий. Поясню, на примере. Мы выставили заявку на продажу фьючерса РТС по цене 150 000 пунктов, и в системе она горит как активная. При этом мы получаем тик с ценой сделки 150 005 пунктов. В этой ситуации можно уже считать заявку исполненной и, исходя из этого, принимать следующие решения.

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

Оптимизация торгового алгоритма

После того, как основные элементы робота были сделаны, пришло время для оптимизации торгового алгоритма. Для оптимизации торговых сигналов я использую факторный анализ. Суть метода в следующем. Допустим, у нас есть фактор или критерий, который наблюдается перед открытием позиции. Проводя бэктестинг системы, мы можем вычислить среднюю сделку (математическое ожидание сделки, не путать со средней прибыльной сделкой) для всех сделок EX и среднюю сделку в тех случаях, когда наблюдался выбранный фактор EX* (условное математическое ожидание). Если значение EX* «значительно» меньше EX, то данный фактор можно использовать в качестве фильтра для отсеивания таких сделок.

Для проверки были взяты следующие критерии:

  • время;
  • скорость тиков;
  • волатильность (разброс тиков за последнюю минуту).

Изучение последних двух факторов не принесло особых результатов. Средняя скорость тиков составляет 30 тиков в секунду. Была гипотеза, что высокой скорости тиков соответствует направленное движение рынка и, соответственно, в такие моменты система будет давать преимущественно убыточные сигналы, но она не подтвердилась. Также ничего интересного не принесло рассмотрение волатильности. А вот время оказалось очень полезным фактором. Выяснилось, что торговля до 12:00 и в период выхода статистических данных (17:30 сейчас) несет в себе в основном убытки.

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

Скорости

Как не крути, а борьба высокочастотных роботов – это борьба скоростей. Недаром капиталисты прокладывают новый канал между Нью-Йорком и Лондоном ради выигрыша всего лишь в 6 миллисекунд и пробурили горы между Нью-Йорком и Чикаго для прямой прокладки кабеля ради 3 миллисекунд. 

Стандартный пинг до сервера брокера из родного Красноярска идет 50-60 миллисекунд. Разместив софт в датацентре в городе герое Москва поближе к бирже РТС, можно сократить пинг до 3-10 миллисекунд. В конечном итоге можно разместить свое железо вообще на самой бирже РТС непосредственно возле ядра торговой системы. В то же время, нужно отчетливо понимать, для чего нужна эта скорость, чтобы не оказаться на дорогущем Феррари в многочасовой пробке.

Для конфигурации выше описанного робота выигрыш в пинге даже в 50 секунд не несет автоматического увеличения эффективности и вот почему. На спокойном рынке через QUIK можно 4 раза в секунду переставить заявку (4 транзакции) с подтверждением, что соответствует отклику в 250 миллисекунд. Когда же на рынке начинаются движения, то отклик от сервера может приходить и через 500 и через 1500 миллисекунд. То есть слабое звено здесь уже не столько канал связи, сколько сервер QUIK. Данная проблема решается просто и дорого – подключением к шлюзу биржи по протоколам FIX или PLAZA II. В рамках данного эксперимента я оказался не готов продолжать исследования на уровне соединения со шлюзом.

Робот в сухом остатке

В воздухе повис вопрос – а где же яхта? Почему столь шикарные результаты в теории не материализовались в мешки с деньгами на практике? Более детальное изучение статистики теоретических сделок показало, что 75% прибыльных сделок происходит в течение 1 секунды. Их можно достать одновременным выставлением сразу двух заявок на покупку и на продажу. Проблема с очередностью исполнения заявок не очень сложна и решается. Но и в этом случае нет ожидаемой прибыли. Здесь пришло время произнести любимое слово моей дочки «почему»? Еще более детальное изучение результатов бэктестинга открыло удивительную вещь: 50% прибыльных сделок – это вторые и третьи сделки, которые проходят в рамках 1 секунды. Получается, в 1 секунду проходят сразу три прибыльные сделки, две из которых для нас практически не достижимы. Вот такая суровая действительность высокочастотного трейдинга!

Заключение

HFT-трейдинг – это интересная и, по всей видимости, прибыльная тема. Другой вопрос состоит в том, как качественно реализовать такого робота и сколько ресурсов в это надо вложить. Если Вы решите заняться этой темой, то для начала посчитайте затраты даже не на создание и развитие, а на поддержание данного проекта – виртуальный или выделенный сервер, доступ к шлюзу, брокерские услуги. В зависимости от набора ценник будет начинаться от 15 000 -20 000 руб. (виртуальный сервер 5 000 руб., доступ к шлюзу PLAZA II – 5 000 руб., фиксированная оплата брокерских услуг 5 000 – 10 000 руб) и уходить в космос. Теперь оцените, какой должен быть доход, чтобы окупать все издержки, технические сбои и еще приносить прибыль!