Model-based gym environments for limit order book trading

8/10

Джозеф Джером, Леандро Санчес-Бетанкурт, Рахул Савани, Мартин Хердеген · University of Liverpool / King’s College London / University of Warwick · 16 сентября 2022 · ICAIF 2022

Оригинал: Jerome, J., Sánchez-Betancourt, L., Savani, R., Herdegen, M. «Model-based gym environments for limit order book trading», 2022 — arxiv.org/abs/2209.07823 (PDF, 7 страниц); код: github.com/JJJerome/mbt_gym · обновлён 2024-01-08 · 440 коммитов.

Первые три автора внесли равный вклад. Рисунки воспроизведены из оригинальной публикации. Перевод выполнен для личной коллекции с указанием источника.

Ключевые слова: книга лимитных заявок (LOB); маркетмейкинг; оптимальное исполнение; предоставление ликвидности; инвентарный риск; обучение с подкреплением.

Аннотация

В литературе по математическим финансам накоплен богатый каталог моделей для задач алгоритмической торговли — маркетмейкинга и оптимального исполнения — в книгах лимитных заявок (limit order book, LOB). Статья представляет mbt_gym — Python-модуль с набором gym-сред для обучения агентов обучения с подкреплением (reinforcement learning, RL) таким model-based торговым задачам. Модуль устроен расширяемо: компоненты разных моделей можно комбинировать. Поддерживаются высокоэффективные векторизованные среды, ускоряющие обучение RL-агентов. В работе мотивируется вызов применения RL к model-based LOB-задачам матфинансов, объясняется устройство gym-среды и демонстрируется её использование на стандартных и нестандартных постановках из литературы. В конце намечена дорожная карта развития модуля; код открыт на GitHub как точка сборки RL-исследований в model-based алгоритмической торговле.

1. Введение

Существенная доля финансовых рынков сводит покупателей и продавцов через механизм книги лимитных заявок [32]. Поэтому LOB — центральный объект математических финансов. Разработан широкий спектр моделей динамики цены и приходов заявок; на них анализируют маркетмейкинг и оптимальное исполнение. Модели различаются прежде всего стохастическими процессами цены и потока заявок, действиями, доступными агенту, и функцией вознаграждения.

Обычно такие задачи решают (часто приближённо) методами теории уравнений в частных производных (PDE): формулируют уравнение Гамильтона–Якоби–Беллмана (HJB) и численно решают его схемами Эйлера или конечными разностями. Однако:

  1. Численный HJB требует схем, заточенных под конкретные стохастические процессы модели. Желательны более модельно-агностичные подходы.
  2. HJB особенно сильно страдает от проклятия размерности — это само по себе сужает класс моделей, которые вообще рассматривают и решают этим методом.
  3. При работе с HJB часто ищут полуявные решения и поэтому ограничиваются «хорошими» функциями, что сужает спектр изучаемых торговых задач.

Обучение с подкреплением решает задачи управления методом проб и ошибок. После революции глубокого обучения RL дал ряд ярких успехов. Мы утверждаем, что применение RL к model-based LOB-задачам важно и перспективно:

В отношении указанных слабостей HJB отметим: model-free RL в принципе позволяет решать модели с предположениями, плохо совместимыми с HJB, применять один метод обучения ко многим моделям и работать в более высоких размерностях — а значит, с более богатыми постановками. Авторы представляют открытый бенчмарк-модуль с рядом LOB-моделей и торговых задач из литературы матфинансов вместе с RL-решениями. Цель — показать потенциал RL и упростить дальнейшие исследования в этом направлении.

При всей перспективности у RL есть общепризнанная слабость — низкая sample efficiency. К счастью, изучаемые model-based торговые задачи допускают крайне эффективную векторизацию сред; авторы этим пользуются и показывают, что такая параллелизация критична для почти оптимальных решений на бенчмарках.

Основные вклады.

Модуль: https://github.com/JJJerome/mbt_gym · обновлён 2024-01-08 · 440 коммитов · обновлён 2024-01-08 · 440 коммитов.

1.1. Обзор литературы

1.1.1. Математические финансы

Задача маркетмейкинга с лимитными заявками введена в [36] и математически формализована спустя три десятилетия в [5]. С тех пор литература огромна. Работа [34] даёт явное решение с инвентарными ограничениями. Более реалистичные модели — [35; 17]. Расширения с сигналами — [12; 21] (непрерывные и бинарные действия). Сообщество продолжает работать по опционам [7], FX [9] и автоматизированному маркетмейкингу [13].

