У меня есть скрипт для отбора криптовалют. На рынке две фазы движения цены : Фаза импульса и фаза накоплени(фаза баланса), я торгую исключительно в фазе баланса, нужно достоверно определить фазу рынка и оставить фазу баланса, подключить все фьючерсы бинанс,  с помощью не менее 5 лучших индикаторов для фазы баланса определить точку входа и тейк и понятно визуализировать на графике import logging
import requests
import pandas as pd
import mplfinance as mpf
from datetime import datetime, timedelta, timezone
import telegram
import asyncio
import config

# Настройка логирования
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s',
    handlers=[
        logging.FileHandler("bot.log"),
        logging.StreamHandler()
    ]
)


# Функция для получения данных от Binance
def get_historical_klines(symbol, interval, hours):
    try:
        logging.info(f"Запрос данных для {symbol} с интервалом {interval} за последние {hours} часов.")
        end_time = datetime.now(timezone.utc)
        start_time = end_time - timedelta(hours=hours)
        start_timestamp = int(start_time.timestamp() * 1000)
        end_timestamp = int(end_time.timestamp() * 1000)
        url = 'https://api.binance.com/api/v3/klines'
        params = {
            'symbol': symbol,
            'interval': interval,
            'startTime': start_timestamp,
            'endTime': end_timestamp
        }
        response = requests.get(url, params=params)
        response.raise_for_status()
        data = response.json()
        df = pd.DataFrame(data, columns=[
            'Open time', 'Open', 'High', 'Low', 'Close', 'Volume',
            'Close time', 'Quote asset volume', 'Number of trades',
            'Taker buy base asset volume', 'Taker buy quote asset volume', 'Ignore'
        ])
        df['Open time'] = pd.to_datetime(df['Open time'], unit='ms')
        df['Close time'] = pd.to_datetime(df['Close time'], unit='ms')
        df[['Open', 'High', 'Low', 'Close', 'Volume']] = df[['Open', 'High', 'Low', 'Close', 'Volume']].astype(float)
        logging.info("Данные успешно получены.")
        return df[['Open time', 'Open', 'High', 'Low', 'Close', 'Volume']]
    except requests.exceptions.RequestException as e:
        logging.error(f"Ошибка при запросе данных: {e}")
        raise
    except Exception as e:
        logging.error(f"Неизвестная ошибка при обработке данных: {e}")
        raise


# Функция для построения графика
def plot_candlestick(df, symbol):
    try:
        logging.info("Построение графика свечей.")
        df.set_index('Open time', inplace=True)
        mc = mpf.make_marketcolors(up='g', down='r', inherit=True)
        s = mpf.make_mpf_style(marketcolors=mc)
        filename = f"{symbol}_72h.png"
        mpf.plot(
            df,
            type='candle',
            style=s,
            title=f'{symbol} - Last 72 Hours',
            ylabel='Price (USDT)',
            volume=True,
            savefig=filename
        )
        logging.info(f"График сохранен как {filename}.")
        return filename
    except Exception as e:
        logging.error(f"Ошибка при построении графика: {e}")
        raise


# Асинхронная функция для отправки сообщения в Telegram
async def send_telegram_message(token, chat_id, text, image_path):
    try:
        logging.info("Отправка сообщения в Telegram.")
        bot = telegram.Bot(token=token)
        await bot.send_message(chat_id=chat_id, text=text)
        with open(image_path, 'rb') as photo:
            await bot.send_photo(chat_id=chat_id, photo=photo)
        logging.info("Сообщение успешно отправлено.")
    except telegram.error.TelegramError as e:
        logging.error(f"Ошибка Telegram: {e}")
        raise
    except Exception as e:
        logging.error(f"Неизвестная ошибка при отправке сообщения: {e}")
        raise


async def main():
    try:
        symbol = 'FTMUSDT'
        interval = '1h'
        hours = 72
        logging.info("Запуск основного процесса.")

        df = get_historical_klines(symbol, interval, hours)
        image_path = plot_candlestick(df, symbol)
        message = f"Отчет по {symbol} за последние {hours} часов."
        await send_telegram_message(config.TELEGRAM_TOKEN, config.CHAT_ID, message, image_path)

        logging.info("Процесс завершен успешно.")
    except Exception as e:
        logging.error(f"Процесс завершился с ошибкой: {e}")


if __name__ == '__main__':
    asyncio.run(main())