⚙️ Как настроить торгового телеграм-бота для отображения торговых индикаторов
Индикаторы помогают трейдеру глубже анализировать рынок и принимать более эффективные решения в торговле. В этой статье разберем, как реализовать отображение самых популярных индикаторов на ценовом графике с помощью телеграм-бота — чтобы автоматизировать анализ, правильнее определять тренды и точнее отслеживать движение цен.
Определяем типы индикаторов
Мы будем использовать для анализа через бота эти индикаторы:
- 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
Реализация отображения индикаторов: подготовительный этап
Создаем токен для телеграм-бота:
TOKEN = os.environ.get('TOKEN')
Данные получаем с помощью API от сервиса bybit.com:
PATH = 'https://api.bybit.com/'
ENDPOINT = '/v5/market/kline'
URL = PATH + ENDPOINT
Добавляем список инструментов:
SYMBOLS = ['BTCUSDT', 'ETHUSDT', 'BTCPERP', 'ETHPERP',
'BTCUSD', 'ETHUSD', 'BTCUSDT',
'XRPUSDT', 'BNBUSDT', 'DOGEUSDT', 'GMTUSDT']
Добавляем список графиков:
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']
Добавляем список интервалов:
INTERVALS = [1, 3, 5, 15, 30, 60, 120,
240, 360, 720, 'D', 'W', 'M']
Добавляем словарь расшифровок и терминов:
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',
Создаем бота:
bot = telebot.TeleBot(TOKEN)
Создаем функцию для отправки инструкции по формированию запроса после запуска бота командой /start:
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)
Создаем функцию для проверки наличия запроса со стороны пользователя:
request = message.text.split()
if request:
return True
else:
return False
Создаем функцию для выдачи результата на основе информации, запрошенной пользователем:
Получение содержания запроса пользователя:
request = message.text.split()
Текущее время для отображения в ответе пользователю:
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
Проверка наличия в запросе типа графика 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
Проверка наличия в запросе типа графика 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
Проверка наличия в запросе типа графика 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
Проверка наличия в запросе типа графика 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
Проверка наличия в запросе типа графика 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
Проверка наличия в запросе типа графика 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
Проверка наличия в запросе типа графика 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)
Дашборд из трех графиков
Проверка наличия в запросе дашборда из 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
Проверка наличия в запросе графика 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)
Дополнительные функции
Отправка сообщения об ошибке в случае некорректного ввода данных:
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)