Литература по оптимальному исполнению не менее обширна: начиная с [11; 3], задача привлекает всё больше внимания. Фокус дизайна моделей — как рынок перерабатывает поток заявок ликвидатора (и других участников) и как строить и эксплуатировать сигналы [15, 14; 30; 25; 46; 24; 38; 19]. Далее — стохастическая волатильность и ликвидность [2], стохастический price impact [8; 26], латентность и трения [45; 20].

Отличный учебный обзор и оптимального исполнения, и маркетмейкинга — [16; 33].

1.1.2. RL для высокочастотной торговли

Краткий обзор RL для HFT с акцентом на динамику среды обучения — главный фокус статьи. Основное внимание — маркетмейкингу (большинство сред mbt_gym сейчас именно про MM); кратко затронуто и RL для оптимального исполнения.

Три главных подхода к моделированию рынка в RL-среде. Первый — market replay: исторические данные воспроизводятся в симуляторе, обучаемый агент с ними взаимодействует. Второй — model-based; к этой категории относится данная статья. Третий — агентные симуляторы: hand-crafted агенты, моделирующие реальных участников, взаимодействуют друг с другом и с обучаемым агентом через биржевой механизм. Хорошее сравнение достоинств подходов — [6].

Market replay для HFT: [47] и [37] — Nasdaq; [51] — LSE; [55] — фьючерсы CME; [54] — XSHE; [48], [49] и [29] — криптовалюты.

Model-based маркетмейкинг: [22] — пуассоновская модель в духе [31]; [40] — скрытая марковская модель, подобранная по сделкам Nasdaq; [43] — постановка в пуассоновской модели [23]; [52] — робастная adversarial-версия задачи из [16, §10.2].

Агентные HFT-симуляторы для обучения RL: [27], [41], [39] и [4].

2. Дизайн модуля

Принципы: расширяемость, общность, минимум дублирования кода. Все gym-среды наследуют класс TradingEnvironment и разделяют общие функции step и обновления состояния.

Функция step, приведённая ниже, не специфична для конкретной торговой задачи.1

def step(self, action: np.ndarray):
    current_state = self.state.copy()
    next_state = self._update_state(action)
    done = self.state[0, 2] >= self.terminal_time - self.step_size / 2
    dones = np.full((self.num_trajectories,), done, dtype=bool)
    rewards = self.reward_function.calculate(current_state, action,
                                                        next_state, done)
    infos = self.empty_infos
    return self.state.copy(), rewards, dones, infos

Функция _update_state, показанная далее, уже специфична для торговли.

def _update_state(self, action: np.ndarray) -> np.ndarray:
    arrivals = self.arrival_model.get_arrivals()
    if self.action_type in ["limit", "limit_and_market"]:
        depths = self.limit_depths(action)
        fills = self.fill_probability_model.get_fills(depths)
    else:
        fills = self.post_at_touch(action)
    self._update_agent_state(arrivals, fills, action)
    self._update_market_state(arrivals, fills, action)
    return self.state

Один и тот же _update_state покрывает многие стандартные LOB-модели литературы, потому что у них общий порядок зависимостей стохастических процессов. Это позволяет фиксировать последовательность шага: сначала обновляется процесс приходов, он влияет на mid-цену, затем — модель fill probability. Симуляцией этих процессов занимается _update_market_state:

def _update_market_state(self, arrivals, fills, action):
    self.arrival_model.update(arrivals, fills, action)
    self.midprice_model.update(arrivals, fills, action)
    self.fill_probability_model.update(arrivals, fills, action)
    self.state[:, self.midprice_index_range[0]:
                  self.midprice_index_range[1]] =
                        self.midprice_model.current_state
    self.state[:, self.arrival_index_range[0]:
                  self.arrival_index_range[1]] =
                        self.arrival_model.current_state
    self.state[:, self.fill_index_range[0]:
                  self.fill_index_range[1]] =
                        self.fill_probability_model.current_state

Наконец, _update_agent_state обновляет кэш и инвентарь агентов по исполнениям и движениям цены и зависит от пространства действий задачи.

