Создайте биткойн-бота в Unreal Engine 4, используя глубокое обучение с подкреплением и визуальные сценарии

[Загрузить весь проект на Github]

Начнем с очевидного вопроса - зачем использовать игровой движок для создания бота для автоматической торговли?

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

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

В этом примере мы будем использовать плагин MindMaker Machine Learning для Unreal Engine, который можно скачать бесплатно и который имеет приятную гладкую кривую обучения. Фактически, весь этот пример может быть выполнен без программирования ни одной строчки кода! MindMaker предоставляет визуальный интерфейс сценариев для применения методов ИИ, таких как глубокое обучение с подкреплением, к широкому кругу приложений в игровом движке, включая управление роботами, поведение NPC, процедурную графику и т. Д. Поскольку он использует чертежи Unreal Engine, можно делать все на машине учиться, ничего не зная о библиотеках внутреннего обучения, таких как Tensorflow, Pytorch или Keras. Это позволяет нам построить весь наш проект, используя только визуальные сценарии, и быстро решить то, что в противном случае могло бы оказаться сложной задачей. Использование визуальных сценариев также снижает барьеры для входа для тех, кто хочет запачкать руки машинным обучением или автоматической торговлей.

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

Без дальнейших предварительных действий приступим к созданию нашего торгового робота.

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

Затем нам нужно настроить нашу торговую среду в Unreal Engine с помощью плагина MindMaker AI. Для этого мы загрузим плагин M indMaker AI для Unreal Enginge 4.26. В этом случае мы будем использовать набор алгоритмов MindMaker's Deep Reinforcement Learning Suite, который включает в себя передовые методы машинного обучения, такие как Proximal Policy Optimization (PPO), Asynchronous Actor Critic (A2C) и Deep Q Learning (DQN). После того, как мы настроили нашего торгового бота, мы можем легко переключаться между этими алгоритмами, чтобы увидеть, какой из них работает лучше всего.

Мы начнем с открытия стартового проекта MindMakerDRL в Unreal Engine и поиска папки содержимого MindMakerStarter. Для этой цели можно также легко изменить один из примеров проектов MindMaker DRL, но использование пустого начального проекта обеспечивает более чистую основу. Одним из первых бизнес-заказов является импорт данных о торговле акциями. Это делается с помощью таблицы данных Unreal Engine. Чтобы импортировать данные обучения, мы должны создать настраиваемую структуру, которая будет использоваться для сортировки таблицы данных при ее импорте. Для этого создайте новую настраиваемую структуру с именем StockDataStructure и введите в нее заголовки каждого столбца, содержащиеся в файле .csv ваших исторических данных о запасах. После этого перетащите CSV-файл в папку UE в интерфейсе игрового движка. UE автоматически предложит вам предоставить структуру для организации таблицы данных, и вы захотите выбрать только что созданную пользовательскую структуру. Чтобы получить подробное представление об этом процессе импорта таблицы данных, посмотрите это поучительное видео:

Https://www.youtube.com/watch?v=nt1hlJO-DPo

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

Найдите ресурс чертежа MindMaker под названием «MindMakerObject» в папке начального содержимого и переименуйте его в MindMakerStockBotBP или что-то подобное. Это шаблон чертежа, который мы будем использовать для создания нашего торгового бота. Затем перетащите объект MindMakerStockBotBP на карту проекта, расположенную в каталоге начальных карт содержимого. По умолчанию объект MindMakerStockBot отображается на экране в виде сферы. См. Картинку. Вы могли бы заменить это на какой-нибудь другой объект, но сфера - это хорошая прибавка ко всем научно-фантастическим фильмам, в которых сфера представляет собой могущественный инопланетный разум. В самом деле, есть что-то чуждое в том, как глубокое обучение с подкреплением может открывать стратегии, не полностью понятые человеческому разуму.

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

Затем найдите узел события Launch MindMaker и добавьте к нему следующее, по сути устанавливая некоторые из наших начальных условий, таких как баланс счета и т. Д.

Настройка действия и пространства для наблюдения:

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

Для наших целей мы установим форму пространства действия на:

«Low = np.array ([0, 0]), high = np.array ([1, 1])»

Мы даем алгоритму описание того, какие действия он будет генерировать. В этом случае, по сути, есть два значения действия, обозначенные массивом [0,0]. Каждое значение в массиве имеет минимальное значение 0 и максимальное значение 1. Первое значение в массиве, которое мы определим, означает, будет ли алгоритм выполнять ордер на покупку, продажу или удержание. Поскольку алгоритм будет возвращать непрерывный спектр значений от 0 до 1, нам необходимо определить граничные условия для ордеров на покупку, продажу и удержание. В следующем разделе мы определяем любое значение ниже 0,33 как удержание, любое значение между 0,333 и 0,666 как покупку и значение выше 0,666 как продажу. На данный момент нам просто нужно указать границы пространства действий, чтобы алгоритм мог начать генерировать случайные действия, на которых он мог бы продолжить обучение.

