Files
Place-Order-Trading-Bot/telegram_notifier.py
T
cbazzaandClaude Sonnet 4.6 4e45db967b fix: core module review fixes (signal scoring, ML, session filter, telegram, MT filter)
enhanced_signal_scoring.py:
- mt -> mt5, add logging module, replace print() with logger
- Remove no-op df['tick_volume'] = df['tick_volume'] line
- Fix RSI division-by-zero: loss.replace(0, nan) + fillna(100)

ml_signal_predictor.py:
- Remove global warnings.filterwarnings('ignore') suppression
- Fix bare except -> except Exception with logger.warning
- Add note: default data files excluded from git, need manual export
- Add pickle security warning comment

session_confidence_filter.py:
- Move imports to file top, add logging + functools.wraps
- Remove repeated AdaptiveRhythmManager() per-call instantiation
- Add functools.wraps to preserve wrapped function metadata
- Document that extended_top_down_v2_adaptive is notebook-only
- Replace print() with logger, pass **kwargs through wrapper

telegram_notifier.py:
- Remove network call from __init__ -> explicit test_connection() method
- Add logging module, replace all print() with logger calls
- Narrow exception type: Exception -> requests.RequestException
- Remove unused imports (timedelta)
- notify_trade_entry/exit now return bool from send_message

multi_timeframe_regime_filter.py:
- Change debug default from True to False in wrapper to avoid verbose production output

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-12 10:12:25 +02:00

553 lines
15 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
📱 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
import logging
from datetime import datetime
from typing import Dict, List, Optional
import os
logger = logging.getLogger(__name__)
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}"
def test_connection(self) -> bool:
"""Test Telegram API connection — call explicitly, not in __init__"""
try:
response = requests.get(f"{self.base_url}/getMe", timeout=5)
if response.status_code == 200:
username = response.json()['result']['username']
logger.info(f"Telegram Bot connected: @{username}")
return True
else:
logger.warning(f"Telegram connection issue: {response.status_code}")
return False
except requests.RequestException as e:
logger.error(f"Telegram connection failed: {e}")
return False
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:
logger.warning(f"Telegram send failed: {response.status_code}")
return False
except requests.RequestException as e:
logger.error(f"Telegram error: {e}")
return False
# ==========================================
# TRADE NOTIFICATIONS
# ==========================================
def notify_trade_entry(self, trade_data: Dict) -> bool:
"""
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
"""
return self.send_message(message)
def notify_trade_exit(self, trade_data: Dict) -> bool:
"""
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 "🔴"
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
"""
return 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)