def _update_agent_state(self, arrivals: np.ndarray, fills: np.ndarray,
                                                        action: np.ndarray):
    if self.action_type == "limit_and_market":
        mo_buy = np.single(self.market_order_buy(action) > 0.5)
        mo_sell = np.single(self.market_order_sell(action) > 0.5)
        best_bid = self.midprice - self.half_spread
        best_ask = self.midprice + self.half_spread
        self.state[:, CASH_INDEX] += mo_sell * best_bid - mo_buy * best_ask
        self.state[:, INVENTORY_INDEX] += mo_buy - mo_sell
    self.state[:, INVENTORY_INDEX] +=
                        np.sum(arrivals * fills * -self.multiplier, axis=1)
    if self.action_type == "touch":
        self.state[:, CASH_INDEX] += np.sum(
            self.multiplier * arrivals * fills *\
            (self.midprice + self.half_spread * self.multiplier), axis=1)
    else:
        self.state[:, CASH_INDEX] += np.sum(
            self.multiplier * arrivals * fills *\
            (self.midprice + self.limit_depths(action) * self.multiplier),
                                                                    axis=1)
    self._clip_inventory_and_cash()
    self.state[:, TIME_INDEX] += self.step_size

2.1. Процессы приходов

Пуассоновский процесс

Класс PoissonArrivalModel — наиболее частая модель приходов в литературе по маркетмейкингу. Приходы рыночных заявок на покупку/продажу моделируются пуассоновскими процессами $(M^{\pm}_{t})_{t\ge 0}$ с интенсивностями $\lambda^{\pm}\in\mathbb{R}^{+}$.

Процесс Хокса

Самовозбуждающийся механизм Хокса реализован в HawkesArrivalModel (см. также Appendix A.3 в [16]). Для простоты авторы сосредоточены на экспоненциальных ядрах. Пусть $(\lambda^{\pm}_{t})_{t\ge 0}$ — стохастические интенсивности потока buy/sell, $(M^{\pm}_{t})_{t\ge 0}$ — соответствующие считающие процессы. Реализованы чуть более общие стохастические интенсивности

\[ \mathrm{d}\lambda^{\pm}_{t}=\kappa\,\bigl(\bar{\lambda}-\lambda^{\pm}_{t}\bigr)\,\mathrm{d}t+\gamma\,\mathrm{d}M^{\pm}_{t}, \tag{1} \]

где $\kappa>0$ — скорость возврата к среднему,2 $\bar{\lambda}>0$ — базовая интенсивность, $\gamma$ — размер скачка.

2.2. Процессы mid-цены

Ниже $(W_{t})_{t\ge 0}$ — стандартное броуновское движение. Реализованные mid-price модели делятся на две группы: (i) броуновские mid-цены и (ii) динамика со mean-reverting дрифтом.

Броуновское движение

Класс BrownianMotionMidpriceModel описывает хорошо известное арифметическое броуновское движение; mid-цена записывается как

\[ S_{t}=S_{0}+\mu\,t+\sigma\,W_{t}, \tag{2} \]

где $\mu\in\mathbb{R}$ — дрифт, $\sigma\in\mathbb{R}^{+}$ — волатильность. В той же категории — GeometricBrownianMotionMidpriceModel, сильное решение СДУ

\[ \mathrm{d}S_{t}=\mu\,S_{t}\,\mathrm{d}t+\sigma\,S_{t}\,\mathrm{d}W_{t}. \tag{3} \]

Наконец, BrownianMotionJumpMidpriceModel (как в [34, §5.2]) включает импакт исполненных заявок:

\[ S_{t}=S_{0}+\sigma\,W_{t}-\xi^{-}\,M^{-}_{t}+\xi^{+}\,M^{+}_{t}, \tag{4} \]

где $M^{\pm}_{t}$ — рыночные заявки liquidity takers, $\xi^{\pm}\in\mathbb{R}^{+}$ — параметры постоянного price impact.

Mean-reverting дрифт

Класс OuMidpriceModel покрывает Ornstein–Uhlenbeck (OU) динамику mid-цены; примеры в литературе по алготрейдингу — [10; 18].

На его базе определяется OuDriftMidpriceModel: популярные модели, в которых mid-цена несёт краткосрочный альфа-сигнал в виде OU-процесса [42; 44; 15].

Точнее, mid-цена следует

\[ \mathrm{d}S_{t}=\alpha_{t}\,\mathrm{d}t+\sigma^{S}\,\mathrm{d}W^{S}_{t}, \tag{5} \]

где $\sigma^{S}>0$ — волатильность mid-цены, $W^{S}$ — броуновское движение, а $(\alpha_{t})_{t\ge 0}$ — OU-процесс