Второе значение действия, с которым будет работать алгоритм, также является десятичным числом от 0 до 1 и обозначает процент наших активов, которые мы будем покупать или продавать. Итак, если бы у нас было 8 акций, и первое значение в массиве указывало 0,77 (действие продажи), а второе значение массива указывало 0,5, мы бы продали 0,5 или половину наших существующих акций (4). Если вы не знаете, как алгоритм RL определяет свои действия, я написал учебник по обучению с подкреплением, который поможет прояснить это. На данный момент достаточно знать, что алгоритм методом проб и ошибок обнаружит, какие ингредиенты делают успешную сделку, и со временем сделает больше.

Есть и другие способы определить пространство действий для нашего торгового бота, но этот способ относительно простой и интуитивно понятный. Обратной стороной является то, что это дает нашему боту огромные возможности в плане определения своей торговой стратегии, что может продлить обучение. Поскольку мы имеем дело с непрерывным пространством действий между 0 и 1, это создает массивное пространство для исследования, а не ограничивает количество акций, которыми бот может торговать, примерно 1/3, 2/3 или 3/3 всех его активов. . Можно поэкспериментировать с разными способами разграничения пространства действий и посмотреть, как это влияет на поведение ботов. Переходя к следующей части, мы определим пространство для наблюдения за ботами.

Пространство наблюдения - это данные, к которым бот будет иметь доступ о своей «среде», которая в данном случае представляет собой просто несколько значений из исторических данных торговли. Я выбрал несколько из них, всего 9, таких как RSI, MACD, трехдневная или ценовая история и некоторые другие. Можно было легко добавить другие индикаторы или, возможно, удалить несколько. С самого начала трудно сказать, какая из этих ценностей окажется полезной в обучении бота успешной торговой стратегии, поэтому решение, какие ценности включить в пространство наблюдения ИИ, - это своего рода искусство. Мы предоставим фактические значения для них в функции «Сделать наблюдения», но пока мы просто определяем объем параметров, которые будут использоваться в качестве наблюдений. Мы делаем это, вводя следующее в поле формы наблюдения:

«Low = 0, high = 2147483648, shape = (1, 9), dtype = np.float32»

Таким образом, алгоритм обучения подготовлен к приему данных наблюдений, когда они будут представлены. Пока мы здесь, мы также хотим выбрать алгоритм обучения, который мы будем использовать для обучения, в данном случае A2C (Actor Critic). Кроме того, мы установим количество обучающих эпизодов (34 608 - это количество, которое, как я обнаружил, работает хорошо) и некоторую другую информацию, например, хотим ли мы сохранить обученный алгоритм, когда он будет завершен, и какое имя дать ему. Вот пример того, как это может выглядеть.

Определение торговой среды: действие, наблюдение и вознаграждение

Теперь перейдем к следующей важной функции торгового бота - функции получения действия. Структурно торговый бот и связанный с ним алгоритм обучения расположены вне Unreal Engine в исполняемом файле движка MindMaker. Стратегические действия, определенные алгоритмом, генерируются здесь, а затем передаются в Unreal Engine через соединение socketIO. После этого мы обновляем среду Unreal Engine на основе этих действий и отправляем обратно данные о вознаграждениях и наблюдениях из UE в движок обучения (подробно обсуждается в ближайшее время). Эти награды и наблюдения затем используются механизмом обучения для улучшения выбора действий, и процесс повторяется.

Функция получения действия - это то место, где Unreal Engine получает действие от алгоритма обучения Mindmaker DRL и решает, как его следует обрабатывать. В этом случае нам нужно будет выполнить ряд вычислений на основе действия, выбранного алгоритмом, а затем передать обратно набор наблюдений и вознаграждений на основе этих вычислений. Чтобы понять общую схему того, как действия, наблюдения и награды передаются между средой и алгоритмом обучения, может быть полезно ознакомиться с процессом принятия решений Маркова, а также со средой обучения с подкреплением OpenAI Gym. MindMaker по сути следует той же схеме, что и тренажерный зал OpenAI, для обработки наград, наблюдений и действий.

Продолжая, откройте функцию действия приема в MindMakerStockBotBP. Это одна из функций по умолчанию, включенных в MindMakerObjectBP. Внутри происходит большая часть наших вычислений с точки зрения настройки среды торговли акциями. Сначала нам нужно проанализировать и сохранить действие, предоставленное нам механизмом обучения MindMaker. То есть нам необходимо определить тип сделки, выбранной алгоритмом, будь то покупка, продажа или удержание, и размер нашего портфеля для торговли. Затем нам нужно сохранить эти данные в переменных. Смотрите картинку.

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

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

