#!/usr/bin/env python3
"""
Teste différentes combinaisons de martingale pour trouver la meilleure
"""

from martingale_backtester import MartingaleBacktester
from martingale_strategy import MartingaleStrategy
import copy

print("="*80)
print("🔬 TEST DE MULTIPLES COMBINAISONS MARTINGALE")
print("="*80)

# Fetch data une seule fois
backtester = MartingaleBacktester(
    initial_capital=1000.0,
    trading_fee_pct=0.0005,
    timeout_minutes=60
)

print("\n📥 Téléchargement données...")
df = backtester.fetch_binance_data('BTCUSDT', '1m', 1000)

if df is None:
    print("❌ Erreur téléchargement")
    exit(1)

print(f"✅ {len(df)} bougies chargées\n")

# ============ CONFIGURATIONS À TESTER ============

configs = [
    {
        'name': '1. ORIGINAL (base)',
        'base_position_size': 10.0,
        'martingale_multiplier': 2,  # x2 classique
        'base_leverage': 100,
        'max_leverage': 1000,
        'stop_loss_pct': 0.003,
        'take_profit_ratio': 3.0,
        'min_signal_score': 0.6,
        'reverse_signals': False
    },
    {
        'name': '2. TRIPLE Martingale (x3)',
        'base_position_size': 10.0,
        'martingale_multiplier': 3,  # x3 au lieu de x2
        'base_leverage': 100,
        'max_leverage': 1000,
        'stop_loss_pct': 0.003,
        'take_profit_ratio': 3.0,
        'min_signal_score': 0.6,
        'reverse_signals': False
    },
    {
        'name': '3. TRIPLE Leverage',
        'base_position_size': 10.0,
        'martingale_multiplier': 2,
        'base_leverage': 300,  # 3x plus de leverage
        'max_leverage': 1000,
        'stop_loss_pct': 0.003,
        'take_profit_ratio': 3.0,
        'min_signal_score': 0.6,
        'reverse_signals': False
    },
    {
        'name': '4. TRIPLE Position Size',
        'base_position_size': 30.0,  # 3x la mise
        'martingale_multiplier': 2,
        'base_leverage': 100,
        'max_leverage': 1000,
        'stop_loss_pct': 0.003,
        'take_profit_ratio': 3.0,
        'min_signal_score': 0.6,
        'reverse_signals': False
    },
    {
        'name': '5. INVERSE Signals',
        'base_position_size': 10.0,
        'martingale_multiplier': 2,
        'base_leverage': 100,
        'max_leverage': 1000,
        'stop_loss_pct': 0.003,
        'take_profit_ratio': 3.0,
        'min_signal_score': 0.6,
        'reverse_signals': True  # LONG→SHORT, SHORT→LONG
    },
    {
        'name': '6. CONSERVATIVE (leverage réduit)',
        'base_position_size': 10.0,
        'martingale_multiplier': 2,
        'base_leverage': 50,   # 2x moins
        'max_leverage': 500,   # 2x moins
        'stop_loss_pct': 0.005,  # Plus large
        'take_profit_ratio': 5.0,  # Plus large
        'min_signal_score': 0.6,
        'reverse_signals': False
    },
    {
        'name': '7. AGGRESSIVE (TP large)',
        'base_position_size': 10.0,
        'martingale_multiplier': 2,
        'base_leverage': 100,
        'max_leverage': 1000,
        'stop_loss_pct': 0.002,  # Plus serré
        'take_profit_ratio': 8.0,  # Très large!
        'min_signal_score': 0.6,
        'reverse_signals': False
    },
    {
        'name': '8. HYBRID (x3 + leverage réduit)',
        'base_position_size': 10.0,
        'martingale_multiplier': 3,  # x3
        'base_leverage': 50,   # Réduit
        'max_leverage': 500,   # Réduit
        'stop_loss_pct': 0.004,
        'take_profit_ratio': 5.0,
        'min_signal_score': 0.6,
        'reverse_signals': False
    },
    {
        'name': '9. FIBONACCI (1.5x)',
        'base_position_size': 10.0,
        'martingale_multiplier': 1.5,  # Fibonacci-like
        'base_leverage': 100,
        'max_leverage': 1000,
        'stop_loss_pct': 0.003,
        'take_profit_ratio': 3.0,
        'min_signal_score': 0.6,
        'reverse_signals': False
    },
    {
        'name': '10. ANTI-MARTINGALE (réduit après loss)',
        'base_position_size': 10.0,
        'martingale_multiplier': 0.5,  # RÉDUIT après perte!
        'base_leverage': 100,
        'max_leverage': 1000,
        'stop_loss_pct': 0.003,
        'take_profit_ratio': 3.0,
        'min_signal_score': 0.6,
        'reverse_signals': False
    }
]

