Files
Place-Order-Trading-Bot/infrastructure_patch.py
T
cbazzaandClaude Sonnet 4.6 5a204a05cd fix: equity_curve_trading, infrastructure_patch + news filter cleanup
equity_curve_trading.py:
- mt→mt5 alias in _get_current_equity()
- safe-fail: return False (block trade) when equity unavailable
- UTC timestamps via timezone.utc in update_equity()
- add_initial_equity(): unique timestamps (staggered by minute) instead of identical

infrastructure_patch.py:
- Add logging module, replace all print() with logger calls
- Fix guard: self.db/self.telegram instead of enable_database/enable_telegram
- Fix UTC bug in extract_trade_data_from_mt5() (fromtimestamp with tz=utc)
- Remove direct self.db.cursor.execute() in log_trade_exit() — use get_open_trades()
- Read risk_pct from SESSION_WHITELIST_CONFIG instead of hardcoding 0.01

news_filter.py / news_filter_v2.py:
- Remove both inactive variants (ForexFactory scraper + Finnhub API)
- news_filter_simple.py + news_filter_integration.py remain as active implementation

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

539 lines
16 KiB
Python

"""
🔧 INFRASTRUCTURE PATCH - SQLite + Telegram Integration
Verbindet TradingBot mit Database Logging und Telegram Notifications
INTEGRATION:
- Automatisches DB Logging bei Trade Entry/Exit
- Telegram Notifications für alle Events
- Performance Tracking
- Error Handling
USAGE:
1. Import am Anfang des Notebooks
2. Initialize Infrastructure
3. Wrapper um execute_trade und Position Management
"""
from trading_database import TradingDatabase
from telegram_notifier import TelegramNotifier, load_telegram_config
from datetime import datetime, timezone
from typing import Dict, Optional, Callable
import json
import os
import logging
logger = logging.getLogger(__name__)
class TradingInfrastructure:
"""
Infrastruktur-Manager für Database + Telegram Integration
"""
def __init__(
self,
db_path: str = "trading_bot.db",
telegram_config: Dict = None,
enable_telegram: bool = True,
enable_database: bool = True
):
"""
Initialize Infrastructure
Args:
db_path: Path to SQLite database
telegram_config: Dict with bot_token and chat_id
enable_telegram: Enable Telegram notifications
enable_database: Enable database logging
"""
self.enable_telegram = enable_telegram
self.enable_database = enable_database
# Initialize Database
if self.enable_database:
try:
self.db = TradingDatabase(db_path)
logger.info(f"Database initialized: {db_path}")
except Exception as e:
logger.error(f"Database initialization failed: {e}")
self.enable_database = False
self.db = None
else:
self.db = None
# Initialize Telegram
if self.enable_telegram:
try:
if telegram_config is None:
telegram_config = load_telegram_config()
if telegram_config:
self.telegram = TelegramNotifier(
bot_token=telegram_config['bot_token'],
chat_id=telegram_config['chat_id']
)
logger.info("Telegram notifications enabled")
else:
logger.warning("No Telegram config found, notifications disabled")
self.enable_telegram = False
self.telegram = None
except Exception as e:
logger.error(f"Telegram initialization failed: {e}")
self.enable_telegram = False
self.telegram = None
else:
self.telegram = None
# ==========================================
# TRADE LOGGING
# ==========================================
def log_trade_entry(self, trade_data: Dict):
"""
Log trade entry to database and send notification
Args:
trade_data: Dictionary with trade information
"""
# Log to database
if self.db:
try:
self.db.log_trade_entry(trade_data)
except Exception as e:
logger.error(f"Database logging failed: {e}")
if self.telegram:
try:
self.telegram.notify_trade_entry(trade_data)
except Exception as e:
logger.error(f"Telegram notification failed: {e}")
def log_trade_exit(self, ticket: int, exit_data: Dict):
"""
Log trade exit to database and send notification
Args:
ticket: MT5 ticket number
exit_data: Dictionary with exit information
"""
# Update database
if self.db:
try:
self.db.update_trade_exit(ticket, exit_data)
except Exception as e:
logger.error(f"Database update failed: {e}")
# Send Telegram notification
if self.telegram:
try:
if self.db:
open_trades = self.db.get_open_trades()
trade_row = next((t for t in open_trades if t.get('ticket') == ticket), None)
if trade_row:
trade_dict = dict(trade_row)
trade_dict.update(exit_data)
self.telegram.notify_trade_exit(trade_dict)
else:
self.telegram.notify_trade_exit(exit_data)
else:
self.telegram.notify_trade_exit(exit_data)
except Exception as e:
logger.error(f"Telegram notification failed: {e}")
# ==========================================
# WRAPPER FUNCTIONS
# ==========================================
def create_monitored_execute_trade(self, original_execute_func: Callable):
"""
Create a wrapper around execute_trade function that logs to infrastructure
Args:
original_execute_func: Original execute_trade_v2_adaptive function
Returns:
Wrapped function with logging
"""
def wrapped_execute_trade(*args, **kwargs):
"""
Wrapped execute trade with infrastructure logging
"""
try:
# Call original function
result = original_execute_func(*args, **kwargs)
# If trade was executed, result should contain trade info
# This depends on your execute_trade implementation
# You might need to modify execute_trade to return trade data
return result
except Exception as e:
# Log error
if self.enable_telegram and self.telegram:
self.telegram.send_error_alert(
str(e),
f"Error in execute_trade for {kwargs.get('symbol', 'unknown')}"
)
raise
return wrapped_execute_trade
def extract_trade_data_from_mt5(self, position, strategy_name: str, session: str,
confidence: float = None, quality: str = None) -> Dict:
"""
Extract trade data from MT5 position for logging
Args:
position: MT5 position object
strategy_name: Strategy name
session: Trading session
confidence: Signal confidence
quality: Signal quality
Returns:
Dictionary with trade data
"""
entry_time = datetime.fromtimestamp(position.time, tz=timezone.utc).replace(tzinfo=None)
# risk_pct: try to read from SESSION_WHITELIST_CONFIG, fall back to 0.01
try:
from session_filter_patch import SESSION_WHITELIST_CONFIG
risk_pct = SESSION_WHITELIST_CONFIG.get('max_risk_per_trade', 0.01)
except Exception:
risk_pct = 0.01
return {
'ticket': position.ticket,
'position_id': position.identifier,
'symbol': position.symbol,
'strategy_name': strategy_name,
'type': 'BUY' if position.type == 0 else 'SELL',
'volume': position.volume,
'entry_price': position.price_open,
'sl_price': position.sl,
'tp_price': position.tp,
'entry_time': entry_time.strftime('%Y-%m-%d %H:%M:%S'),
'session': session,
'confidence': confidence,
'quality': quality,
'risk_pct': risk_pct,
'status': 'open'
}
# ==========================================
# STATUS & MONITORING
# ==========================================
def send_bot_started(self, config: Dict):
"""
Send bot started notification
Args:
config: Bot configuration
"""
if self.telegram:
try:
self.telegram.send_bot_started(config)
except Exception as e:
logger.error(f"Telegram notification failed: {e}")
def send_bot_stopped(self, reason: str = "Manual stop"):
"""
Send bot stopped notification
Args:
reason: Stop reason
"""
if self.telegram:
try:
self.telegram.send_bot_stopped(reason)
except Exception as e:
logger.error(f"Telegram notification failed: {e}")
def send_daily_report(self):
"""Send daily performance report"""
if not (self.db and self.telegram):
return
try:
stats = self.db.get_daily_summary()
self.telegram.send_daily_report(stats)
except Exception as e:
logger.error(f"Daily report failed: {e}")
def send_weekly_report(self):
"""Send weekly performance report"""
if not (self.db and self.telegram):
return
try:
stats = self.db.get_overall_statistics(days=7)
session_perf = self.db.get_session_performance(days=7)
self.telegram.send_weekly_report(stats, session_perf)
except Exception as e:
logger.error(f"Weekly report failed: {e}")
def log_bot_status(self, status: str, config: Dict = None, error_message: str = None):
"""
Log bot status to database
Args:
status: 'running', 'stopped', 'error'
config: Optional bot configuration
error_message: Optional error message
"""
if not self.db:
return
try:
status_data = {
'status': status,
'version': config.get('version', 'V1.8') if config else 'V1.8',
'active_sessions': [s for s, enabled in config.get('enabled_sessions', {}).items() if enabled] if config else [],
'confidence_threshold': config.get('base_confidence', 60) if config else 60,
'error_message': error_message
}
self.db.log_bot_status(status_data)
except Exception as e:
logger.error(f"Status logging failed: {e}")
# ==========================================
# MIGRATION & UTILITIES
# ==========================================
def migrate_json_files(self, json_folder: str = "."):
"""
Migrate all JSON performance files to SQLite
Args:
json_folder: Folder containing JSON files
"""
if not (self.enable_database and self.db):
print("❌ Database not enabled")
return
import glob
json_files = glob.glob(os.path.join(json_folder, "trade_performance_*.json"))
if not json_files:
print("⚠️ No JSON files found")
return
print(f"📁 Found {len(json_files)} JSON files")
for json_file in json_files:
print(f"\n🔄 Migrating: {json_file}")
try:
self.db.migrate_from_json(json_file)
except Exception as e:
print(f"❌ Migration failed for {json_file}: {e}")
print("\n✅ Migration complete")
def get_performance_summary(self, days: int = 7) -> Dict:
"""
Get performance summary
Args:
days: Number of days to analyze
Returns:
Dictionary with statistics
"""
if not self.db:
return {}
try:
stats = self.db.get_overall_statistics(days=days)
session_perf = self.db.get_session_performance(days=days)
return {
'overall': stats,
'sessions': session_perf
}
except Exception as e:
logger.error(f"Performance summary failed: {e}")
return {}
def close(self):
"""Close all connections"""
if self.db:
self.db.close()
def __enter__(self):
"""Context manager entry"""
return self
def __exit__(self, exc_type, exc_val, exc_tb):
"""Context manager exit"""
self.close()
# ==========================================
# SCHEDULER INTEGRATION
# ==========================================
def create_scheduled_reports(infrastructure: TradingInfrastructure, scheduler):
"""
Add scheduled reports to APScheduler
Args:
infrastructure: TradingInfrastructure instance
scheduler: APScheduler instance
"""
# Daily report at 22:00 UTC
scheduler.add_job(
infrastructure.send_daily_report,
'cron',
hour=22,
minute=0,
id='daily_report',
replace_existing=True
)
# Weekly report on Sunday at 23:00 UTC
scheduler.add_job(
infrastructure.send_weekly_report,
'cron',
day_of_week='sun',
hour=23,
minute=0,
id='weekly_report',
replace_existing=True
)
print("✅ Scheduled reports added:")
print(" 📊 Daily report: 22:00 UTC")
print(" 📈 Weekly report: Sunday 23:00 UTC")
# ==========================================
# INTEGRATION HELPER
# ==========================================
def create_infrastructure_config() -> Dict:
"""
Create infrastructure configuration
Returns:
Dictionary with configuration
"""
return {
'database': {
'enabled': True,
'path': 'trading_bot.db'
},
'telegram': {
'enabled': True,
'notifications': {
'trade_entry': True,
'trade_exit': True,
'daily_report': True,
'weekly_report': True,
'error_alerts': True
}
}
}
# ==========================================
# USAGE EXAMPLE
# ==========================================
if __name__ == "__main__":
print("="*70)
print("🔧 INFRASTRUCTURE PATCH - Setup Check")
print("="*70)
# Initialize infrastructure
infra = TradingInfrastructure(
db_path="trading_bot.db",
enable_telegram=False # Disable for testing
)
print("\n📊 Checking database...")
if infra.db:
stats = infra.db.get_overall_statistics()
print(f" Total Trades: {stats.get('total_trades', 0)}")
print(f" Win Rate: {stats.get('win_rate', 0)}%")
print("\n" + "="*70)
print("✅ Infrastructure ready!")
print("="*70)
print("""
📋 Integration Steps:
1. Configure Telegram (optional):
- Run: python telegram_notifier.py
- Follow setup instructions
- Create telegram_config.json
2. In your Notebook, add at the beginning:
```python
from infrastructure_patch import TradingInfrastructure, create_scheduled_reports
from session_filter_patch import SESSION_WHITELIST_CONFIG
# Initialize infrastructure
infra = TradingInfrastructure(
db_path="trading_bot.db",
enable_telegram=True,
enable_database=True
)
# Send bot started notification
infra.send_bot_started(SESSION_WHITELIST_CONFIG)
# Add scheduled reports to your scheduler
create_scheduled_reports(infra, scheduler)
```
3. When opening a trade, log it:
```python
# After position opened
trade_data = infra.extract_trade_data_from_mt5(
position, strategy_name, session, confidence, quality
)
infra.log_trade_entry(trade_data)
```
4. When closing a trade, log exit:
```python
# After position closed
exit_data = {
'exit_price': close_price,
'exit_time': datetime.now(),
'profit': profit,
'net_profit': net_profit,
'exit_reason': 'tp' or 'sl'
}
infra.log_trade_exit(ticket, exit_data)
```
5. Optional - Migrate existing JSON data:
```python
infra.migrate_json_files(".")
```
""")
infra.close()