/
Camon
/
Project
Обзор
Документация
Войти
/
Camon
/
Project
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
Project.py
156 строк
6 KB
Олег
first_commit
17 дек 2025, 16:47
17 дек 2025, 16:47
12e65d8
Код
Авторство
О чём код?
import asyncio import sqlite3 import yfinance as yf import pandas as pd from aiogram import Bot, Dispatcher, types from aiogram.filters import Command from datetime import datetime from aiogram.utils.keyboard import InlineKeyboardBuilder from aiogram import F API_TOKEN = '8467882905:AAEOCOW71gRzUK_c0s105C2aZ4PT2WiqjIw' DB_NAME = 'analytics_bot.db' ASSETS = { 'bitcoin': 'BTC-USD', 'ethereum': 'ETH-USD', 'tether': 'USDT-USD', 'binancecoin': 'BNB-USD', 'solana': 'SOL-USD', 'ripple': 'XRP-USD', 'usd-coin': 'USDC-USD', 'cardano': 'ADA-USD', 'dogecoin': 'DOGE-USD', 'tron': 'TRX-USD', 'polkadot': 'DOT-USD', 'chainlink': 'LINK-USD', 'polygon': 'MATIC-USD', 'shiba-inu': 'SHIB-USD', 'litecoin': 'LTC-USD', 'dai': 'DAI-USD', 'bitcoin-cash': 'BCH-USD', 'avalanche': 'AVAX-USD', 'uniswap': 'UNI-USD', 'stellar': 'XLM-USD', 'monero': 'XMR-USD', 'ethereum-classic': 'ETC-USD' } def init_db(): with sqlite3.connect(DB_NAME) as conn: cursor = conn.cursor() cursor.execute('CREATE TABLE IF NOT EXISTS price_history (timestamp DATETIME, asset TEXT, price REAL)') cursor.execute('CREATE TABLE IF NOT EXISTS subscriptions (user_id INTEGER, asset TEXT)') conn.commit() def get_price(asset_name): ticker_symbol = ASSETS.get(asset_name.lower()) if not ticker_symbol: return None try: data = yf.Ticker(ticker_symbol).fast_info return data['last_price'] except Exception as e: print(f"Ошибка Yahoo Finance: {e}") return None async def data_collector(): while True: for name in ASSETS.keys(): price = get_price(name) if price: with sqlite3.connect(DB_NAME) as conn: conn.execute("INSERT INTO price_history VALUES (?, ?, ?)", (datetime.now(), name, price)) print(f"Обновлено: {name} = {price:.2f}") await asyncio.sleep(300) def get_analytics(asset_name): with sqlite3.connect(DB_NAME) as conn: df = pd.read_sql_query(f"SELECT * FROM price_history WHERE asset='{asset_name}'", conn) if len(df) < 3: return "⚠️ Мало данных для анализа. Подождите пару минут..." std = df['price'].std() last_price = df['price'].iloc[-1] avg_price = df['price'].tail(5).mean() diff = (last_price - avg_price) / avg_price status = "📈 Рост" if diff > 0.01 else "📉 Падение" if diff < -0.01 else "↔️ Стабильно" return (f"📊 Актив: {asset_name.upper()}\n" f"Цена: ${last_price:.2f}\n" f"Волатильность (Std): {std:.2f}\n" f"Тренд (последние 5 зап.): {status} ({diff:.2%})") def get_all_assets_analytics(): with sqlite3.connect(DB_NAME) as conn: df = pd.read_sql_query("SELECT * FROM price_history", conn) if df.empty or len(df) < 5: return "⚠️ В базе данных пока слишком мало записей для общего анализа." now = datetime.now().strftime("%H:%M:%S") report = f"📊 ОБЩИЙ АНАЛИЗ РЫНКА ({now})\n" report += f"{'Монета':<12} | {'Цена':<9} | {'Волат.':<5}\n" report += "-" * 35 + "\n" for asset, group in df.groupby('asset'): if len(group) < 2: continue last_price = group['price'].iloc[-1] first_price = group['price'].iloc[0] change_pct = ((last_price - first_price) / first_price) * 100 std = group['price'].std() vol_str = f"{std:.2f}" if not pd.isna(std) else "0.00" emoji = "🟢" if change_pct >= 0 else "🔴" report += f"{asset.capitalize():<12} | ${last_price:<7.2f} | {emoji}{change_pct:>+5.1f}%\n" return f"```\n{report}\n```" def get_update_keyboard(): builder = InlineKeyboardBuilder() builder.row(types.InlineKeyboardButton( text="🔄 Обновить данные", callback_data="refresh_assets") ) return builder.as_markup() bot = Bot(token=API_TOKEN) dp = Dispatcher() @dp.message(Command("start")) async def cmd_start(message: types.Message): await message.answer("Бот запущен! Доступные монеты: bitcoin, ethereum, solana, ethereum, tether, binancecoin, solana, ripple',usd-coin,cardano,dogecoin,tron,polkadot,chainlink,polygon,shiba-inu,litecoin,dai,bitcoin-cash,avalanche,uniswap,stellar,monero, ethereum-classic. \nКоманда /stats даст анализ.") @dp.message(Command("stats")) async def cmd_stats(message: types.Message): report = get_all_assets_analytics() await message.answer(report, parse_mode="Markdown", reply_markup=get_update_keyboard()) @dp.callback_query(F.data == "refresh_assets") async def refresh_callback(callback: types.CallbackQuery): await callback.answer("Обновляю данные из БД...") new_report = get_all_assets_analytics() try: await callback.message.edit_text( new_report, parse_mode="Markdown", reply_markup=get_update_keyboard() ) except Exception: pass @dp.message() async def handle_message(message: types.Message): asset = message.text.lower().strip() if asset in ASSETS: price = get_price(asset) with sqlite3.connect(DB_NAME) as conn: conn.execute("INSERT INTO subscriptions VALUES (?, ?)", (message.from_user.id, asset)) await message.answer(f"Курс {asset}: ${price:.2f}\nДанные сохранены в БД для анализа.") else: await message.answer("Монета не поддерживается. Попробуй: bitcoin") async def main(): init_db() asyncio.create_task(data_collector()) await dp.start_polling(bot) if __name__ == '__main__': asyncio.run(main())