# ============ TESTER CHAQUE CONFIG ============

results_summary = []

for i, config in enumerate(configs, 1):
    print(f"\n{'='*80}")
    print(f"🧪 TEST {i}/{len(configs)}: {config['name']}")
    print(f"{'='*80}")

    # Créer stratégie modifiée
    class ModifiedMartingale(MartingaleStrategy):
        def __init__(self, multiplier, reverse, **kwargs):
            super().__init__(**kwargs)
            self.multiplier = multiplier
            self.reverse_signals = reverse

        def get_martingale_multiplier(self):
            """Override pour multiplier custom"""
            return int(self.multiplier ** self.current_level)

        def generate_signal(self, df):
            """Override pour inverser signaux si nécessaire"""
            signal = super().generate_signal(df)

            if signal and self.reverse_signals:
                # Inverser LONG ↔ SHORT
                signal.side = 'SHORT' if signal.side == 'LONG' else 'LONG'
                # Inverser SL/TP
                signal.stop_loss, signal.take_profit = signal.take_profit, signal.stop_loss

            return signal

    strategy = ModifiedMartingale(
        multiplier=config['martingale_multiplier'],
        reverse=config['reverse_signals'],
        base_position_size=config['base_position_size'],
        max_martingale_level=5,
        base_leverage=config['base_leverage'],
        max_leverage=config['max_leverage'],
        stop_loss_pct=config['stop_loss_pct'],
        take_profit_ratio=config['take_profit_ratio'],
        min_signal_score=config['min_signal_score']
    )

    # Backtest
    result = backtester.run_backtest(df, 'BTCUSDT', strategy)

    if result:
        results_summary.append({
            'name': config['name'],
            'roi': result.total_return_pct,
            'win_rate': result.win_rate,
            'profit_factor': result.profit_factor,
            'trades': result.total_trades,
            'max_dd': result.max_drawdown_pct,
            'final_capital': result.final_capital
        })
    else:
        results_summary.append({
            'name': config['name'],
            'roi': 0,
            'win_rate': 0,
            'profit_factor': 0,
            'trades': 0,
            'max_dd': 0,
            'final_capital': 1000
        })

# ============ COMPARAISON FINALE ============

print("\n" + "="*80)
print("🏆 CLASSEMENT DES STRATÉGIES")
print("="*80)

# Trier par ROI
results_summary.sort(key=lambda x: x['roi'], reverse=True)

print(f"\n{'RANG':<5} {'STRATÉGIE':<35} {'ROI %':>10} {'WR %':>8} {'PF':>6} {'Trades':>7} {'MaxDD %':>9}")
print("-"*80)

for rank, res in enumerate(results_summary, 1):
    emoji = "🥇" if rank == 1 else "🥈" if rank == 2 else "🥉" if rank == 3 else f"{rank:2}"
    print(f"{emoji:<5} {res['name']:<35} {res['roi']:>9.2f}% {res['win_rate']*100:>7.1f}% "
          f"{res['profit_factor']:>5.2f} {res['trades']:>7} {res['max_dd']:>8.2f}%")

# Meilleure stratégie
best = results_summary[0]
print(f"\n{'='*80}")
print(f"🏆 MEILLEURE STRATÉGIE: {best['name']}")
print(f"{'='*80}")
print(f"   ROI:           {best['roi']:+.2f}%")
print(f"   Win Rate:      {best['win_rate']*100:.1f}%")
print(f"   Profit Factor: {best['profit_factor']:.2f}")
print(f"   Trades:        {best['trades']}")
print(f"   Max DD:        {best['max_dd']:.2f}%")
print(f"   Capital Final: ${best['final_capital']:.2f}")
print(f"{'='*80}")

# Sauvegarder résultats
import json
with open('combination_test_results.json', 'w') as f:
    json.dump(results_summary, f, indent=2)

print("\n💾 Résultats sauvegardés: combination_test_results.json")