\[ \mathrm{d}\alpha_{t}=\kappa^{\alpha}(\bar{\alpha}-\alpha_{t})\,\mathrm{d}t+\sigma^{\alpha}\,\mathrm{d}W^{\alpha}_{t}. \tag{6} \]

Здесь $\sigma^{\alpha}>0$ — волатильность OU, $\kappa^{\alpha}\ge 0$ — скорость mean-reversion, $\bar{\alpha}$ — уровень возврата, $W^{\alpha}$ — независимое броуновское движение.

Аналогично, OuJumpMidpriceModel охватывает динамику вида

\[ \mathrm{d}\alpha_{t}=\kappa^{\alpha}(\bar{\alpha}-\alpha_{t})\,\mathrm{d}t+\sigma^{\alpha}\,\mathrm{d}W^{\alpha}_{t}-\xi^{-}\,M^{-}_{t}+\xi^{+}\,M^{+}_{t} \tag{7} \]

и служит основой класса OuJumpDriftMidpriceModel — mid-цены (5), фигурирующей в [17].

2.3. Модели вероятности исполнения (fill probability)

Большинство моделей литературы используют ExponentialFillFunction. Вероятность исполнения заявки, выставленной на глубине $\delta^{\pm}$, равна $\mathbb{P}[\textrm{fill}\mid\delta^{\pm}]=e^{-\kappa\,\delta^{\pm}}$ при экспоненте заполнения $\kappa>0$; если $\delta^{\pm}\in\mathbb{R}^{+}$, значение лежит в $[0,1]$.

Поскольку fill-модель — экземпляр класса StochasticProcess, допустима экспоненциальная модель со стохастическим $\kappa$, на который влияют приходы, действия и исполнения. Другие функциональные формы — прямые обобщения. В частности, реализован TriangularFillFunction: на вход подаётся параметр $\delta_{\texttt{max}}>0$ (max_fill_depth в коде); вероятность равна $1$, если $\delta^{\pm}<0$, нулю, если $\delta^{\pm}>\delta_{\texttt{max}}$, и $1-\delta^{\pm}/\delta_{\texttt{max}}$ иначе. Естественная форма, но авторы не встречали её в литературе.

Класс PowerFillFunction (как в [17]) принимает fill_exponent $\alpha>0$ и fill_multiplier $\kappa>0$; для $\delta^{\pm}\ge 0$ вероятность исполнения

\[ \frac{1}{1+\bigl(\kappa\,\delta^{\pm}\bigr)^{\alpha}}. \tag{8} \]

У всех fill-моделей есть свойство max_depth, ограничивающее пространство действий: это глубина $\delta^{\pm}$, на которой вероятность не исполниться превышает 99% (вероятность исполнения меньше 1%).3

2.4. Пространства действий

Реализованы три способа взаимодействия агента со стаканом.

Во-первых, тип limit: участник выставляет заявки на расстоянии $\delta^{+}$ от mid на ask и $\delta^{-}$ от mid на bid. Большая часть литературы по маркетмейкингу и значительная часть по оптимальному исполнению попадает сюда.

Во-вторых, тип limit_and_market содержит предыдущий случай и позволяет агенту также посылать рыночные заявки на одну единицу актива. Рыночные заявки могут быть на покупку, на продажу или на обе стороны; предполагается исполнение на расстоянии minimum_tick_size от mid на соответствующей стороне книги.

Наконец, тип touch кодирует модели, в которых маркетмейкер решает, выставляться ли на лучших котировках. Пространство действий бинарно; нужен minimum_tick_size — расстояние лучших котировок от mid. При приходе liquidity-taking заявки на покупку/продажу лимитка агента исполняется, если он стоял на лучшем ask/bid.

2.5. Функции вознаграждения

Пусть $T>0$ и $\mathfrak{T}=[0,T]$; $(X_{t})_{t\in\mathfrak{T}}$ — кэш трейдера, $(Q_{t})_{t\in\mathfrak{T}}$ — инвентарь, $(S_{t})_{t\in\mathfrak{T}}$ — mid-цена. Функция PnL («profit and loss», риск-нейтральное вознаграждение) фиксирует изменения mark-to-market ценности позиции $Y_{t}:=X_{t}+Q_{t}S_{t}$. Конкретно, PnL равен $Y_{T}-Y_{0}$.

Вознаграждение RunningInventoryPenalty принимает два параметра: per_step_inventory_aversion $\phi\ge 0$ и terminal_inventory_aversion $a\ge 0$. Это дискретизация по времени функционала

