Как настроить торгового телеграм-бота для отображения торговых индикаторов

Индикаторы помогают трейдеру глубже анализировать рынок и принимать более эффективные решения в торговле. В этой статье разберем, как реализовать отображение самых популярных индикаторов на ценовом графике с помощью телеграм-бота — чтобы автоматизировать анализ, правильнее определять тренды и точнее отслеживать движение цен.
Определяем типы индикаторов
Мы будем использовать для анализа через бота эти индикаторы:
- OHLC — индикатор OHLC. Показывает цены открытия, максимума, минимума и закрытия для каждого периода.
- MA — индикатор Moving Average (скользящее среднее). Показывает среднее значение цены за выбранный промежуток времени.
- VOL — индикатор Volume. Показывает объемы торгов — количество заключенных сделок за единицу времени.
- BB — индикатор Bollinger Bands (ленты, линии боллинджера). Показывает отклонения цены на рынке относительно нормального торгового интервала в режиме реального времени.
- RSI — индикатор Relative Strength Index (RSI, индекс относительной силы индикатор). Показывает соотношение положительных и отрицательных изменений цены.
- STC — индикатор Stochastic Oscillator (стохастический осциллятор индикатор). Показывает отношение между ценой закрытия и диапазоном «максимум-минимум» за период в виде процентов.
- Zigzag— индикатор зигзаг в трейдинге. Показывает наиболее значимые высшие и низшие точки графика.
- ALL — дашборд с 3 индикаторами. Показывает индикаторы Moving Average, Volume и Stochastic Oscillator.
Определяем инструменты и параметры для графиков
Для индикаторов определяем следующие параметры: валютная пара, интервал, период, значение окна.
Валютная пара
- BTCUSDT – Биткоин/ Tether
- ETHUSD — Эфириум/ Доллар
- BTCPERP — Биткоин/ Perpetual Protocol
- ETHPERP — Эфириум/ Perpetual Protocol
- BTCUSD — Биткоин/ Доллар
- XRPUSDT — XRP/ Tether
- BNBUSDT — Binance Coin/ Tether
- DOGEUSDT — Dogecoin/ Tether
- GMTUSDT — GMT/ Tether
Интервалы
1, 3, 5, 15, 30, 60, 120, 240, 360, 720, D, W, M
Периоды
Любое числовое значение в количестве дней — например, интервал в 90 дней.
Значения окна
Количество дней: 1, 3, 5, 10, 30.
Также у индикаторов BB, RSI, STC, ALL можно добавить значение параметра «окно» через нижнее подчеркивание. Например: BB_1, RSI_5, STC_10, ALL_30
Реализация отображения индикаторов: подготовительный этап
Создаем токен для телеграм-бота:
1 | TOKEN = os.environ.get( 'TOKEN' ) |
Данные получаем с помощью API от сервиса bybit.com:
1 2 3 4 5 |
Добавляем список инструментов:
1 2 3 | SYMBOLS = [ 'BTCUSDT' , 'ETHUSDT' , 'BTCPERP' , 'ETHPERP' , 'BTCUSD' , 'ETHUSD' , 'BTCUSDT' , 'XRPUSDT' , 'BNBUSDT' , 'DOGEUSDT' , 'GMTUSDT' ] |
Добавляем список графиков:
1 2 3 4 5 | CHARTS = [ 'OHLC' , 'MA' , 'VOL' , 'MPET' , 'ZIGZAG' , 'ALL_1' , 'ALL_5' , 'ALL_10' , 'ALL_30' , 'BB_1' , 'BB_3' , 'BB_5' , 'BB_10' , 'RSI_1' , 'RSI_5' , 'RSI_10' , 'RSI_30' , 'STC_1' , 'STC_5' , 'STC_10' , 'STC_30' ] |
Добавляем список интервалов:
1 2 | INTERVALS = [ 1 , 3 , 5 , 15 , 30 , 60 , 120 , 240 , 360 , 720 , 'D' , 'W' , 'M' ] |
Добавляем словарь расшифровок и терминов:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | INTERVAL_NAMES = { 1 : '1 minute' , 3 : '3 minutes' , 5 : '5 minutes' , 15 : '15 minutes' , 30 : '30 minutes' , 60 : '1 hour' , 120 : '2 hours' , 240 : '4 hours' , 360 : '6 hours' , 720 : '12 hours' , 'D' : 'day' , 'W' : 'week' , 'M' : 'month' , |
Создаем бота:
1 | bot = telebot.TeleBot(TOKEN) |
Создаем функцию для отправки инструкции по формированию запроса после запуска бота командой /start:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | symbols_list = ( 'BTCUSDT, ETHUSDT, BTCPERP, ' '\n ETHPERP, BTCUSD, ETHUSD, ' '\n BTCUSDT, XRPUSDT, BNBUSDT, ' '\n DOGEUSDT, GMTUSDT' ) intervals_list = ( '1, 3, 5, 15, 30, 60, 120, ' '\n 240, 360, 720, D, W, M' ) charts_list = ( 'OHLC, MA, VOL, MPET, ZIGZAG, ' '\n ALL_1, ALL_5, ALL_10, ALL_30, ' '\n BB_1, BB_3, BB_5, BB_10, ' '\n RSI_1, RSI_5, RSI_10, RSI_30, ' '\n STC_1, STC_5, STC_10, STC_30' ) text = (f "Укажите:" "\n 1. Инструмент" f "\n {symbols_list}" "\n\n 2. Интервал (в минутах)" f "\n {intervals_list}" "\n\n 3. Период (в днях)." "\n\n 4. График:" f "\n {charts_list}" "\n\n Пример: BTCUSD 240 7 OHLC" ) bot.send_message(message.chat. id , text) |
Создаем функцию для проверки наличия запроса со стороны пользователя:
1 2 3 4 5 | request = message.text.split() if request: return True else : return False |
Создаем функцию для выдачи результата на основе информации, запрошенной пользователем:
1 2 | Получение содержания запроса пользователя: request = message.text.split() |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | Текущее время для отображения в ответе пользователю: date_now = dt.datetime.fromtimestamp(time.time()).strftime( '%d.%m.%Y' ) Текст сообщения об ошибке, в случае если пользователь неверно ввел данные: text_error = 'Проверьте пожалуйста формат введенных данных.' Проверка запроса на наличие требуемых 4 параметров: # try: if ( len (request) = = 4 ): Определение инструмента из введенного запроса: symbol = str (request[ 0 ]) Определение интервала из введенного запроса: if request[ 1 ] in [ 'D' , 'W' , 'M' ]: interval = str (request[ 1 ]) elif request[ 1 ] in [ '1' , '3' , '5' , '15' , '30' , '60' , '120' , '240' , '360' , '720' ]: interval = int (request[ 1 ]) Определение периода из введенного запроса: period = int (request[ 2 ]) Определение типа графика из введенного запроса: chart_name = str (request[ 3 ]) Проверка валидности введенных данных в запросе для последующей генерации соответствующего ответа: if ((symbol in SYMBOLS) & (interval in INTERVALS) & ( type (period) = = int ) & (chart_name in CHARTS)): Получение данных на основе полученного инструмента и интервала: data = bybit.get_data(URL, symbol, interval) Определение начальной и конечной даты на основе полученного периода и фильтрации полученных данных: end_date = dt.date.today() start_date = end_date + dt.timedelta(days = - period) Фильтрация полученных данных на основе параметров, полученных в запросе пользователя: df = etl(data, start_date, end_date) Определение паттерна «тренд» для полученных данных: trend = ohlc.trend_pattern(df) reversal = ohlc.reversal_pattern(df) oid_fill = ohlc.void_fill_pattern(df) Генерация шаблона отчета для пользователя на полученный от него запрос согласно указанным параметрам: text_analytics = (f "Инструмент: {symbol}" f "\nДата: {date_now}" "\nВремя анализа: 00:01" f "\nАнализ на: {period} days" f "\nНаправление тренда: {trend}" f "\nПаттерн разворот: {reversal}" f "\nПаттерн пустота: {oid_fill}" f "\nТочки входа определены на: " f "{INTERVAL_NAMES[interval]}" ) |
Реализация отображения индикаторов
График OHLC
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | Проверка наличия в запросе типа графика OHLC: if chart_name = = 'OHLC' : Создание графика OHLC: charts.chart_ohlc(df, symbol, interval, period) Сохранение полученного графика в файл .png: chart = open ( 'images/chart_' + chart_name + '_' + symbol + '_' + str (interval) + '_' + str (period) + '.png' , 'rb' ) Отправка полученного графика ботом пользователю: bot.send_photo(message.chat. id , chart) Отправка подготовленного текстового отчета ботом пользователю: bot.send_message(message.chat. id , text_analytics) |
График Moving Averages
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | Проверка наличия в запросе типа графика Moving Averages: elif chart_name = = 'MA' : Создание графика Moving Averages: charts.chart_moving_averages(df, symbol, interval, period) Сохранение полученного графика в файл .png: chart = open ( 'images/chart_' + chart_name + '_' + symbol + '_' + str (interval) + '_' + str (period) + '.png' , 'rb' ) Отправка полученного графика ботом пользователю: bot.send_photo(message.chat. id , chart) Отправка подготовленного текстового отчета ботом пользователю: bot.send_message(message.chat. id , text_analytics) |
График Bollinger Bands
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | Проверка наличия в запросе типа графика bollinger bands: elif 'BB' in chart_name: Определение в запросе типа графика и значения параметра window: chart_nm, chart_vl = chart_name.split( '_' ) Создание графика bollinger bands: charts.bol_bands(df, symbol, interval, period, k = int (chart_vl)) Сохранение полученного графика в файл .png: chart = open ( 'images/chart_' + chart_nm + '_' + symbol + '_' + str (interval) + '_' + str (period) + '.png' , 'rb' ) Отправка полученного графика ботом пользователю: bot.send_photo(message.chat. id , chart) Отправка подготовленного текстового отчета ботом пользователю: bot.send_message(message.chat. id , text_analytics) |
График Volume
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | Проверка наличия в запросе типа графика Volume: elif chart_name = = 'VOL' : Создание графика Volume: charts.chart_vol(df, symbol, interval, period) Сохранение полученного графика в файл .png: chart = open ( 'images/chart_' + chart_name + '_' + symbol + '_' + str (interval) + '_' + str (period) + '.png' , 'rb' ) Отправка полученного графика ботом пользователю: bot.send_photo(message.chat. id , chart) Отправка подготовленного текстового отчета ботом пользователю: bot.send_message(message.chat. id , text_analytics) |
График RSI
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | Проверка наличия в запросе типа графика RSI: elif 'RSI' in chart_name: Определение в запросе типа графика и значения параметра window: chart_nm, chart_vl = chart_name.split( '_' ) Создание графика RSI: charts.rsi(df, symbol, interval, period, k = int (chart_vl)) Сохранение полученного графика в файл .png: chart = open ( 'images/chart_' + chart_nm + '_' + symbol + '_' + str (interval) + '_' + str (period) + '.png' , 'rb' ) Отправка полученного графика ботом пользователю: bot.send_photo(message.chat. id , chart) Отправка подготовленного текстового отчета ботом пользователю: bot.send_message(message.chat. id , text_analytics) |
График Stochastic
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | Проверка наличия в запросе типа графика Stochastic: elif 'STC' in chart_name: Определение в запросе типа графика и значения параметра window: chart_nm, chart_vl = chart_name.split( '_' ) Создание графика Stochastic: charts.stochastic(df, symbol, interval, period, k = int (chart_vl)) Сохранение полученного графика в файл .png: chart = open ( 'images/chart_' + chart_nm + '_' + symbol + '_' + str (interval) + '_' + str (period) + '.png' , 'rb' ) Отправка полученного графика ботом пользователю: bot.send_photo(message.chat. id , chart) Отправка подготовленного текстового отчета ботом пользователю: bot.send_message(message.chat. id , text_analytics) |
График Market Profile External Timeframe
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | Проверка наличия в запросе типа графика Market Profile и External Timeframe: elif chart_name = = 'MPET' : Создание графика Market Profile и External Timeframe: charts.chart_mpet(df, symbol, interval, period) Сохранение полученного графика в файл .png: chart = open ( 'images/chart_' + chart_name + '_' + symbol + '_' + str (interval) + '_' + str (period) + '.png' , 'rb' ) Отправка полученного графика ботом пользователю: bot.send_photo(message.chat. id , chart) Отправка подготовленного текстового отчета ботом пользователю: bot.send_message(message.chat. id , text_analytics) |
Дашборд из трех графиков
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | Проверка наличия в запросе дашборда из 3 графиков: elif 'ALL' in chart_name: Определение в запросе типа графика и значения параметра window: chart_nm, chart_vl = chart_name.split( '_' ) Создание дашборда из трех графиков: charts.ma_vol_stc(df, symbol, interval, period, k = int (chart_vl)) Сохранение полученного графика в файл .png: chart = open ( 'images/chart_' + chart_nm + '_' + symbol + '_' + str (interval) + '_' + str (period) + '.png' , 'rb' ) Отправка полученного графика ботом пользователю: bot.send_photo(message.chat. id , chart) Отправка подготовленного текстового отчета ботом пользователю: bot.send_message(message.chat. id , text_analytics) |
График ZigZag
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | Проверка наличия в запросе графика ZigZag: elif chart_name = = 'ZIGZAG' : Создание графика ZigZag: charts.chart_zigzag(df, symbol, interval, period) Сохранение полученного графика в файл .png: chart = open ( 'images/chart_' + chart_name + '_' + symbol + '_' + str (interval) + '_' + str (period) + '.png' , 'rb' ) Отправка полученного графика ботом пользователю: bot.send_photo(message.chat. id , chart) Отправка подготовленного текстового отчета ботом пользователю: bot.send_message(message.chat. id , text_analytics) |
Дополнительные функции
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | Отправка сообщения об ошибке в случае некорректного ввода данных: bot.send_message(message.chat. id , text_error) Запуск цикла для отслеживания ошибок при работе бота: i = 0 while True : i + = 1 try : Запуск бота: bot.polling() Определение текущего времени, для отслеживания ошибок: time_now = dt.datetime.fromtimestamp( time.time()).strftime( '%d-%m-%Y %H:%M:%S' ) Вывод номера очередности, времени и текста ошибки: print (i, time_now, err) |