Затем нам нужно спросить, какому значению действия, полученному от обучающей системы, соответствует покупка, продажа или удержание. Это будет десятичное значение от 0 до 1, и нам нужно определить, что эти значения означают с точки зрения торговли. Как уже упоминалось, я решил разбить это на 3 равных набора: от 0 до 0,333, от 0,333 до 0,666 и 0,666 и выше. У нас есть пара узлов ветвления, чтобы определить, какое из этих значений было возвращено механизмом обучения, см. Рисунок.

Если значение типа сделки меньше 0,33, это приравнивается к удержанию, поэтому никакие вычисления в отношении акций или остатков не требуются. Наша чистая стоимость по-прежнему будет колебаться, если мы будем держать какие-либо акции, поскольку цена актива увеличивается или уменьшается, но это пока не нужно рассчитывать. Следуя ложной ветви нашего условного условия Hold, мы добавляем еще один условный узел, чтобы определить, является ли это действием Buy. Если значение действия находится между 0,333 и 0,666, это приравнивается к покупке, и нам нужно провести серию вычислений, сначала определив, возможна ли покупка с учетом баланса нашего счета, а затем определить, какую сумму купить на основе второго. значение, возвращаемое механизмом обучения. Это второе значение представляет собой процентную долю баланса нашей учетной записи, которую можно потратить на покупку. Отсюда мы можем определить, сколько акций капитала / валюты мы покупаем, и рассчитать остаток на счете, количество удерживаемых акций и т. Д. Это можно увидеть на следующем рисунке.

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

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

После выполнения этих расчетов переходим к функции «Задержка для отображения». Это отделено от функции действия приема, потому что в некоторых случаях мы хотели бы, чтобы наша среда UE изменялась в зависимости от действий, выполняемых агентом, и это можно обрабатывать отдельно в функции задержки для отображения. Поскольку задержка для отображения находится внутри окна «График событий», она поддерживает такие узлы, как «Задержка», которые могут быть важны для приостановки алгоритма обучения, пока происходят изменения в среде. В нашем случае это на самом деле не важно, поскольку во время торговли не происходит визуальных изменений среды, и мы не будем работать с какими-либо задержками.

В дополнение к обновлению среды Unreal функция Delay for Display выполняет три задачи: (1) мы вызовем функцию Make Observations, чтобы собрать данные, которые мы хотим передать обратно в алгоритм обучения, (2) мы вызовем функцию Check Reward. чтобы решить, как будут распределяться вознаграждения алгоритму на основе его действий, и (3) мы передадим всю эту информацию обратно в движок обучения MindMaker, чтобы он мог соответствующим образом обновить свою стратегию. Это ключ к обучению с подкреплением, нужно организовать вознаграждение, наблюдения и действия в согласованном потоке, чтобы механизм обучения мог оптимизировать свое поведение. Вы можете увидеть задержку для функции отображения на следующем рисунке.

Затем мы рассмотрим каждую из функций в Delay for Display, чтобы увидеть, что происходит под капотом. Во-первых, давайте откроем функцию "Наблюдения". Inside Make Observations, нам нужно вытащить некоторые важные торговые данные для рассматриваемого эпизода. Мы делаем это с помощью узла «Получить строку таблицы данных», разбивая его на составные части и выбирая, какие элементы мы хотим предоставить механизму обучения. Я выбрал такие вещи, как MACD, RSI и Trade Volume, среди прочего. Они добавляются в одну строку, каждое значение разделяется запятыми. Этот формат важен, поскольку система обучения предназначена специально для работы с ним. Однако, какие значения размещать здесь, решать вам, если они содержат информацию, необходимую алгоритму для определения выигрышной стратегии. Может быть предоставлена ​​избыточная информация, так как алгоритм должен иметь возможность отсортировать важные данные от несущественных в ходе обучения курса, но если вам не хватает какой-то важной информации в Make Observations, агент будет ограничен в том, насколько хорошо он изучает стратегию. Выбор хороших наблюдений очень важен. Если после многих испытаний ваш агент, кажется, ничего не узнает, это может быть потому, что вы не предоставили правильных наблюдений. Как формулируются наблюдения, мы можем увидеть на следующем рисунке.