\[ Y_{T}-Y_{0}-a\,Q_{T}^{2}-\phi\int_{0}^{T}Q_{t}^{2}\,\mathrm{d}t. \tag{9} \]

Наконец, ExponentialUtility принимает risk_aversion $\gamma>0$ и вычисляет $\exp\bigl(-\gamma(Y_{T}-Y_{0})\bigr)$.

2.6. Примеры поддерживаемых моделей

Чтобы показать диапазон моделей, реализованных как расширения базового торгового класса, авторы приводят примеры: сначала, в табл. 1, стандартные постановки из литературы, затем, в табл. 2, гибриды, сразу доступные за счёт комбинации компонентов разных стандартных моделей.

Таблица 1. Примеры стандартных моделей из литературы, реализованных в mbt_gym.
НазваниеПриходыMid-ценаДействияВознаграждение
Avellaneda and Stoikov [5]PoissonArrivalModelBrownianMotionMidpriceModellimitExponentialUtility
MM с лимитками [16, §10.2]PoissonArrivalModelBrownianMotionMidpriceModellimitRunningInventoryPenalty
MM at the touch [16, §10.2.2]PoissonArrivalModelBrownianMotionMidpriceModeltouchRunningInventoryPenalty
Cartea, Jaimungal, and Ricci (CJR) [17]HawkesArrivalProcessOuJumpDriftMidpriceModellimitRunningInventoryPenalty
Guéant, Lehalle, and Fernandez-Tapia [34], §5.2PoissonArrivalModelBrownianMotionJumpMidpriceModellimitExponentialUtility
Опт. исполнение limit+market [16, §8.4]PoissonArrivalModelBrownianMotionMidpriceModellimit_and_marketRunningInventoryPenalty
Таблица 2. Примеры поддерживаемых гибридных моделей.
НазваниеПриходыMid-ценаДействияВознаграждение
Avellaneda–Stoikov с потоками ХоксаHawkesArrivalProcessBrownianMotionMidpriceModellimitExponentialUtility
CJR-14 с pure-jump ценойHawkesArrivalProcessOuJumpDriftMidpriceModeltouchRunningInventoryPenalty
CJR-14 с экспоненциальной полезностьюHawkesArrivalProcessOuJumpDriftMidpriceModellimitExponentialUtility

2.7. Векторизованные среды

Ключевая особенность gym-сред mbt_gym — высокая параллелизация. Одна траектория состояний и вознаграждений для данной политики имеет очень большую дисперсию: стохастичность приходит сразу из нескольких источников — (1) mid-цена; (2) процесс приходов; (3) случайность исполнения лимиток агента.

Стандартный способ параллелизовать RL-rollouts — поднять много сред на потоках или CPU и собирать траектории в центре обучения. На одной машине multiprocessing делается пакетом concurrent.futures.

Так deep RL масштабируется по железу. Но структура model-based маркетмейкинга допускает гораздо более эффективный режим: одновременная симуляция многих траекторий через векторные операции линейной алгебры. В частности, mbt_gym использует массивы NumPy [53] как представление состояний, действий и вознаграждений. Ускорение относительно multiprocessing показано на рис. 1. При 1000 траекториях multiprocessing занимает 5 мин 30 с, а подход на NumPy — 0,2 с.4 На практике при policy gradient авторы использовали 10 000 (и даже 1 000 000) rollouts — с multiprocessing это было бы запретительно медленно.

Рис. 1. Сравнение времени rollout: NumPy против concurrent.futures
Рис. 1. Ускорение векторизации через NumPy.

3. Базовые агенты

Реализован ряд baseline-агентов:

Они полезны для изучения моделей и сред. Два оптимальных агента — эталон для RL; в разделе 4 обучают агента в постановке CarteaJaimungalAgent и сравнивают с оптимумом.

4. Простой пример обучения

Как демонстрация обучения в mbt_gym авторы применили PPO5 [50] к задаче маркетмейкинга из [16, §10.2]. Это удобный тест-бед: существует явное оптимальное решение. Рис. 2 показывает эволюцию средних вознаграждений за эпизод во времени при разной степени векторизации; рис. 3 сравнивает выученную политику с оптимальной из [16, §10.2].

На рис. 2 видно: если параллелизация слишком мала ($n=10$ траекторий), обучение нестабильно. Если слишком велика ($n=10\,000$), wall-clock время до сходимости растёт. Между $n=100$ и $n=1000$ разница невелика, но $n=1000$ чуть лучше: ниже дисперсия и выше сходимость средних rewards.

