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

249 lines
6.9 KiB
Python
Raw Normal View History

2025-12-26 16:28:07 +01:00
#!/usr/bin/env python3
"""
🗑️ Historical Trades Cleanup
Behandelt die 240 'historical' Trades mit NULL profit
"""
import sqlite3
import shutil
from datetime import datetime
DB_PATH = "trading_bot.db"
BACKUP_DIR = "backups"
def create_backup():
"""Backup erstellen"""
timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
backup_path = f"{BACKUP_DIR}/trading_bot_before_historical_cleanup_{timestamp}.db"
shutil.copy(DB_PATH, backup_path)
print(f"✅ Backup: {backup_path}")
return backup_path
def analyze_historical_trades(conn):
"""Analysiere historical trades"""
print("\n" + "="*80)
print("📊 ANALYSE: Historical Trades")
print("="*80)
cursor = conn.cursor()
# Basic info
cursor.execute("""
SELECT
COUNT(*) as total,
MIN(entry_time) as first_trade,
MAX(entry_time) as last_trade,
COUNT(DISTINCT DATE(entry_time)) as trading_days
FROM trades
WHERE status = 'historical' AND net_profit IS NULL
""")
total, first, last, days = cursor.fetchone()
print(f"\nTotal: {total} Trades")
print(f"Zeitraum: {first} bis {last}")
print(f"Trading Days: {days}")
# Session breakdown
cursor.execute("""
SELECT session, COUNT(*) as count
FROM trades
WHERE status = 'historical' AND net_profit IS NULL
GROUP BY session
ORDER BY count DESC
""")
print("\nSession Breakdown:")
for session, count in cursor.fetchall():
print(f" {session:10} {count:3} Trades")
# Quality breakdown
cursor.execute("""
SELECT
quality,
COUNT(*) as count,
ROUND(AVG(confidence), 1) as avg_conf
FROM trades
WHERE status = 'historical' AND net_profit IS NULL
GROUP BY quality
""")
print("\nQuality Breakdown:")
for quality, count, conf in cursor.fetchall():
print(f" {quality if quality else 'NULL':12} {count:3} Trades (avg conf: {conf}%)")
return total
def option_delete_historical(conn):
"""Option 1: Lösche alle historical trades"""
print("\n" + "="*80)
print("🗑️ OPTION 1: Alle historical Trades LÖSCHEN")
print("="*80)
cursor = conn.cursor()
cursor.execute("DELETE FROM trades WHERE status = 'historical' AND net_profit IS NULL")
deleted = cursor.rowcount
print(f"✅ Gelöscht: {deleted} Trades")
conn.commit()
def option_mark_as_invalid(conn):
"""Option 2: Markiere als invalid statt löschen"""
print("\n" + "="*80)
print("🏷️ OPTION 2: Als 'invalid' markieren")
print("="*80)
cursor = conn.cursor()
cursor.execute("""
UPDATE trades
SET status = 'invalid_historical'
WHERE status = 'historical' AND net_profit IS NULL
""")
updated = cursor.rowcount
print(f"✅ Markiert: {updated} Trades als 'invalid_historical'")
conn.commit()
def option_set_zero_profit(conn):
"""Option 3: Setze net_profit = 0 (als breakeven)"""
print("\n" + "="*80)
print("💰 OPTION 3: net_profit = 0 setzen (Breakeven)")
print("="*80)
cursor = conn.cursor()
cursor.execute("""
UPDATE trades
SET net_profit = 0.0,
profit = 0.0,
profit_pct = 0.0,
exit_reason = 'historical_migration_breakeven'
WHERE status = 'historical' AND net_profit IS NULL
""")
updated = cursor.rowcount
print(f"✅ Updated: {updated} Trades auf Breakeven gesetzt")
conn.commit()
def verify_cleanup(conn):
"""Verifiziere Cleanup"""
print("\n" + "="*80)
print("✅ VERIFICATION")
print("="*80)
cursor = conn.cursor()
# Count historical
cursor.execute("SELECT COUNT(*) FROM trades WHERE status = 'historical'")
historical = cursor.fetchone()[0]
# Count NULL profits
cursor.execute("SELECT COUNT(*) FROM trades WHERE net_profit IS NULL")
null_profits = cursor.fetchone()[0]
# Count invalid
cursor.execute("SELECT COUNT(*) FROM trades WHERE status = 'invalid_historical'")
invalid = cursor.fetchone()[0]
print(f"Historical Trades: {historical}")
print(f"NULL Profits: {null_profits}")
print(f"Invalid Historical: {invalid}")
# Performance
cursor.execute("""
SELECT
COUNT(*) as total,
SUM(CASE WHEN net_profit > 0 THEN 1 ELSE 0 END) as wins,
SUM(CASE WHEN net_profit < 0 THEN 1 ELSE 0 END) as losses,
ROUND(SUM(net_profit), 2) as total_profit
FROM trades
WHERE net_profit IS NOT NULL
""")
total, wins, losses, profit = cursor.fetchone()
win_rate = (wins / total * 100) if total > 0 else 0
print(f"\nGesamt Performance (nur valide Trades):")
print(f" Total: {total}")
print(f" Wins: {wins} ({win_rate:.1f}%)")
print(f" Losses: {losses}")
print(f" Total Profit: ${profit}")
def main():
print("="*80)
print("🗑️ HISTORICAL TRADES CLEANUP")
print("="*80)
# Backup
backup_path = create_backup()
# Connect
conn = sqlite3.connect(DB_PATH)
try:
# Analyze
total = analyze_historical_trades(conn)
# Ask user
print("\n" + "="*80)
print("❓ AUSWAHL")
print("="*80)
print("\nWas soll mit den 240 historical Trades passieren?")
print()
print("1️⃣ LÖSCHEN - Alle historical trades permanent entfernen")
print(" Pro: Saubere Datenbank")
print(" Con: Daten unwiederbringlich weg")
print()
print("2️⃣ MARKIEREN - Als 'invalid_historical' markieren (behalten aber ausblenden)")
print(" Pro: Daten bleiben erhalten")
print(" Con: Nimmt Speicherplatz")
print()
print("3️⃣ BREAKEVEN - net_profit = 0 setzen (als Breakeven-Trades behandeln)")
print(" Pro: Fließen in Statistik ein")
print(" Con: Verfälscht Performance-Daten")
print()
print("4️⃣ ABBRECHEN - Nichts tun, Trades behalten wie sie sind")
print()
choice = input("Ihre Wahl (1-4): ").strip()
if choice == "1":
option_delete_historical(conn)
elif choice == "2":
option_mark_as_invalid(conn)
elif choice == "3":
option_set_zero_profit(conn)
elif choice == "4":
print("\n⏸️ Abgebrochen - Keine Änderungen")
return
else:
print(f"\n❌ Ungültige Wahl: {choice}")
return
# Verify
verify_cleanup(conn)
print("\n" + "="*80)
print("✅ CLEANUP ABGESCHLOSSEN")
print("="*80)
print(f"\nBackup: {backup_path}")
except Exception as e:
print(f"\n❌ ERROR: {e}")
conn.rollback()
# Restore backup
print(f"Restore Backup: {backup_path}")
shutil.copy(backup_path, DB_PATH)
print("✅ Backup wiederhergestellt")
finally:
conn.close()
if __name__ == "__main__":
main()