Я только недавно начал подробно изучать обучение с подкреплением и был очарован, когда понял, как успехи в этой области были достигнуты с помощью таких проектов, как DeepMind AlphaGo и AlphaZero. Это вызвало у меня желание понять глубокий RL со всеми его сложностями, и поэтому я решил проанализировать его компоненты и использовать их для создания интересного приложения.

Создание стабильно прибыльного торгового бота - непростая задача, возможно, до некоторой степени невозможная. Идеальная модель в основном знала бы состояние рынка со всеми его переменными, а также некоторыми переменными, о существовании которых мы даже не подозреваем. В таком проекте, как AlphaZero, меня позабавило то, что алгоритм мог разрабатывать стратегии в игре Го, которые еще не были обнаружены высокоуровневыми игроками в Го. Основываясь на этом понятии, я заинтересован в изучении стратегий, которые агент RL мог бы разработать в сложной торговой среде, и под сложной я имею в виду просто на нескольких рынках.

Большинство статей, которые я прочитал по этой теме, посвящены одному рынку, например, «Бот для торговли биткойнами». Я считаю, что добавляю этот фактор `` сложности '', потому что, во-первых, мы предоставляем нашему агенту больше данных с разных рынков, что снижает вероятность его обобщения, а во-вторых, могут существовать значимые закономерности в наблюдении за несколькими рынками в одном и том же пространстве, которое будет цифровым. валютное пространство для этого проекта.

Создание нашей окружающей среды

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

Наиболее важные два вектора, на которые следует обратить внимание, - это действия и наблюдения. На каждом шаге наш агент будет выбирать монету для покупки, продажи или удержания в размере% от того, что он в настоящее время владеет, поэтому у нас есть массив numpy с формой (3) типа int, где первое значение - это количество пар, с которыми мы будем работать, 2-я - это покупка, продажа или удержание, а последняя - сумма, где 1 - 10%, 2 составляет 20% и так далее.

Что касается пространства для наблюдения, я хочу, чтобы мой агент наблюдал за рынком в целом, а не только за монетой, которой он только что торгуется. Итак, сейчас это (4, 5, 40), где 4 - пары, 5 - объем , значения open, high, low и close для каждого шага, а 40 - это окно ретроспективного анализа, которое, по сути, показывает, как далеко назад агент должен смотреть на данные. Возможно, это не оптимальное пространство для наблюдения, которое нам нужно, но моя цель в этой статье - просто иметь полноценную среду, с которой мы можем начать экспериментировать и проектировать каждый компонент позже.

Также мы определили наш кошелек как список, в котором первое значение - это начальный баланс в долларах США. Обратите внимание, что я использую локально сохраненные данные в виде таблицы Excel, я использовал Binance's API для загрузки рыночных данных для каждой пары, разделенной на листы:

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

Затем мы определяем наш метод reset () для сброса нашей среды с каждым эпизодом:

Подобно конструктору в методе reset () мы повторно инициализируем все, кроме констант, таких как, например, наши данные о ценах.

Теперь перейдем к нашей ступенчатой ​​функции, которой агент будет передавать «действие» и получать объект «временной шаг», содержащий вознаграждение, состояние и скидку на каждом шаге.

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

Затем мы либо покупаем, либо продаем, либо удерживаем, в зависимости от того, что кошелек будет обновлен, и, наконец, мы увеличим наш шаг и вернем объект временного шага в качестве перехода к следующему состоянию.

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

Рендеринг нашей окружающей среды

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

Здесь достаточно просто я инициализировал подзаголовки так, чтобы у нас было 4 оси, используя plt.subplots (2,2), так что у нас есть 2 строки и 2 столбца:

Распространенной библиотекой, используемой для графиков свечей, является «mlp_finance», но по какой-то причине мне было трудно заставить ее работать, поэтому я решил написать свою собственную функцию построения свечей в нашем классе «TradingGraph»:

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

Затем нам нужно определить функцию, которая будет принимать все данные и строить их на 4 подзаголовках:

Переменная 'axs' в нашей конструкции хранит наши подзаголовки в 2-мерном массиве numpy, чтобы к ним можно было получить доступ через индекс, например [0,0] - это первый подзаголовок, [1,0] - второй и так далее. . Поэтому я использовал функцию flatten (), так что это 1-мерный массив размером 4, и теперь мы можем перебирать фреймы данных, где каждый фрейм данных здесь содержит данные о цене монеты, и редактировать его график.

Затем я определил функцию для рендеринга сделок, совершенных нашим агентом:

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

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

Здесь мы просто вызываем render_prices () и render_trades (), а затем draw () библиотеки matplotlib. Обычно matplotlib работает, если в любой момент вызывается функция plot (), она покажет фигуру, но мы использовали plt.ion () в нашем конструкторе, чтобы сообщить об этом что мы будем обрабатывать, когда обновим фигуру. Итак, на каждом шаге мы будем выполнять все необходимые графические работы, а затем вызывать draw, чтобы перерисовать фигуру с изменениями. Наконец, plt.pause (0.1) используется для указания времени в секундах, в течение которого мы будем ждать между каждым кадром, и необходим для работы нашего механизма обновления графика в реальном времени.

Мы можем вернуться к нашему классу среды, импортировать этот класс визуализации как «tg» и определить нашу функцию рендеринга для использования того, что мы только что создали.

Тестирование окружающей среды

Чтобы протестировать нашу среду, я создал новый файл python, чтобы импортировать среду и начать с ней взаимодействовать:

Это запускает среду для 100 шагов с использованием случайного действия покупка, продажа, удержание с распределением вероятностей 0,1, 0,1, 0,8 соответственно, затем выбирает случайную монету и Я оставил количество равным 2, потому что это не влияет на нашу текущую визуальную модель, поэтому пока нет необходимости рандомизировать ее.

Наш окончательный результат:

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

Следующим шагом будет добавление оболочки tenorflow pyenvironment в нашу среду, чтобы агенты TF могли правильно взаимодействовать без проблем, но мы оставим это для следующей статьи.

Резюме и заключительные мысли

В этой статье я обсудил процесс, через который я прошел, чтобы разработать полноценную среду обучения с подкреплением агентов TF для криптотрейдинга на python. Вы можете найти полный код этого проекта здесь. Еще предстоит проделать некоторую работу, прежде чем мы сможем начать применять обучение с подкреплением. Любые обновления, которые я делаю, будут обновлены в этой статье и в репозитории, поэтому нет необходимости на самом деле просматривать эти незначительные изменения. Так что, надеюсь, в следующей статье мы сможем начать с более интересных аспектов и начать экспериментировать с современными алгоритмами обучения с подкреплением, предоставленными моей библиотекой агентов Tensorflow.

Это один из самых забавных, но разочаровывающих проектов, над которыми я работал, и дальше он будет становиться только интереснее, так что надеюсь, что вы нашли в нем ценность и следите за обновлениями :)