Рис. 2. Среднее вознаграждение во времени при разной степени векторизации
Рис. 2. Эффект разной степени векторизации.

На рис. 3 агент осваивает политику достаточно хорошо: при отрицательном инвентаре уменьшает bid-depth и увеличивает ask-depth (и наоборот), индуцируя mean-reversion инвентаря около нуля.

Помимо PPO, в репозитории есть пример решения той же задачи vanilla policy gradient — более простой алгоритм, не из SB3, реализованный авторами. Для ускорения обучения начальный инвентарь может случайно принимать целые значения из интервала, расширяя покрытие состояний.

Рис. 3. Выученные и оптимальные глубины котирования как функции инвентаря
Рис. 3. Обученный PPO-агент против CarteaJaimungalAgent.

5. Дорожная карта дальнейшего развития

Среда может принять ряд расширений в ближайшем будущем. Примеры группируются в три категории: (i) новые предположения о динамике стохастических процессов; (ii) литература по оптимальному исполнению через торговые скорости; (iii) работа mbt_gym с другими RL-библиотеками.

Что касается (i), среда уже готова к ряду расширений. Можно исследовать, как меняются оптимальные стратегии, если fill-модель зависит от приходов, действий и самих исполнений. Например, в экспоненциальной модели $\mathbb{P}[\mathrm{Fill}]=e^{-\kappa\,\delta}$, где $\delta\ge 0$ — глубина котирования, а $\kappa>0$ — экспонента заполнения, параметр $\kappa$ можно сделать стохастическим процессом, на который влияют arrivals, actions и fills.

Можно также реализовать тип действий touch-and-market: контроль выставления на лучших котировках и момента отправки рыночной заявки на единицу актива.

Другие расширения сложнее: (a) гранулярные приходы через многомерные процессы Хокса — см. §5 в [1]; (b) латентность — [28; 20]. Разберём (b) чуть подробнее. В [20] время (в часах агента) между отправкой заявки на биржу и исполнением экспоненциально распределено (случайная латентность) или фиксировано (детерминированная). Оба варианта реализуемы через обновление mid-цены совместно с классом LatencyProcess (наследник StochasticProcess), задающим (возможно, случайную) задержку. Mid обновляется от $t$ до $t+\ell$, где $\ell$ — латентность; сделка совершается в $t+\ell$; затем mid идёт от $t+\ell$ до $t+\Delta$, где $\Delta$ — шаг времени; предполагается $\mathbb{P}[\ell\in(0,\Delta]]=1$. Так латентность учитывается эндогенно, а не как искусственная стоимость.

В части (ii) планируется тип действий trading_speed: контроль — скорость покупки/продажи. Аналогично fill-экспоненте нужен класс price impact, открывающий изучение оптимальных стратегий при разных функциях или процессах импакта. Дальше — гибриды speed-and-limit и speed-and-touch: агент торгует с выбранной скоростью и одновременно выставляет ликвидность в надежде на fill по лучшей цене, чем агрессивный захват [14].

Для (iii) желательна интеграция с RLlib и RLax6 как альтернативами Stable Baselines. Наконец, естественное расширение — от single-agent RL к multi-agent RL, например для обучения агентов, робастных к параметрам модели, как в [52].

6. Заключение

Представлен mbt_gym — библиотека сред для применения RL к model-based задачам торговли в LOB — вместе с дорожной картой развития. Авторы приветствуют вклад сообщества.

Сноски

  1. В листингах статьи импорты идут из пакета DRL4AMM — рабочее имя проекта на момент ICAIF; актуальный репозиторий называется mbt_gym.
  2. Для стационарности процесса Хокса $\kappa$ должно быть достаточно большим. В оригинале сноска записана как $\kappa^{\alpha}$; в уравнении (1) параметр — $\kappa$.
  3. В оригинале: «the probability of not getting filled … is less than 1%». По смыслу свойства max_depth и по типичной калибровке экспоненциального fill ($e^{-\kappa\delta}\approx 0{,}01$) имеется в виду вероятность исполнения меньше 1%.
  4. Rollouts считались на AMD Ryzen 7 3800X (8 ядер, 16 потоков) с 64 GB RAM.
  5. Использована реализация PPO из Stable Baselines 3.
  6. docs.ray.io/en/latest/rllib; github.com/deepmind/rlax · обновлён 2026-08-06 · 226 коммитов.

Литература