Files
Place-Order-Trading-Bot/telegram_notifier.py
T

552 lines
15 KiB
Python
Raw Normal View History

"""
📱 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)