#!/usr/bin/env python3 """ πŸ”§ Fix Closed Positions - Manual Update Aktualisiert geschlossene Positionen in der Datenbank mit Exit-Daten aus MT5 """ import MetaTrader5 as mt import sqlite3 from datetime import datetime, timedelta print("=" * 60) print("πŸ”§ MANUAL FIX: Closed Positions Update") print("=" * 60) # ========================================== # 1. CONNECT TO MT5 # ========================================== print("\n1️⃣ Verbinde mit MT5...") if not mt.initialize(): print(f"❌ MT5 Connection failed: {mt.last_error()}") exit(1) print("βœ… MT5 verbunden") # ========================================== # 2. CONNECT TO DATABASE # ========================================== print("2️⃣ Verbinde mit Datenbank...") conn = sqlite3.connect("trading_bot.db") conn.row_factory = sqlite3.Row cursor = conn.cursor() print("βœ… Datenbank verbunden") # ========================================== # 3. FIND CLOSED POSITIONS # ========================================== print("\n3️⃣ Suche geschlossene Positionen...") # Get all open trades from DB cursor.execute(""" SELECT ticket, symbol, type, entry_price, sl_price, tp_price, entry_time FROM trades WHERE status = 'open' """) db_open_trades = cursor.fetchall() # Get current MT5 positions mt5_positions = mt.positions_get() mt5_tickets = {pos.ticket for pos in mt5_positions} if mt5_positions else set() # Find closed positions closed_tickets = [] for trade in db_open_trades: if trade['ticket'] not in mt5_tickets: closed_tickets.append(trade) print(f"βœ… Gefunden: {len(closed_tickets)} geschlossene Positionen") if not closed_tickets: print("\nβœ… Keine geschlossenen Positionen zu updaten!") mt.shutdown() conn.close() exit(0) # ========================================== # 4. UPDATE EACH CLOSED POSITION # ========================================== print("\n4️⃣ Update geschlossene Positionen...") now = datetime.now() days_ago = now - timedelta(days=30) updated_count = 0 failed_count = 0 for trade in closed_tickets: ticket = trade['ticket'] print(f"\n Processing Ticket {ticket}...") try: # Get deals history with time range (last 30 days) deals = mt.history_deals_get(days_ago, now, ticket=ticket) if not deals: print(f" ❌ No history found") failed_count += 1 continue # Find close deal (entry == 1) close_deal = None for deal in deals: if deal.entry == 1: # Entry out = Close close_deal = deal break if not close_deal: print(f" ❌ No close deal found") failed_count += 1 continue # Calculate exit data exit_price = close_deal.price exit_time = datetime.fromtimestamp(close_deal.time) profit = close_deal.profit commission = close_deal.commission swap = close_deal.swap net_profit = profit + commission + swap # Calculate duration entry_time = datetime.strptime(trade['entry_time'], '%Y-%m-%d %H:%M:%S') duration_hours = (exit_time - entry_time).total_seconds() / 3600 # Calculate RR ratio rr_ratio = None if trade['sl_price'] and trade['tp_price']: risk = abs(trade['entry_price'] - trade['sl_price']) reward = abs(trade['tp_price'] - trade['entry_price']) if risk > 0: rr_ratio = reward / risk # Determine exit reason exit_reason = "manual_close" tolerance = 0.5 if trade['tp_price'] and trade['sl_price']: if trade['type'] == "BUY": if abs(exit_price - trade['tp_price']) <= tolerance: exit_reason = "take_profit" elif abs(exit_price - trade['sl_price']) <= tolerance: exit_reason = "stop_loss" else: # SELL if abs(exit_price - trade['tp_price']) <= tolerance: exit_reason = "take_profit" elif abs(exit_price - trade['sl_price']) <= tolerance: exit_reason = "stop_loss" # Update database cursor.execute(""" UPDATE trades SET exit_price = ?, exit_time = ?, duration_hours = ?, profit = ?, commission = ?, swap = ?, net_profit = ?, rr_ratio = ?, status = 'closed', exit_reason = ? WHERE ticket = ? """, ( exit_price, exit_time.strftime('%Y-%m-%d %H:%M:%S'), duration_hours, profit, commission, swap, net_profit, rr_ratio, exit_reason, ticket )) conn.commit() print(f" βœ… Updated successfully!") print(f" Exit: {exit_price}") print(f" Time: {exit_time}") print(f" Profit: ${net_profit:.2f}") print(f" Reason: {exit_reason}") updated_count += 1 except Exception as e: print(f" ❌ Error: {e}") failed_count += 1 # ========================================== # 5. SUMMARY # ========================================== print("\n" + "=" * 60) print("πŸ“Š ZUSAMMENFASSUNG") print("=" * 60) print(f"\nβœ… Erfolgreich updated: {updated_count}") print(f"❌ Fehlgeschlagen: {failed_count}") if updated_count > 0: print("\nπŸŽ‰ Datenbank wurde erfolgreich aktualisiert!") print(" Dashboard zeigt jetzt Profit-Daten an.") else: print("\n⚠️ Keine Positionen konnten aktualisiert werden.") print(" PrΓΌfe MT5 History-Einstellungen.") # ========================================== # 6. VERIFY # ========================================== print("\n" + "=" * 60) print("πŸ” VERIFIZIERUNG") print("=" * 60) cursor.execute(""" SELECT COUNT(*) as total, SUM(CASE WHEN status = 'closed' THEN 1 ELSE 0 END) as closed, SUM(CASE WHEN net_profit IS NOT NULL THEN 1 ELSE 0 END) as with_profit FROM trades WHERE status != 'historical' """) stats = cursor.fetchone() print(f"\nLive Trades:") print(f" Total: {stats['total']}") print(f" Closed: {stats['closed']}") print(f" Mit Profit: {stats['with_profit']}") mt.shutdown() conn.close() print("\n" + "=" * 60) print("βœ… Fix abgeschlossen!") print("=" * 60)