Создание сигнального криптобота Telegram для приема сигналов на основе ваших собственных торговых идей на Python

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

В этой статье я хочу поделиться первыми шагами по созданию Telegram-бота на aiogram и показать простую торговую идею с использованием данных криптобиржи.

План статьи:

  1. Генерация токена для бота Telegram
  2. Получить идентификатор пользователя
  3. Создание базового функционала для бота
  4. Разработайте торговую идею
  5. Положил все это вместе

Исходный код можно найти на моем Github.

1. Создайте токен для бота Telegram

Прежде всего, вам нужно создать бота с @BotFather в Telegram.

  1. Найдите @BotFather в Telegram
  2. Отправить сообщение «/start»
  3. Отправьте сообщение «/newbot» и следуйте инструкциям, чтобы создать имя и имя пользователя для своего бота.
  4. Скопируйте и сохраните токен API бота.

2. Получите идентификатор пользователя

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

  1. Найдите @getmyid_bot в Telegram
  2. Отправить сообщение «/start»
  3. Скопируйте и сохраните идентификатор пользователя.

3. Создайте базовый функционал для бота

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

Вы можете поместить токен API и идентификатор пользователя прямо в код, но в этом руководстве мы будем считывать их из локального файла по соображениям безопасности. Убедитесь, что никто не имеет доступа к файлу, и при необходимости добавьте его в .gitignore. Создайте файл .env в каталоге проекта для хранения токена API и идентификатора пользователя.

# place user_id and api token instead of brackets
USER_ID=<your user id> 
BOT_TOKEN=<your API token>

Затем напишите базовую логику для бота.

Я использую пакет dotenv для работы с .env файлами. load_dotenv() загружает идентификатор пользователя и токен API из файла в код. Botпомогает взаимодействовать с Telegram API, а Dispatcher работает с сообщениями. executor.start_polling() запускает бота.

Теперь мы создали две функции:

  1. send_welcome отвечает: «Привет!» когда мы отправляем боту «/start» или «/help»
  2. echo просто возвращает текст, который мы отправили боту

4. Разработайте торговую идею

❗️ Важно. Это не финансовая рекомендация. Я не предлагаю инвестиции, трейдинг или любые другие советы. Любые инвестиции или риски, которые вы принимаете, используя эту торговую идею, являются вашей ответственностью.

В этой части я не хочу реализовывать популярные ТА-индикаторы готовыми к использованию TA-Lib или другими пакетами. Давайте сосредоточимся на чем-то более простом и необычном, но, возможно, не столь эффективном, как классические инструменты ТА 😊.

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

И давайте посчитаем это как агрегированные значения. Посмотрите на диаграмму ниже. Есть два графика соотношения биткойнов к USDT на 1-часовом и 5-минутном таймфреймах. 1 час соответствует 12 свечам по 5 минут, где каждая временная метка имеет положительный или отрицательный доход и объем торгов.

Алгоритм:

  1. На каждый час выберите 12 свечей по 5 минут каждая.
  2. Рассчитайте абсолютные суммы доходностей для положительных закрытых свечей и отрицательных закрытых свечей
  3. Рассчитать объемы для положительных закрытых свечей и отрицательных закрытых свечей
  4. Разделите сумму объема положительно закрытой свечи на сумму доходности положительно закрытой свечи и сделайте то же самое для отрицательного объема и доходности.
  5. Рассчитайте соотношение этих величин (назовем его VPR — объем на возврат)

create_config() предоставляет параметры, необходимые для загрузки и обработки данных. Функция get_signal() загружает данные с помощью get_data() и вычисляет VPR с помощью функции calculate_vpr(). В результате рассчитанные коэффициенты должны выглядеть так, как показано на диаграмме ниже.

Интерпретация заключается в том, что чем выше значение VPR, тем труднее поднять цену, поскольку для роста требуется больше объема, чем для падения. И чем ниже значение VPR, тем труднее упасть цене.

Таким образом, мы можем найти экстремальные значения, отследить динамику VPR во времени или провести другой анализ.

5. Соберите все вместе

Теперь добавим функцию отправки торговой идеи.

send_info() генерирует сигнал, создает и отправляет пользователю график с текстом. С помощью декоратора @dp.message_handler(commands=['signal']) мы можем отправить сообщение "/signal", чтобы получить диаграмму со значением VPR. Выражение await message.answer_photo(fig, caption=text) отвечает за отправку изображений.

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

config.hard_to_grow_th = 60
config.hard_to_fall_th = 40
# Calculate signals
resampled_data['hard_to_grow'] = resampled_data.vpr >= config.hard_to_grow_th
resampled_data['hard_to_fall'] = resampled_data.vpr <= config.hard_to_fall_th

Функция send_signal() вычисляет VPR, генерирует сигналы с использованием определенных пороговых значений и создает диаграмму. Я добавил смайлик к тексту, чтобы сделать его более привлекательным, используя пакет emoji.

Теперь нам нужно запланировать задачу для бота, чтобы он мог запускать функцию каждые 60 минут и 5 секунд (в качестве промежутка).

Я использовал apscheduler для создания планировщика. Передайте interval в качестве значения триггера, зарегистрируйте send_signal() и не забудьте об объекте bot.

В итоге должно получиться вот так

Не стесняйтесь проверить полный код в моем репозитории Github.