Open chingybrooks opened 1 day ago
Для улучшения и дополнения Telegram-бота, который отслеживает касания уровня MA 99 и MA 200, можно внести несколько изменений и добавить новые функции. Вот несколько идей:
config.py
, используйте переменные окружения (environment variables
). Это повысит безопасность данных..env
файла с использованием библиотеки python-dotenv
:Установка библиотеки:
pip install python-dotenv
Пример обновленного config.py
:
import os
from dotenv import load_dotenv
load_dotenv() # Загружаем переменные окружения из .env файла
TELEGRAM_TOKEN = os.getenv('TELEGRAM_TOKEN')
CHAT_ID = os.getenv('CHAT_ID')
BINANCE_API_KEY = os.getenv('BINANCE_API_KEY')
BINANCE_API_SECRET = os.getenv('BINANCE_API_SECRET')
Создайте .env
файл:
TELEGRAM_TOKEN=ваш_токен_бота
CHAT_ID=ID_чата_или_канала
BINANCE_API_KEY=ваш_бинанс_API_ключ
BINANCE_API_SECRET=ваш_бинанс_секретный_ключ
logging
, чтобы сохранять ошибки или важные события в файл или выводить в консоль:Пример логирования:
import logging
# Настройка логирования
logging.basicConfig(level=logging.INFO, filename='bot.log', filemode='a',
format='%(asctime)s - %(levelname)s - %(message)s')
# Используйте logging для сообщений:
logging.info(f"Цена {symbol} коснулась уровня MA 99: {ma_99}")
logging.error(f"Ошибка при получении данных: {e}")
1h
, 4h
, 1d
) через команды бота. Добавьте обработчики команд для изменения интервалов или добавления новых пар.Пример кода для изменения интервалов:
@bot.message_handler(commands=['set_interval'])
def set_interval(message):
interval = message.text.split()[1] # Например, '/set_interval 4h'
if interval in ['1m', '5m', '15m', '1h', '4h', '1d']:
global INTERVAL
INTERVAL = interval
bot.send_message(config.CHAT_ID, f"Интервал изменен на {interval}")
else:
bot.send_message(config.CHAT_ID, "Некорректный интервал. Используйте '1m', '5m', '15m', '1h', '4h', '1d'.")
try:
# Ваш основной код
except Exception as e:
bot.send_message(config.CHAT_ID, f"Ошибка в работе бота: {e}")
logging.error(f"Ошибка: {e}")
matplotlib
или plotly
и отправлять изображения графиков в Telegram. Это поможет визуализировать касания MA.Пример использования matplotlib
:
import matplotlib.pyplot as plt
def plot_price_and_ma(symbol, interval='1h'):
klines = client.get_klines(symbol=symbol, interval=interval, limit=200)
close_prices = [float(kline[4]) for kline in klines]
timestamps = [kline[0] for kline in klines]
ma_99 = np.convolve(close_prices, np.ones(99)/99, mode='valid')
ma_200 = np.convolve(close_prices, np.ones(200)/200, mode='valid')
plt.figure(figsize=(10, 5))
plt.plot(close_prices, label='Цена', color='blue')
plt.plot(range(98, len(ma_99) + 98), ma_99, label='MA 99', color='green')
plt.plot(range(199, len(ma_200) + 199), ma_200, label='MA 200', color='red')
plt.title(f'{symbol} {interval}')
plt.legend()
plt.savefig('chart.png')
# Отправка графика в Telegram
with open('chart.png', 'rb') as photo:
bot.send_photo(config.CHAT_ID, photo)
Пример создания таблицы в SQLite:
import sqlite3
# Подключение к базе данных SQLite
conn = sqlite3.connect('crypto_data.db')
cursor = conn.cursor()
# Создание таблицы для хранения касаний MA
cursor.execute('''
CREATE TABLE IF NOT EXISTS ma_touches (
id INTEGER PRIMARY KEY,
symbol TEXT,
ma_level TEXT,
touch_time TIMESTAMP,
price REAL
)
''')
conn.commit()
# Сохранение данных
def save_ma_touch(symbol, ma_level, touch_time, price):
cursor.execute('INSERT INTO ma_touches (symbol, ma_level, touch_time, price) VALUES (?, ?, ?, ?)',
(symbol, ma_level, touch_time, price))
conn.commit()
/report
, чтобы бот мог выводить статистику по количеству касаний за определенный период.Вот обновленный код с добавленными улучшениями, исключая построение графиков и базу данных. Мы добавим управление конфигурацией через .env
, улучшенное логирование, поддержку нескольких временных интервалов, гибкие пороги для касания MA, а также обработку исключений.
Убедитесь, что у вас установлены следующие библиотеки:
pip install python-binance pyTelegramBotAPI python-dotenv numpy
Файл .env
:
Создайте файл .env
в корне проекта:
TELEGRAM_TOKEN=ваш_токен_бота
CHAT_ID=ID_чата_или_канала
BINANCE_API_KEY=ваш_бинанс_API_ключ
BINANCE_API_SECRET=ваш_бинанс_секретный_ключ
Файл config.py
:
import os
from dotenv import load_dotenv
load_dotenv() # Загружаем переменные окружения из .env файла
TELEGRAM_TOKEN = os.getenv('TELEGRAM_TOKEN')
CHAT_ID = os.getenv('CHAT_ID')
BINANCE_API_KEY = os.getenv('BINANCE_API_KEY')
BINANCE_API_SECRET = os.getenv('BINANCE_API_SECRET')
import time
import config
import telebot
from binance.client import Client
from binance.exceptions import BinanceAPIException
import numpy as np
import logging
# Настройка логирования
logging.basicConfig(level=logging.INFO, filename='bot.log', filemode='a',
format='%(asctime)s - %(levelname)s - %(message)s')
# Инициализация клиента Binance и Telegram бота
client = Client(config.BINANCE_API_KEY, config.BINANCE_API_SECRET)
bot = telebot.TeleBot(config.TELEGRAM_TOKEN)
# Глобальные настройки
INTERVAL = '1h' # Начальный интервал
TOUCH_PRECISION = 0.01 # Порог чувствительности для касания MA (1%)
# Функция для расчета скользящей средней
def get_moving_average(symbol, interval, window):
try:
klines = client.get_klines(symbol=symbol, interval=interval, limit=window)
close_prices = [float(kline[4]) for kline in klines] # Извлекаем цены закрытия
return np.mean(close_prices)
except BinanceAPIException as e:
logging.error(f"Ошибка при получении данных с Binance: {e}")
return None
# Функция для проверки касания уровня MA
def check_touch(symbol):
ma_99 = get_moving_average(symbol, INTERVAL, 99)
ma_200 = get_moving_average(symbol, INTERVAL, 200)
if ma_99 is None or ma_200 is None:
return
try:
current_price = float(client.get_symbol_ticker(symbol=symbol)['price'])
if abs(current_price - ma_99) / ma_99 <= TOUCH_PRECISION:
message = f"{symbol}: Цена коснулась уровня MA 99 ({ma_99}). Текущая цена: {current_price}"
bot.send_message(config.CHAT_ID, message)
logging.info(message)
if abs(current_price - ma_200) / ma_200 <= TOUCH_PRECISION:
message = f"{symbol}: Цена коснулась уровня MA 200 ({ma_200}). Текущая цена: {current_price}"
bot.send_message(config.CHAT_ID, message)
logging.info(message)
except BinanceAPIException as e:
logging.error(f"Ошибка при получении текущей цены: {e}")
# Обработчик команды для изменения интервала
@bot.message_handler(commands=['set_interval'])
def set_interval(message):
global INTERVAL
interval = message.text.split()[1] # Например, '/set_interval 4h'
if interval in ['1m', '5m', '15m', '1h', '4h', '1d']:
INTERVAL = interval
response = f"Интервал изменен на {interval}"
bot.send_message(config.CHAT_ID, response)
logging.info(response)
else:
bot.send_message(config.CHAT_ID, "Некорректный интервал. Используйте '1m', '5m', '15m', '1h', '4h', '1d'.")
# Обработчик команды для изменения порога касания MA
@bot.message_handler(commands=['set_precision'])
def set_precision(message):
global TOUCH_PRECISION
try:
precision = float(message.text.split()[1]) # Например, '/set_precision 0.02' для 2%
if 0 < precision < 0.1: # Устанавливаем допустимые пределы от 0% до 10%
TOUCH_PRECISION = precision
response = f"Порог точности изменен на {precision * 100}%"
bot.send_message(config.CHAT_ID, response)
logging.info(response)
else:
bot.send_message(config.CHAT_ID, "Порог должен быть между 0.1% и 10%.")
except ValueError:
bot.send_message(config.CHAT_ID, "Введите корректное число для порога точности (например, 0.02 для 2%).")
# Основной цикл
def main():
symbols = ['BTCUSDT', 'ETHUSDT', 'BNBUSDT'] # Укажите монеты, которые хотите отслеживать
while True:
try:
for symbol in symbols:
check_touch(symbol)
time.sleep(300) # Проверка каждые 5 минут
except Exception as e:
logging.error(f"Неожиданная ошибка в основном цикле: {e}")
bot.send_message(config.CHAT_ID, f"Ошибка в работе бота: {e}")
time.sleep(60) # Задержка в случае ошибки, чтобы избежать частых повторений
if __name__ == "__main__":
bot.polling(none_stop=True) # Запуск бота для обработки команд
main()
.env
— API ключи и другие конфигурационные параметры теперь хранятся в .env
, что безопаснее.logging
для сохранения событий, ошибок и другой информации в лог-файл./set_interval
, позволяющая менять временной интервал для анализа MA прямо через Telegram./set_precision
, позволяющая изменять порог чувствительности касания MA./set_interval <интервал>
— изменить временной интервал (например, /set_interval 4h
)./set_precision <точность>
— изменить порог чувствительности (например, /set_precision 0.02
для 2%).Запустите скрипт командой:
python ваш_скрипт.py
Теперь бот готов к использованию, и вы сможете управлять его параметрами через Telegram-команды.
Вот обновленный код с вашим уточнением для начального интервала 4h
, допустимых интервалов (1h
, 4h
, 1d
, 1w
) и измененной задержки для проверки каждые 30 минут:
import time
import config
import telebot
from binance.client import Client
from binance.exceptions import BinanceAPIException
import numpy as np
import logging
# Настройка логирования
logging.basicConfig(level=logging.INFO, filename='bot.log', filemode='a',
format='%(asctime)s - %(levelname)s - %(message)s')
# Инициализация клиента Binance и Telegram бота
client = Client(config.BINANCE_API_KEY, config.BINANCE_API_SECRET)
bot = telebot.TeleBot(config.TELEGRAM_TOKEN)
# Глобальные настройки
INTERVAL = '4h' # Начальный интервал
TOUCH_PRECISION = 0.01 # Порог чувствительности для касания MA (1%)
# Функция для расчета скользящей средней
def get_moving_average(symbol, interval, window):
try:
klines = client.get_klines(symbol=symbol, interval=interval, limit=window)
close_prices = [float(kline[4]) for kline in klines] # Извлекаем цены закрытия
return np.mean(close_prices)
except BinanceAPIException as e:
logging.error(f"Ошибка при получении данных с Binance: {e}")
return None
# Функция для проверки касания уровня MA
def check_touch(symbol):
ma_99 = get_moving_average(symbol, INTERVAL, 99)
ma_200 = get_moving_average(symbol, INTERVAL, 200)
if ma_99 is None or ma_200 is None:
return
try:
current_price = float(client.get_symbol_ticker(symbol=symbol)['price'])
if abs(current_price - ma_99) / ma_99 <= TOUCH_PRECISION:
message = f"{symbol}: Цена коснулась уровня MA 99 ({ma_99}). Текущая цена: {current_price}"
bot.send_message(config.CHAT_ID, message)
logging.info(message)
if abs(current_price - ma_200) / ma_200 <= TOUCH_PRECISION:
message = f"{symbol}: Цена коснулась уровня MA 200 ({ma_200}). Текущая цена: {current_price}"
bot.send_message(config.CHAT_ID, message)
logging.info(message)
except BinanceAPIException as e:
logging.error(f"Ошибка при получении текущей цены: {e}")
# Обработчик команды для изменения интервала
@bot.message_handler(commands=['set_interval'])
def set_interval(message):
global INTERVAL
interval = message.text.split()[1] # Например, '/set_interval 4h'
if interval in ['1h', '4h', '1d', '1w']:
INTERVAL = interval
response = f"Интервал изменен на {interval}"
bot.send_message(config.CHAT_ID, response)
logging.info(response)
else:
bot.send_message(config.CHAT_ID, "Некорректный интервал. Используйте '1h', '4h', '1d', '1w'.")
# Обработчик команды для изменения порога касания MA
@bot.message_handler(commands=['set_precision'])
def set_precision(message):
global TOUCH_PRECISION
try:
precision = float(message.text.split()[1]) # Например, '/set_precision 0.02' для 2%
if 0 < precision < 0.1: # Устанавливаем допустимые пределы от 0.1% до 10%
TOUCH_PRECISION = precision
response = f"Порог точности изменен на {precision * 100}%"
bot.send_message(config.CHAT_ID, response)
logging.info(response)
else:
bot.send_message(config.CHAT_ID, "Порог должен быть между 0.1% и 10%.")
except ValueError:
bot.send_message(config.CHAT_ID, "Введите корректное число для порога точности (например, 0.02 для 2%).")
# Основной цикл
def main():
symbols = ['BTCUSDT', 'ETHUSDT', 'BNBUSDT'] # Укажите монеты, которые хотите отслеживать
while True:
try:
for symbol in symbols:
check_touch(symbol)
time.sleep(1800) # Проверка каждые 30 минут (1800 секунд)
except Exception as e:
logging.error(f"Неожиданная ошибка в основном цикле: {e}")
bot.send_message(config.CHAT_ID, f"Ошибка в работе бота: {e}")
time.sleep(60) # Задержка в случае ошибки, чтобы избежать частых повторений
if __name__ == "__main__":
bot.polling(none_stop=True) # Запуск бота для обработки команд
main()
4h
./set_interval
ограничены значениями '1h'
, '4h'
, '1d'
, и '1w'
.time.sleep(1800)
.Теперь бот будет проверять касание уровней MA каждые 30 минут и позволит вам гибко изменять интервал анализа через команду /set_interval
.
Для того чтобы отслеживать топ-200 монет без стейблкоинов, необходимо получить список монет с Binance и исключить из него стейблкоины (например, USDT, BUSD, USDC и другие).
Ниже приведен код, который автоматически загружает топ-200 криптовалют (без стейблкоинов) с Binance и использует их в основном цикле:
import time
import config
import telebot
from binance.client import Client
from binance.exceptions import BinanceAPIException
import numpy as np
import logging
# Настройка логирования
logging.basicConfig(level=logging.INFO, filename='bot.log', filemode='a',
format='%(asctime)s - %(levelname)s - %(message)s')
# Инициализация клиента Binance и Telegram бота
client = Client(config.BINANCE_API_KEY, config.BINANCE_API_SECRET)
bot = telebot.TeleBot(config.TELEGRAM_TOKEN)
# Глобальные настройки
INTERVAL = '4h' # Начальный интервал
TOUCH_PRECISION = 0.01 # Порог чувствительности для касания MA (1%)
EXCLUDED_SYMBOLS = ['USDT', 'BUSD', 'USDC', 'DAI', 'TUSD', 'PAX', 'GUSD', 'USDP', 'SUSD', 'UST'] # Исключаем стейблкоины
# Функция для получения топ-200 монет без стейблкоинов
def get_top_200_symbols():
try:
# Получение списка всех торговых пар
tickers = client.get_ticker()
symbols = []
# Фильтрация топ-200 пар и исключение стейблкоинов
for ticker in tickers:
symbol = ticker['symbol']
# Проверка на стейблкоин (исключаем пары, содержащие стейблкоины)
if any(stable in symbol for stable in EXCLUDED_SYMBOLS):
continue
# Проверяем, что пара торгуется к USDT (или другим крупным рынкам)
if symbol.endswith('USDT'):
symbols.append(symbol)
# Ограничиваем список топ-200
return sorted(symbols, key=lambda s: float(client.get_symbol_ticker(symbol=s)['price']), reverse=True)[:200]
except BinanceAPIException as e:
logging.error(f"Ошибка при получении топ-200 монет: {e}")
return []
# Функция для расчета скользящей средней
def get_moving_average(symbol, interval, window):
try:
klines = client.get_klines(symbol=symbol, interval=interval, limit=window)
close_prices = [float(kline[4]) for kline in klines] # Извлекаем цены закрытия
return np.mean(close_prices)
except BinanceAPIException as e:
logging.error(f"Ошибка при получении данных с Binance: {e}")
return None
# Функция для проверки касания уровня MA
def check_touch(symbol):
ma_99 = get_moving_average(symbol, INTERVAL, 99)
ma_200 = get_moving_average(symbol, INTERVAL, 200)
if ma_99 is None or ma_200 is None:
return
try:
current_price = float(client.get_symbol_ticker(symbol=symbol)['price'])
if abs(current_price - ma_99) / ma_99 <= TOUCH_PRECISION:
message = f"{symbol}: Цена коснулась уровня MA 99 ({ma_99}). Текущая цена: {current_price}"
bot.send_message(config.CHAT_ID, message)
logging.info(message)
if abs(current_price - ma_200) / ma_200 <= TOUCH_PRECISION:
message = f"{symbol}: Цена коснулась уровня MA 200 ({ma_200}). Текущая цена: {current_price}"
bot.send_message(config.CHAT_ID, message)
logging.info(message)
except BinanceAPIException as e:
logging.error(f"Ошибка при получении текущей цены: {e}")
# Обработчик команды для изменения интервала
@bot.message_handler(commands=['set_interval'])
def set_interval(message):
global INTERVAL
interval = message.text.split()[1] # Например, '/set_interval 4h'
if interval in ['1h', '4h', '1d', '1w']:
INTERVAL = interval
response = f"Интервал изменен на {interval}"
bot.send_message(config.CHAT_ID, response)
logging.info(response)
else:
bot.send_message(config.CHAT_ID, "Некорректный интервал. Используйте '1h', '4h', '1d', '1w'.")
# Обработчик команды для изменения порога касания MA
@bot.message_handler(commands=['set_precision'])
def set_precision(message):
global TOUCH_PRECISION
try:
precision = float(message.text.split()[1]) # Например, '/set_precision 0.02' для 2%
if 0 < precision < 0.1: # Устанавливаем допустимые пределы от 0.1% до 10%
TOUCH_PRECISION = precision
response = f"Порог точности изменен на {precision * 100}%"
bot.send_message(config.CHAT_ID, response)
logging.info(response)
else:
bot.send_message(config.CHAT_ID, "Порог должен быть между 0.1% и 10%.")
except ValueError:
bot.send_message(config.CHAT_ID, "Введите корректное число для порога точности (например, 0.02 для 2%).")
# Основной цикл
def main():
symbols = get_top_200_symbols() # Получаем топ-200 монет без стейблкоинов
while True:
try:
for symbol in symbols:
check_touch(symbol)
time.sleep(1800) # Проверка каждые 30 минут (1800 секунд)
except Exception as e:
logging.error(f"Неожиданная ошибка в основном цикле: {e}")
bot.send_message(config.CHAT_ID, f"Ошибка в работе бота: {e}")
time.sleep(60) # Задержка в случае ошибки, чтобы избежать частых повторений
if __name__ == "__main__":
bot.polling(none_stop=True) # Запуск бота для обработки команд
main()
Функция get_top_200_symbols
:
EXCLUDED_SYMBOLS
.Переменная EXCLUDED_SYMBOLS
:
Теперь бот будет отслеживать только топ-200 криптовалют без стейблкоинов, проверяя касание уровней MA 99 и MA 200 каждые 30 минут.
Добавлю пункты 1, 4, 7 и 9. Вот обновленный код с учетом этих дополнений:
Реализуем улучшение обработки ошибок и повторные попытки при запросах к API. Это повысит стабильность работы бота:
import logging
import time
from binance.exceptions import BinanceAPIException
# Логирование
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
# Получение MA с улучшенной обработкой ошибок
def get_moving_average(symbol, interval, window, retries=3):
attempt = 0
while attempt < retries:
try:
klines = client.get_klines(symbol=symbol, interval=interval, limit=window)
close_prices = [float(kline[4]) for kline in klines]
return np.mean(close_prices)
except BinanceAPIException as e:
logging.error(f"Ошибка при получении данных с Binance (попытка {attempt + 1}): {e}")
time.sleep(10) # Задержка перед повторной попыткой
attempt += 1
logging.error(f"Не удалось получить данные для {symbol} после {retries} попыток.")
return None
Добавим команду для настройки порога приближения к уровням MA, чтобы бот мог уведомлять, когда цена находится вблизи MA на определенный процент:
TOUCH_PRECISION = 0.01 # По умолчанию 1% приближения
@bot.message_handler(commands=['set_alert_threshold'])
def set_alert_threshold(message):
global TOUCH_PRECISION
try:
threshold = float(message.text.split()[1]) # Например, '/set_alert_threshold 0.05' для 5%
if 0 < threshold < 0.2: # Ограничение от 0.1% до 20%
TOUCH_PRECISION = threshold
response = f"Порог приближения к MA установлен на {threshold * 100}%"
bot.send_message(config.CHAT_ID, response)
logging.info(response)
else:
bot.send_message(config.CHAT_ID, "Порог должен быть между 0.1% и 20%.")
except ValueError:
bot.send_message(config.CHAT_ID, "Введите корректное число для порога (например, 0.05 для 5%).")
Добавим более детализированное логирование, чтобы записывать ошибки, уведомления и системные события отдельно. Настроим ротацию логов:
from logging.handlers import RotatingFileHandler
# Настройка ротации логов
log_handler = RotatingFileHandler('crypto_bot.log', maxBytes=5*1024*1024, backupCount=3)
log_handler.setLevel(logging.INFO)
log_handler.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(message)s'))
logger = logging.getLogger()
logger.addHandler(log_handler)
# Логирование успешных уведомлений
def log_alert(message):
logging.info(f"Отправлено уведомление: {message}")
bot.send_message(config.CHAT_ID, message)
# Пример использования логирования в функции касания MA
def check_touch(symbol):
ma_99 = get_moving_average(symbol, INTERVAL, 99)
ma_200 = get_moving_average(symbol, INTERVAL, 200)
if not ma_99 or not ma_200:
logging.error(f"Не удалось получить MA для {symbol}")
return
current_price = float(client.get_symbol_ticker(symbol=symbol)['price'])
if abs((current_price - ma_99) / ma_99) <= TOUCH_PRECISION:
message = f"Цена {symbol} коснулась MA 99: {current_price} (MA 99 = {ma_99})"
log_alert(message)
if abs((current_price - ma_200) / ma_200) <= TOUCH_PRECISION:
message = f"Цена {symbol} коснулась MA 200: {current_price} (MA 200 = {ma_200})"
log_alert(message)
Используем многопоточность для улучшения производительности при обработке списка монет:
from concurrent.futures import ThreadPoolExecutor
def main():
symbols = get_top_200_symbols() # Функция для получения топ-200 монет
while True:
try:
with ThreadPoolExecutor(max_workers=5) as executor:
executor.map(check_touch, symbols)
time.sleep(1800) # Задержка на 30 минут перед повторной проверкой
except Exception as e:
logging.error(f"Неожиданная ошибка в основном цикле: {e}")
bot.send_message(config.CHAT_ID, f"Ошибка в работе бота: {e}")
time.sleep(60)
Теперь бот:
Эти улучшения делают бота более надежным и гибким для пользователей, а также позволяют лучше отслеживать и анализировать работу бота.
Вот полный код с улучшениями, включающими обработку ошибок, уведомления по порогам, расширенное логирование и многопоточность:
import logging
import time
import numpy as np
from binance.client import Client
from binance.exceptions import BinanceAPIException
from telebot import TeleBot
from concurrent.futures import ThreadPoolExecutor
# Конфигурация
class Config:
TELEGRAM_TOKEN = 'your_telegram_token'
CHAT_ID = 'your_chat_id'
BINANCE_API_KEY = 'your_binance_api_key'
BINANCE_API_SECRET = 'your_binance_api_secret'
config = Config()
# Инициализация клиента Binance
client = Client(config.BINANCE_API_KEY, config.BINANCE_API_SECRET)
# Инициализация бота Telegram
bot = TeleBot(config.TELEGRAM_TOKEN)
# Логирование с ротацией логов
log_handler = logging.handlers.RotatingFileHandler('crypto_bot.log', maxBytes=5*1024*1024, backupCount=3)
log_handler.setLevel(logging.INFO)
log_handler.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(message)s'))
logger = logging.getLogger()
logger.addHandler(log_handler)
# Настройки
INTERVAL = '4h' # Начальный интервал
TOUCH_PRECISION = 0.01 # Порог приближения к MA (по умолчанию 1%)
# Получение MA с обработкой ошибок
def get_moving_average(symbol, interval, window, retries=3):
attempt = 0
while attempt < retries:
try:
klines = client.get_klines(symbol=symbol, interval=interval, limit=window)
close_prices = [float(kline[4]) for kline in klines]
return np.mean(close_prices)
except BinanceAPIException as e:
logging.error(f"Ошибка при получении данных с Binance (попытка {attempt + 1}): {e}")
time.sleep(10) # Задержка перед повторной попыткой
attempt += 1
logging.error(f"Не удалось получить данные для {symbol} после {retries} попыток.")
return None
# Функция для логирования уведомлений
def log_alert(message):
logging.info(f"Отправлено уведомление: {message}")
bot.send_message(config.CHAT_ID, message)
# Функция проверки касания MA
def check_touch(symbol):
ma_99 = get_moving_average(symbol, INTERVAL, 99)
ma_200 = get_moving_average(symbol, INTERVAL, 200)
if not ma_99 or not ma_200:
logging.error(f"Не удалось получить MA для {symbol}")
return
current_price = float(client.get_symbol_ticker(symbol=symbol)['price'])
if abs((current_price - ma_99) / ma_99) <= TOUCH_PRECISION:
message = f"Цена {symbol} коснулась MA 99: {current_price} (MA 99 = {ma_99})"
log_alert(message)
if abs((current_price - ma_200) / ma_200) <= TOUCH_PRECISION:
message = f"Цена {symbol} коснулась MA 200: {current_price} (MA 200 = {ma_200})"
log_alert(message)
# Команда для настройки порога
@bot.message_handler(commands=['set_alert_threshold'])
def set_alert_threshold(message):
global TOUCH_PRECISION
try:
threshold = float(message.text.split()[1]) # Например, '/set_alert_threshold 0.05' для 5%
if 0 < threshold < 0.2: # Ограничение от 0.1% до 20%
TOUCH_PRECISION = threshold
response = f"Порог приближения к MA установлен на {threshold * 100}%"
bot.send_message(config.CHAT_ID, response)
logging.info(response)
else:
bot.send_message(config.CHAT_ID, "Порог должен быть между 0.1% и 20%.")
except ValueError:
bot.send_message(config.CHAT_ID, "Введите корректное число для порога (например, 0.05 для 5%).")
# Получение списка топ-200 монет (исключая stablecoins)
def get_top_200_symbols():
# Здесь вы можете использовать API Binance для получения списка монет
# Например, получим все символы торговых пар с Binance и исключим stablecoins
all_symbols = client.get_exchange_info()['symbols']
return [symbol['symbol'] for symbol in all_symbols if symbol['status'] == 'TRADING' and not symbol['symbol'].endswith('USDT')]
# Основной цикл с многопоточностью
def main():
symbols = get_top_200_symbols() # Получаем топ-200 монет
while True:
try:
with ThreadPoolExecutor(max_workers=5) as executor:
executor.map(check_touch, symbols)
time.sleep(1800) # Задержка на 30 минут перед повторной проверкой
except Exception as e:
logging.error(f"Неожиданная ошибка в основном цикле: {e}")
bot.send_message(config.CHAT_ID, f"Ошибка в работе бота: {e}")
time.sleep(60)
if __name__ == '__main__':
main()
crypto_bot.log
, который имеет ротацию.get_top_200_symbols()
получает список монет с Binance, исключая stablecoins.Этот код теперь гораздо более устойчив и функционален для отслеживания криптовалютных цен и уведомлений по касанию уровней MA.
Чтобы создать Telegram-бота, который будет отслеживать касания криптовалютами уровней скользящих средних MA 99 и MA 200 на Binance и отправлять уведомления в Telegram, можно воспользоваться библиотеками
python-binance
иpyTelegramBotAPI
(также известная какtelebot
). Вот шаги для реализации такого бота:1. Установка библиотек
Убедитесь, что у вас установлены необходимые библиотеки:
2. Настройка конфигурации
Создайте файл
config.py
для хранения настроек:3. Код бота
Вот пример кода для Telegram-бота, который будет проверять уровни MA 99 и MA 200:
4. Описание работы кода
get_moving_average
получает последниеN
свечей и рассчитывает среднюю цену закрытия для определения скользящей средней.check_touch
проверяет, коснулась ли текущая цена уровней MA 99 или MA 200 (в пределах 1% точности).main()
проверяет заданные криптовалюты каждые 5 минут и отправляет уведомления в Telegram.5. Дополнительные настройки
symbols
.1h
,4h
,1d
и т.д.) в переменнойinterval
.Запуск
Запустите скрипт командой:
Теперь бот будет отслеживать касания уровней MA 99 и MA 200 и отправлять уведомления в ваш Telegram-канал.