""" πŸ“± TELEGRAM NOTIFIER - Mobile Trading Notifications Sendet Trade Updates, Performance Reports und Alerts FEATURES: - Trade Entry/Exit Notifications - Daily/Weekly Performance Reports - Error Alerts - Bot Status Updates - Custom Commands (/status, /report) """ import requests import json from datetime import datetime, timedelta from typing import Dict, List, Optional import os class TelegramNotifier: """ Telegram Bot Integration fΓΌr Trading Notifications """ def __init__(self, bot_token: str, chat_id: str): """ Initialize Telegram Bot Args: bot_token: Telegram Bot Token (von @BotFather) chat_id: Telegram Chat ID (deine User ID) """ self.bot_token = bot_token self.chat_id = chat_id self.base_url = f"https://api.telegram.org/bot{bot_token}" # Test connection self._test_connection() def _test_connection(self): """Test Telegram API connection""" try: response = requests.get(f"{self.base_url}/getMe", timeout=5) if response.status_code == 200: bot_info = response.json() print(f"βœ… Telegram Bot connected: @{bot_info['result']['username']}") else: print(f"⚠️ Telegram connection issue: {response.status_code}") except Exception as e: print(f"❌ Telegram connection failed: {e}") def send_message(self, text: str, parse_mode: str = "Markdown") -> bool: """ Send a text message to Telegram Args: text: Message text (supports Markdown) parse_mode: 'Markdown' or 'HTML' Returns: True if successful, False otherwise """ try: url = f"{self.base_url}/sendMessage" payload = { 'chat_id': self.chat_id, 'text': text, 'parse_mode': parse_mode, 'disable_web_page_preview': True } response = requests.post(url, json=payload, timeout=10) if response.status_code == 200: return True else: print(f"⚠️ Telegram send failed: {response.status_code}") return False except Exception as e: print(f"❌ Telegram error: {e}") return False # ========================================== # TRADE NOTIFICATIONS # ========================================== def notify_trade_entry(self, trade_data: Dict): """ Notify about new trade entry Args: trade_data: Dictionary with trade information """ type_emoji = "🟒" if trade_data['type'] == 'BUY' else "πŸ”΄" session_emoji = self._get_session_emoji(trade_data.get('session', 'unknown')) message = f""" {type_emoji} *Trade Opened* *Symbol:* {trade_data['symbol']} *Type:* {trade_data['type']} *Entry:* {trade_data['entry_price']} *SL:* {trade_data.get('sl_price', 'N/A')} | *TP:* {trade_data.get('tp_price', 'N/A')} *Risk:* ${trade_data.get('risk_amount', 0):.2f} ({trade_data.get('risk_pct', 0)*100:.1f}%) *Volume:* {trade_data.get('volume', 0)} lots {session_emoji} *Session:* {trade_data.get('session', 'unknown').upper()} πŸ“Š *Confidence:* {trade_data.get('confidence', 0):.1f}% 🎯 *Quality:* {trade_data.get('quality', 'unknown').upper()} ⏰ {datetime.now().strftime('%Y-%m-%d %H:%M:%S')} UTC """ self.send_message(message) def notify_trade_exit(self, trade_data: Dict): """ Notify about trade exit Args: trade_data: Dictionary with trade and exit information """ profit = trade_data.get('net_profit', 0) profit_emoji = "βœ…" if profit > 0 else "❌" type_emoji = "🟒" if trade_data['type'] == 'BUY' else "πŸ”΄" # Format profit/loss profit_text = f"+${profit:.2f}" if profit > 0 else f"${profit:.2f}" message = f""" {profit_emoji} *Trade Closed* {type_emoji} *Symbol:* {trade_data['symbol']} *Type:* {trade_data['type']} *Entry:* {trade_data['entry_price']} *Exit:* {trade_data.get('exit_price', 'N/A')} *Profit:* {profit_text} *Duration:* {trade_data.get('duration_hours', 0):.1f}h *Exit Reason:* {trade_data.get('exit_reason', 'unknown').upper()} *R:R Ratio:* {trade_data.get('rr_ratio', 0):.2f} ⏰ {datetime.now().strftime('%Y-%m-%d %H:%M:%S')} UTC """ self.send_message(message) # ========================================== # PERFORMANCE REPORTS # ========================================== def send_daily_report(self, stats: Dict): """ Send daily performance summary Args: stats: Dictionary with daily statistics """ win_rate = stats.get('win_rate', 0) net_profit = stats.get('net_profit', 0) # Emojis based on performance profit_emoji = "πŸ’°" if net_profit > 0 else "πŸ“‰" wr_emoji = "🎯" if win_rate >= 50 else "⚠️" if win_rate >= 40 else "πŸ”΄" message = f""" πŸ“Š *Daily Trading Report* πŸ“… {datetime.now().strftime('%Y-%m-%d')} ━━━━━━━━━━━━━━━━━━━━ *Trades:* {stats.get('total_trades', 0)} *Wins:* {stats.get('wins', 0)} | *Losses:* {stats.get('losses', 0)} {wr_emoji} *Win Rate:* {win_rate:.1f}% {profit_emoji} *Net Profit:* ${net_profit:.2f} *Gross Profit:* ${stats.get('gross_profit', 0):.2f} *Gross Loss:* ${stats.get('gross_loss', 0):.2f} *Avg Trade:* ${stats.get('avg_trade', 0):.2f} ━━━━━━━━━━━━━━━━━━━━ βœ… Bot Status: Running """ self.send_message(message) def send_weekly_report(self, stats: Dict, session_perf: Dict = None): """ Send weekly performance summary Args: stats: Dictionary with weekly statistics session_perf: Optional session performance breakdown """ win_rate = stats.get('win_rate', 0) net_profit = stats.get('net_profit', 0) profit_factor = stats.get('profit_factor', 0) # Emojis profit_emoji = "πŸ’°" if net_profit > 0 else "πŸ“‰" pf_emoji = "🟒" if profit_factor >= 1.5 else "🟑" if profit_factor >= 1.2 else "πŸ”΄" message = f""" πŸ“ˆ *Weekly Trading Report* πŸ“… {(datetime.now() - timedelta(days=7)).strftime('%Y-%m-%d')} to {datetime.now().strftime('%Y-%m-%d')} ━━━━━━━━━━━━━━━━━━━━ πŸ“Š *Overall Performance* *Total Trades:* {stats.get('total_trades', 0)} *Wins:* {stats.get('wins', 0)} | *Losses:* {stats.get('losses', 0)} *Win Rate:* {win_rate:.1f}% {profit_emoji} *Net Profit:* ${net_profit:.2f} {pf_emoji} *Profit Factor:* {profit_factor:.2f} *Avg Trade:* ${stats.get('avg_trade', 0):.2f} ━━━━━━━━━━━━━━━━━━━━ """ # Add session breakdown if available if session_perf: message += "\nπŸ“ *Session Performance*\n\n" # Sort sessions by profit sorted_sessions = sorted( session_perf.items(), key=lambda x: x[1].get('total_profit', 0), reverse=True ) for session, data in sorted_sessions: session_emoji = self._get_session_emoji(session) profit = data.get('total_profit', 0) wr = data.get('win_rate', 0) profit_text = f"+${profit:.2f}" if profit > 0 else f"${profit:.2f}" status = "βœ…" if profit > 0 else "❌" message += f"{session_emoji} *{session.upper()}:* {profit_text} ({wr:.1f}% WR) {status}\n" message += "\n━━━━━━━━━━━━━━━━━━━━\nβœ… Bot Status: Running" self.send_message(message) # ========================================== # ALERTS & STATUS # ========================================== def send_error_alert(self, error_message: str, context: str = ""): """ Send error alert Args: error_message: Error description context: Additional context """ message = f""" 🚨 *ERROR ALERT* *Time:* {datetime.now().strftime('%Y-%m-%d %H:%M:%S')} UTC *Error:* {error_message} {f'*Context:* {context}' if context else ''} ⚠️ Please check the bot! """ self.send_message(message) def send_bot_started(self, config: Dict): """ Notify when bot starts Args: config: Bot configuration """ active_sessions = [s for s, enabled in config.get('enabled_sessions', {}).items() if enabled] message = f""" πŸš€ *TradingBot Started* *Version:* {config.get('version', 'V1.8')} *Time:* {datetime.now().strftime('%Y-%m-%d %H:%M:%S')} UTC βš™οΈ *Configuration:* *Active Sessions:* {', '.join(s.upper() for s in active_sessions)} *Confidence Threshold:* {config.get('base_confidence', 60)}% *Max Risk/Trade:* {config.get('max_risk_per_trade', 0.01)*100:.1f}% βœ… Bot is now monitoring the market """ self.send_message(message) def send_bot_stopped(self, reason: str = "Manual stop"): """ Notify when bot stops Args: reason: Stop reason """ message = f""" ⏸️ *TradingBot Stopped* *Time:* {datetime.now().strftime('%Y-%m-%d %H:%M:%S')} UTC *Reason:* {reason} ℹ️ Bot has stopped trading """ self.send_message(message) def send_session_blocked(self, session: str, reason: str): """ Notify when a trading session is blocked Args: session: Session name reason: Block reason """ session_emoji = self._get_session_emoji(session) message = f""" ⏸️ *Trading Skipped* {session_emoji} *Session:* {session.upper()} *Reason:* {reason} πŸ’‘ Bot is waiting for allowed session """ # Only send if debug mode (optional - can be noisy) # self.send_message(message) # ========================================== # BOT COMMANDS (Optional - for interactive use) # ========================================== def handle_command(self, command: str, db) -> str: """ Handle Telegram bot commands Args: command: Command string (e.g., '/status', '/report') db: TradingDatabase instance Returns: Response message """ if command == '/status': return self._cmd_status(db) elif command == '/report': return self._cmd_report(db) elif command == '/today': return self._cmd_today(db) elif command == '/help': return self._cmd_help() else: return "Unknown command. Use /help for available commands." def _cmd_status(self, db) -> str: """Get bot status""" open_positions = db.get_open_positions() stats = db.get_overall_statistics(days=7) return f""" πŸ“Š *Bot Status* *Open Positions:* {len(open_positions)} *7-Day Win Rate:* {stats.get('win_rate', 0):.1f}% *7-Day Profit:* ${stats.get('net_profit', 0):.2f} βœ… Bot is running """ def _cmd_report(self, db) -> str: """Get performance report""" stats = db.get_overall_statistics(days=7) self.send_weekly_report(stats) return "Report sent!" def _cmd_today(self, db) -> str: """Get today's summary""" stats = db.get_daily_summary() self.send_daily_report(stats) return "Today's report sent!" def _cmd_help(self) -> str: """Get help text""" return """ πŸ“š *Available Commands* /status - Bot status & open positions /report - Weekly performance report /today - Today's summary /help - Show this help Bot will automatically send: β€’ Trade entry/exit notifications β€’ Daily reports (22:00 UTC) β€’ Error alerts """ # ========================================== # HELPER FUNCTIONS # ========================================== def _get_session_emoji(self, session: str) -> str: """Get emoji for session""" emojis = { 'asian': 'πŸŒ™', 'london': 'πŸ‡¬πŸ‡§', 'overlap': 'πŸ”„', 'ny': 'πŸ‡ΊπŸ‡Έ' } return emojis.get(session.lower(), '❓') # ========================================== # CONFIGURATION # ========================================== def load_telegram_config() -> Dict: """ Load Telegram configuration from file or environment Returns: Dictionary with bot_token and chat_id """ # Try to load from config file config_file = "telegram_config.json" if os.path.exists(config_file): with open(config_file, 'r') as f: return json.load(f) # Try environment variables bot_token = os.getenv('TELEGRAM_BOT_TOKEN') chat_id = os.getenv('TELEGRAM_CHAT_ID') if bot_token and chat_id: return { 'bot_token': bot_token, 'chat_id': chat_id } # Return empty config if nothing found return {} def create_telegram_config_template(): """Create template configuration file""" template = { "bot_token": "YOUR_BOT_TOKEN_HERE", "chat_id": "YOUR_CHAT_ID_HERE", "notifications": { "trade_entry": True, "trade_exit": True, "daily_report": True, "weekly_report": True, "error_alerts": True }, "daily_report_time": "22:00", # UTC "weekly_report_day": "Sunday" } with open('telegram_config_template.json', 'w') as f: json.dump(template, f, indent=2) print("βœ… Created telegram_config_template.json") print("πŸ“ Edit this file and rename to telegram_config.json") # ========================================== # USAGE EXAMPLE # ========================================== if __name__ == "__main__": print("="*70) print("πŸ“± TELEGRAM NOTIFIER - Setup") print("="*70) # Create config template create_telegram_config_template() print(""" πŸ“‹ Setup Instructions: 1. Create Telegram Bot: - Open Telegram and search for @BotFather - Send /newbot and follow instructions - Copy the Bot Token 2. Get your Chat ID: - Search for @userinfobot in Telegram - Send /start - Copy your User ID 3. Configure: - Edit telegram_config_template.json - Add your bot_token and chat_id - Rename to telegram_config.json 4. Test: - Run this script again to test connection Example Usage: ```python from telegram_notifier import TelegramNotifier # Initialize notifier = TelegramNotifier( bot_token='YOUR_BOT_TOKEN', chat_id='YOUR_CHAT_ID' ) # Send trade notification notifier.notify_trade_entry({ 'symbol': 'XAUUSD', 'type': 'BUY', 'entry_price': 2650.00, 'sl_price': 2645.00, 'tp_price': 2660.00, 'session': 'ny', 'confidence': 75.5 }) ``` """) print("="*70)