Как стать автором
Обновить

Как я заставил робота читать трейдерские и инвест-каналы вместо меня

Время на прочтение4 мин
Количество просмотров11K

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

Предыстория

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

Знакомство мое с этой темой происходило в нескольких направлениях.

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

Во-вторых, ежедневно начал разбирать биржевые термины, явления и взаимосвязи, и писать для себя заметки в телеге. Таких постов за полгода набралось 500.

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

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

Проблема бесконечного потока информации

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

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

Что я тогда сделал

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

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

Теперь про код

Из библиотек нам понадобится по большому счету только telethon

from telethon import TelegramClient, events, sync
from telethon.tl.functions.channels import JoinChannelRequest
import re

Чтобы сделать робота, который будет подключаться к телеграму по API нам понадобится зарегистрировать свое приложение на странице https://my.telegram.org/, войти в аккаунт, нажать на "API development tools", заполнить первые 2 поля, в Platform выбрать Desktop.

Скопировать App api_id, App api_hash в соответствующие переменные ниже. А в переменную PHONE_NUMBER ввести номер телефона, который привязан к аккаунту телеграмм.

API_ID = 1234567 # вставье свой api_id
API_HASH = 'your_hash'
PHONE_NUMBER = '+7xxxxxxxxxx'  

Далее нужно прописать имена каналов, которые будут на входе алгоритма

 CHANNELS = (
             'channel1_name',  # здесь вводятся имена каналов 
             'channel2_name',  # без https://t.me, @ или ссылок - просто имя
   					 'channel3_name    
             )  

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

# мэппинг
names = {
    'channel1_to_post': ['interesting_text1', 
                         'interesting_text2'],
    'channel2_to_post': ['other_channel_interesting_text1', 
                         'other_channel_interesting_text2', 
                         'other_channel_interesting_text3'],
}
# "разворачивание" под другой формат хранения + приведение к низкому регистру
d = {}
for name in names.keys():
    for t in names[name]:
        d[t.lower()] = name.lower()
print(d)

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

client = TelegramClient('session', API_ID, API_HASH)
client.start()

for channel in CHANNELS:
    client(JoinChannelRequest(channel))

Далее собственно ожидание нового сообщения, проверка по шаблон и принятие решения, куда делать репост

# Ожидание новых постов и пересылка
@client.on(events.NewMessage(CHANNELS))
async def handler(event):
    print(f'received text: {event.message.message}')
    
    for tmp in d.keys():
      await client.forward_messages(d[tmp], event.message)

client.run_until_disconnected()

На этом все, спасибо за внимание!

Теги:
Хабы:
Всего голосов 15: ↑14 и ↓1+13
Комментарии6

Публикации