После того, как наблюдения сформулированы, мы возвращаемся к функции «Задержка для отображения», где следующий порядок действий - определить, какую информацию о вознаграждении предоставить алгоритму обучения. Это будет происходить в функции проверки вознаграждения, которая вызывается сразу после выполнения наблюдений. Открывая крышку функции Check Reward, нам нужно сформулировать, как вознаграждать алгоритм обучения на основе только что выполненных действий. Создание подходящей функции вознаграждения - это глубокая тема, и от ее правильного выполнения многое зависит. В нашем случае интуитивно понятный подход заключался бы в использовании чистой стоимости в качестве вознаграждения, поскольку это, в конечном счете, то, что мы хотим увеличивать по мере того, как бот торгует. Однако более поучительной наградой на самом деле является ИЗМЕНЕНИЕ собственного капитала в каждом эпизоде, например разница между чистым капиталом в предыдущем эпизоде ​​и в этом. Мы хотим, чтобы алгоритм фокусировался на увеличении чистой стоимости, а не только на достижении высокой чистой стоимости. Можно поэкспериментировать с разными наградами, чтобы найти наиболее эффективную. В нашем случае изменение чистой стоимости, похоже, работает хорошо. Вы можете увидеть, как структурированы награды, на следующем рисунке.

Наконец, возвращаясь к функции «Задержка для отображения», нам нужно обновить настраиваемую структуру MindMaker с данными о наградах и наблюдениях, которые мы только что сгенерировали, и передать их механизму обучения MindMaker в вызове функции Emit. Это отправит данные в механизм обучения через соединение ввода-вывода сокета. Как уже упоминалось, механизм обучения и связанный с ним алгоритм содержатся в отдельном исполняемом файле от Unreal Engine. После того, как данные о награде и наблюдениях будут отправлены, механизм обучения соответствующим образом обновит свою стратегию и выберет новое действие, в идеале, более подходящее для получения награды. Мы в основном обучаем алгоритм торговле методом проб и ошибок, изучая способ, которым собака учится получать награду за еду, выполняя серию действий, таких как сидение или переворачивание. На этом мы завершаем все наши расчеты и настройку торгового бота, когда данные о наградах и наблюдениях отправляются обратно в обучающую систему. Теперь движок обучения выберет новое действие, отправит его в Unreal Enging, и процесс повторится. За многие тысячи итераций алгоритм обучения должен успешно определять, что составляет успешную сделку, на основе данных о вознаграждении и наблюдениях, которые мы ему предоставили.

Тестирование бота и решение проблемы удержания покупки

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

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

После долгих попыток получить правильные параметры обучения, это действительно то, что мы видим: чистая стоимость каждого учебного эпизода неуклонно растет со временем по мере обучения алгоритма. Чтобы подтвердить, что мы действительно на правильном пути, мы можем использовать режим эксплойтов MindMaker, в котором окончательная, полностью обученная версия алгоритма запускается на исторических данных. При этом наш алгоритм работает на удивление хорошо, часто достигая чистой стоимости, превышающей 10 000% от первоначальной стартовой суммы! Это несколько вводит в заблуждение, поскольку простой подход к удержанию покупки в отношении биткойнов привел бы к увеличению чистой стоимости активов примерно на 5000% за тот же период времени.

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

Обсуждение и выводы: будущее автоматизированной торговли

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

Вместо того, чтобы подбирать кривую, было бы точнее сказать, что алгоритм обнаруживает набор причинно-следственных связей в обучающих данных, индикаторы, которые предвещают будущие движения цены акций и, следовательно, полезны для заключения прибыльных сделок. Обучение с подкреплением - это причинно-следственная структура, и то, что мы создаем с помощью нашего торгового бота, похоже на внутреннее чувство, которое испытывают опытные трейдеры, когда видят график конкретной акции и инстинктивно знают, в каком направлении будет двигаться акция, не будучи в состоянии объяснить. их рассуждения. Во многих отношениях обучение с подкреплением соответствует бессознательному дофаминергическому процессу обучения, имеющему место у людей, который экономист Даниэль Канеман назвал мышлением Системы 1. То, что алгоритмы обучения с подкреплением теперь могут имитировать это быстрое, интуитивно понятное принятие решений людьми, предполагает, что мы находимся на переломном этапе в отношении машинного обучения. Таким образом, нам, вероятно, потребуются новые методы понимания и взаимодействия с нашими компьютерами, поскольку они начинают программироваться способами, более похожими на дрессировку животных, чем с помощью заданных дискретных наборов инструкций. Значение этой и подобных тем освещается в соответствующих сообщениях в блоге, а также в книге Перехитрили: обучение с подкреплением, его перспективы и опасность.

Также Автор

Перехитрил: обучение с подкреплением - это обещание и опасность

Причина и следствие взлома с помощью обучения с подкреплением

Создание ИИ видеоигр нового поколения с использованием обучения с подкреплением

Когда идентичность становится алгоритмом