Этот пост основан на моем опыте участия в очень интересном конкурсе прогнозирования, организованном XTX. Перед участниками стояла задача спрогнозировать будущую доходность (предположительно) актива Forex на основе данных книги лимитных заказов (LOB). В рамках конкурса подробностей о датах активов или лимитных заявок не разглашалось.

В рамках конкурса XTX предоставила данные о разработке собственной модели. Данные включали 3 миллиона тиковых записей, каждая из которых содержала несколько уровней цен покупки и продажи. Соревнование было разработано таким образом, чтобы вся предыдущая история накопленных тиковых данных была доступна в каждый момент времени, но никакие исторические доходы не могут использоваться для будущего прогноза. Это устранило классические модели временных рядов и потребовало от участников в полной мере использовать модели прогнозирования книги лимитных ордеров.

В этом посте я сосредоточусь на применении фильтра Калмана для получения неявного состояния LOB. Подробное описание теории фильтров Калмана можно найти в широком диапазоне академических ресурсов (пример).

Каркас модели

Я придерживался относительно стандартного подхода к построению регрессионной модели:

  • Модель регрессии XGBoost как ядро
  • Поиск параметров в сетке на основе перекрестной проверки методом прямого перехода
  • Генерация дополнительных динамических факторов на основе исторических тиковых данных

Я опущу подробности XGBoost и перекрестной проверки, все подробности можно найти на моем github. Вместо этого я сосредоточусь на технике разработки функций, основанной на фильтре Калмана.

Использование фильтра Калмана для вывода неявных потоков LOB

LOB-данные представлены в виде массивов размеров и цен предложения / продажи, разделенных на 15 сегментов: bidSize [0..14], askSize [0..14], bidPrice [0..14], askPrice. [0..14]. На приведенном ниже графике показаны кумулятивные объемы спроса и предложения в LOB за короткий период времени:

Чтобы отслеживать динамику LOB во времени, вводятся подразумеваемые скрытые денежные потоки между бакетами LOB. Для упрощения все сегменты [1..14] объединены в одну. Следовательно, наблюдения описываются как вектор [bidSize1_14, bidSize0, askSize0, askSize1_14]

Скрытые состояния системы определяются на основе следующих одиннадцати параметров:

  • Четыре параметра, определяющие текущий объем в каждом из сегментов bidSize1_14, bidSize0, askSize0, askSize1_14; Несмотря на то, что эти параметры непосредственно наблюдаются в данных, фильтр Калмана считает, что на них влияют ошибки измерения и процесса;
  • Четыре параметра, определяющие внешний денежный поток в / из соответствующих сегментов;
  • Три параметра, определяющие следующие денежные потоки между бакетами:
  1. ask1_14 ask_0
  2. bid1_14 bid_0
  3. ask_0 bid_0

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

На основании состояний, приведенных выше, матрица переходов состояний Калмана размером 11 на 11 определяется следующим образом:

В матрице перехода между состояниями строки и столбцы упорядочены в соответствии со списком скрытых состояний выше. Начиная со строки 5 и далее это единичная матрица, показывающая, что никаких изменений в потоках не ожидается. Строки с 1 по 4 представляют собой изменение текущего объема спроса / предложения. Например, изменение BidSize для сегментов 1–14 с течением времени t выглядит следующим образом:

с ω, представляющим процесс белого шума.

Алгоритм фильтра Калмана реализован в приведенном ниже коде:

Код возвращает значения неявных потоков, которые в дальнейшем используются в качестве факторов прогнозирования в основной регрессионной модели. В качестве примера первые 20000 наблюдений за потоком (ask_0 ⇆ bid_0) представлены на временном ряду ниже:

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

Выдержка статистики важности переменных представлена ​​на диаграмме ниже, где первая функция представляет собой поток ask_0 ⇆ bid_0:

Вывод

Мы рассмотрели пример фактора, который генерируется на основе неявного динамического денежного потока LOB актива. Несмотря на то, что поток является неявным и ненаблюдаемым в данных, использование алгоритма фильтра Калмана позволило сгенерировать фактор со значительной предсказательной силой при использовании в качестве входных данных в базовый алгоритм XGBoost.

Отказ от ответственности: метод, описанный в этом посте, использовался как часть более широкого диапазона факторов прогнозирования. В совокупности представленная модель заняла 13-е место в итоговом рейтинге конкурса.