Можно ли с помощью ИИ автоматизировать набор правил, по которым действуют на бирже профессиональные трейдеры? Команда VK Cloud Solutions перевела статью о том, как это удалось реализовать и что вышло из такой затеи. Пару недель назад я болтал с приятелем. Он рассказывал мне, что пытался устроить детокс от брокерского приложения на смартфоне. Я забеспокоился, не разорился ли он, и уточнил значение слова «детокс» в этом контексте.  Он ответил, что занимается трейдингом. «Если какая-то ценная бумага растет на протяжении часа и я уже заработал более 1%, я ее продаю, — объяснил он. — Это одно из моих персональных правил». Не обращая внимания на псевдонаучный аспект этих правил, я понял, что он имел в виду под детоксом. Чтобы соблюдать такие правила, нужно постоянно заглядывать в смартфон. И я задумался, можно ли автоматизировать набор правил, по которым действовал мой приятель? Чтобы система занималась трейдингом вместо меня? Вы наверняка уже догадались, что ответ на этот вопрос — «да». Что ж, давайте порассуждаем.  Но для начала: время — деньги, и я не хочу никого разводить на деньги. Вот что мы сделаем: Возьмем детализированные данные о ценах на акции в реальном времени, в идеале с интервалом в одну минуту. Чем их больше, тем лучше. Используем для этого Yahoo! Finance, подробнее объясню ниже. Вместо персонального набора правил добавим в систему ИИ. Раскрою все карты. Я, мягко говоря, не эксперт по анализу временных рядов. Сейчас есть немало руководств по обучению нейронных сетей трейдингу, и мне совершенно не хочется усложнять игрушечную систему вроде этой. Так что давайте стремиться к простоте: пока нам хватит самой базовой модели ARIMA. У нас есть данные и прогноз, который мы получаем от алгоритма. С его помощью нужно решать, что делать с акциями: покупать, продавать или сохранять. А еще нужно подключиться к брокеру, чтобы выполнять нужные действия. Мы будем использовать RobinHood и Alpaca. Вот, собственно, и все — система готова. Осталось только где-то деплоить и отслеживать ее работу. Я решил, что система будет отправлять сообщение в телеграм-чат при выполнении какого-либо действия. Что нам понадобится? Python 3.6 с несколькими библиотеками; учетная запись в облаке с правами администратора для хранения и деплоймента; Node.js, чтобы установить Serverless Framework для деплоймента; аккаунт в телеграме для мониторинга. Весь написанный код — здесь. Без лишних церемоний перейдем к первой части — сбору данных. Собрать данные — дело непростое. Еще несколько лет назад были доступны официальный Yahoo! Finance API и его альтернатива Google Finance. К сожалению, оба сервиса закрылись несколько лет назад. Но остались альтернативы. Я сформулировал следующие требования: Бесплатно. Для рабочей системы я бы, конечно, поменял это требование на «недорого», но для игрушечной системы данные мне нужны бесплатно. Высокая скорость. Желательно вообще без ограничений, но производительности свыше 500 запросов в минуту более чем достаточно. Данные в реальном времени. Некоторые API выдают данные с небольшой задержкой, скажем, в 15 минут. Мне нужны цены на акции, максимально приближенные к текущим. Простота использования. Это проверка идеи, так что мне нужно самое простое решение. С учетом своих требований я решил присмотреться к yfinance — неофициальной альтернативе старого доброго Yahoo Finance API. Для рабочей системы я бы выбрал Alpha Vantage API, опираясь на замечательный список Патрика Коллинза. Но пока давайте не усложнять.  Ран Арусси разработал библиотеку yfinance для доступа к данным Yahoo! Finance, когда официальный API перестал работать. Приведу цитату с GitHub: «С тех пор как Yahoo! Finance закрыли свой API исторических данных, многие программы, которые использовали этот интерфейс, прекратили работу. yfinance призвана решить проблему — это надежное решение на Python для загрузки исторических данных по рынку из Yahoo! Finance». Мило, мне подходит. Как это работает? Для начала библиотеку нужно установить: А потом можно получить доступ к данным через объект Ticker: Это достаточно быстрый метод (в среднем исполняется чуть дольше 0,005 секунды), который возвращает МАССУ информации об акциях. Например, google.info содержит 123 поля, в том числе:  Еще больше данных можно получить с помощью методов dividends, splits, balance_sheet, earnings и других. Большинство из них возвращают данные в виде объекта pandas DataFrame, так что придется немного повозиться, чтобы получить все, что нам нужно.  Пока мне требуется информация об изменении цен на акции с течением времени, лучше всего для этого подходит метод history. Мы можем выбрать период или даты интервала, а также частоту получения данных до одной минуты.  Обратите внимание, что информация с разбивкой по времени внутри дня доступна, если вы указали период менее 60 дней, и что за один запрос можно получить данные с детализацией до минуты только за семь дней. Транспонированные данные последней записи с интервалом в одну минуту: Видно, как они индексируются по дате и времени. При этом у каждой записи семь характеристик: четыре значения цены на акцию за эту минуту (открытие, максимальная, минимальная, закрытие) а также объем, дивиденды и сплит акций. Я буду использовать только характеристику «минимальная». Соберем необходимые данные:   Поскольку мы используем только данные за последний день, давайте проиндексируем DataFrame, чтобы удалить дату и часовой пояс, оставив только время. Хорошо выглядит! Мы уже знаем, как найти последние данные в yfinance. Чуть позже передадим их в наш алгоритм. Но для начала нужно с ним определиться, так что переходим к следующему этапу. Не пытайтесь повторять это в домашних условиях. Я подобрал ОЧЕНЬ простую модель ARIMA для прогнозирования следующей цены на акцию, поэтому относитесь к ней как к учебной. Чтобы использовать эти наработки для настоящего трейдинга, советую поискать модель получше и помощнее. Но не теряйте бдительности: если бы это было просто, такие модели были бы у всех. Для начала давайте разделим DataFrame на данные для обучения и для тестирования, чтобы можно было использовать тестовый набор для проверки результатов учебной модели. В качестве тестового набора я собираюсь использовать последние 10% данных. Построим график: Теперь добавим в модель данные для обучения и получим прогноз. Обратите внимание, что здесь гиперпараметры модели фиксированы, а в реальной жизни для получения оптимальных параметров нужно использовать кросс-валидацию. К вашим услугам замечательное руководство о том, как подбирать гиперпараметры ARIMA по сетке на Python. Я использую конфигурацию 5, 0, 1 и получаю прогноз на момент, который наступает сразу после данных для обучения. Давайте посмотрим, хорошо ли сработала наша учебная модель: Что ж, неплохо, работать можно. С этой информацией получится определить набор правил, основанных на любых наших предпочтениях: не продавать, если акции растут в цене, или продавать, если цена падает. Но не будем формулировать правила — вдруг те, кто потеряют на них все деньги, подадут на меня в суд. Вам придется разработать собственный набор правил без моих подсказок :) А пока я перехожу ко второму этапу — подключению к брокеру. Как вы, наверное, догадались, многое зависит от выбранного брокера. Я расскажу о подключении к RobinHood и Alpaca. Почему я выбрал именно их? Есть публичный API. Они не берут комиссию за трейдинговые операции. В зависимости от типа учетной записи действуют те или иные ограничения. Например, у RobinHood можно совершать всего три трейдинговые операции в пять дней, если остаток на счете менее 25 000 долларов. У Alpaca ограничения не такие жесткие, но все же установлен лимит в 200 запросов в минуту на один ключ API. Есть несколько библиотек, поддерживающих RobinHood API, но ни одна из них не является официальной. Библиотека Sanko была самой большой, с 1,5 тысяч звезд на GitHub, но ее закрыли. Библиотека LichAmnesia приняла эстафету, но пока что набрала только 99 звезд. Я собираюсь использовать robin_stocks, у которой на момент написания статьи чуть более 670 звезд. Давайте ее установим: Для большинства действий нужен логин, так что для начала войдем в систему. RobinHood требует многофакторную аутентификацию, так что необходимо ее настроить. Войдите в свою учетную запись, включите двухфакторную аутентификацию и выберите «other» в ответе на вопрос «Какое приложение вы собираетесь использовать?». Вы получите буквенно-цифровой код, который мы применим: Купить или продать — дело нехитрое: Примеры и варианты использования для продвинутых пользователей можно посмотреть в документации. Для Alpaca мы используем библиотеку alpaca-trade-api, у которой на GitHub более 700 звезд. Устанавливаем: Войдите в учетную запись и получите API key ID и секретный ключ, они нужны для входа в систему: Отправлять поручения здесь несколько сложнее, чем в RobinHood: Готово! Напомню, что оставлять свои учетные данные в виде Plain Text — чрезвычайно плохая идея. Но не переживайте, на следующем этапе мы перейдем к переменным среды, это намного безопаснее. Теперь давайте развернем модель в облаке и настроим мониторинг. Мы собираемся задеплоить нашу систему в AWS Lambda. Для работы это не лучший вариант, поскольку в Lambda нет хранилища, а обученную модель пришлось бы где-то хранить, например в S3.  Но пока обойдемся и этим — запланируем ежедневный запуск Lambda и обучение модели на данных за текущий день. Для мониторинга настроим бот в Telegram, который отправляет сообщение с действием и его результатом. AWS Lambda можно пользоваться бесплатно, если не превышать заданные лимиты; но если вы хотите отправлять очень много сообщений, помните о квотах. Для начала создадим бота. Я опирался на официальную инструкцию из телеграма: Найдите в телеграме пользователя @BotFather. Используйте команду \newbot, выберите название и имя пользователя для бота. Получите и сохраните в надежном месте токен, он вам скоро понадобится. Следующий этап — деплоймент. Есть несколько способов деплоймента в Lambda. Я собираюсь использовать фреймворк serverless, так что давайте его установим и создадим шаблон. Мы создали папку scheduled_tg_bot с тремя файлами: .gitignore, serverless.yml, и handler.py. Serverless.yml определяет деплоймент: что, когда и как будет запущено. А файл handler.py содержит запускаемый код. Нужно поменять CHAT_ID на ID группы, канала или диалога, с которыми бот должен взаимодействовать. Здесь можно узнать, как получить ID канала, а здесь — ID группы. Теперь давайте определим, как запускать код. Откройте serverless.yml и напишите: Этот код сообщает AWS, какая среда выполнения нам нужна, и берет токен телеграма из нашего собственного окружения, чтобы нам не пришлось его развертывать. После этого мы определяем Сron для ежедневного запуска функции в 21:00. Единственное, что осталось сделать перед деплойментом, это получить учетные данные AWS и установить их как переменные среды вместе с токеном и остальными переменными как переменные среды. Получить учетные данные достаточно просто. Из консоли AWS: перейдите в My Security Credentials — Users — Add user; выберите имя пользователя и Programmatic access; на следующей странице выберите Attach existing policies directly — AdministratorAccess; скопируйте и сохраните Access Key ID и Secret Access Key; Вот и все. Теперь давайте экспортируем учетные данные AWS и токен телеграма. Откройте терминал и напишите: Установите необходимые пакеты локально и выполните деплоймент в AWS: Готово! Бот будет торговать за нас каждый день в 21:00 и отправлять нам сообщения о совершенном действии. Для апробации концепции неплохо. Пожалуй, можно порадовать приятеля: теперь он может расслабиться и заниматься трейдингом, не заглядывая в смартфон сто раз в день :) Напомню, что у всех ресурсов, которые мы использовали в этом руководстве, есть собственная документация. Вы можете углубиться в любом направлении, которое вас заинтересует, ведь мы опробовали всего-навсего игрушечную систему! И все-таки я думаю, что эта игрушечная система — хорошее начало для многофункционального сложного продукта. Удачи! Команда VK Cloud Solutions развивает собственные ML-решения. Будем признательны, если вы их протестируете и дадите обратную связь. Для тестирования пользователям при регистрации начисляем 3000 бонусных рублей. Читать по теме: Как дата-сайентистам эффективно сотрудничать с дата-инженерами Четыре хитрости в работе с пайплайнами данных, о которых знают не все Настоящее и будущее дата-инжиниринга