#!/usr/bin/env python3
"""
RECHERCHE D'UN EDGE - Trouve l'avantage qui rend la stratégie profitable

Tests:
1. Inverser côté après N pertes
2. Doubler TP après N pertes
3. Skip trades après N pertes
4. Combinations
"""

from martingale_backtester import MartingaleBacktester
from martingale_strategy import MartingaleStrategy
import copy

print("="*80)
print("🔍 RECHERCHE D'UN EDGE - TROUVER L'AVANTAGE GAGNANT")
print("="*80)

# Fetch data
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")
    exit(1)

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

# ============ EDGES À TESTER ============

edges = [
    {
        'name': '1. BASE (anti-martingale)',
        'reverse_after_losses': None,
        'double_tp_after_losses': None,
        'skip_after_losses': None,
        'reduce_leverage_after_losses': None
    },
    {
        'name': '2. REVERSE après 2 pertes',
        'reverse_after_losses': 2,
        'double_tp_after_losses': None,
        'skip_after_losses': None,
        'reduce_leverage_after_losses': None
    },
    {
        'name': '3. REVERSE après 3 pertes 🎯',
        'reverse_after_losses': 3,
        'double_tp_after_losses': None,
        'skip_after_losses': None,
        'reduce_leverage_after_losses': None
    },
    {
        'name': '4. REVERSE après 4 pertes',
        'reverse_after_losses': 4,
        'double_tp_after_losses': None,
        'skip_after_losses': None,
        'reduce_leverage_after_losses': None
    },
    {
        'name': '5. DOUBLE TP après 2 pertes',
        'reverse_after_losses': None,
        'double_tp_after_losses': 2,
        'skip_after_losses': None,
        'reduce_leverage_after_losses': None
    },
    {
        'name': '6. DOUBLE TP après 3 pertes',
        'reverse_after_losses': None,
        'double_tp_after_losses': 3,
        'skip_after_losses': None,
        'reduce_leverage_after_losses': None
    },
    {
        'name': '7. SKIP 1 trade après 3 pertes',
        'reverse_after_losses': None,
        'double_tp_after_losses': None,
        'skip_after_losses': 3,
        'reduce_leverage_after_losses': None
    },
    {
        'name': '8. REDUCE leverage 50% après 2 pertes',
        'reverse_after_losses': None,
        'double_tp_after_losses': None,
        'skip_after_losses': None,
        'reduce_leverage_after_losses': 2
    },
    {
        'name': '9. REVERSE + DOUBLE TP après 3 pertes',
        'reverse_after_losses': 3,
        'double_tp_after_losses': 3,
        'skip_after_losses': None,
        'reduce_leverage_after_losses': None
    },
    {
        'name': '10. REVERSE + REDUCE LEV après 3 pertes',
        'reverse_after_losses': 3,
        'double_tp_after_losses': None,
        'skip_after_losses': None,
        'reduce_leverage_after_losses': 3
    },
    {
        'name': '11. REVERSE après 2 + SKIP après 4',
        'reverse_after_losses': 2,
        'double_tp_after_losses': None,
        'skip_after_losses': 4,
        'reduce_leverage_after_losses': None
    },
    {
        'name': '12. REVERSE après 3 + DOUBLE TP après 2',
        'reverse_after_losses': 3,
        'double_tp_after_losses': 2,
        'skip_after_losses': None,
        'reduce_leverage_after_losses': None
    }
]

# ============ STRATÉGIE AVEC EDGES ============

class EdgeStrategy(MartingaleStrategy):
    def __init__(self, edge_config, **kwargs):
        super().__init__(**kwargs)
        self.edge_config = edge_config
        self.side_reversed = False
        self.skip_next = False

    def get_martingale_multiplier(self):
        # Anti-martingale
        return 0.5 ** self.current_level

    def get_leverage_for_level(self):
        base_lev = super().get_leverage_for_level()

        # Edge: Reduce leverage après N pertes
        if (self.edge_config['reduce_leverage_after_losses'] and
            self.consecutive_losses >= self.edge_config['reduce_leverage_after_losses']):
            return int(base_lev * 0.5)

        return base_lev

    def generate_signal(self, df):
        # Edge: Skip après N pertes
        if (self.edge_config['skip_after_losses'] and
            self.consecutive_losses >= self.edge_config['skip_after_losses']):
            if self.skip_next:
                self.skip_next = False
                return None
            else:
                self.skip_next = True

        signal = super().generate_signal(df)

        if not signal:
            return None

        # Edge: Reverse côté après N pertes
        if (self.edge_config['reverse_after_losses'] and
            self.consecutive_losses >= self.edge_config['reverse_after_losses']):
            if not self.side_reversed:
                signal.side = 'SHORT' if signal.side == 'LONG' else 'LONG'
                # Swap SL/TP
                signal.stop_loss, signal.take_profit = signal.take_profit, signal.stop_loss
                self.side_reversed = True

        # Edge: Double TP après N pertes
        if (self.edge_config['double_tp_after_losses'] and
            self.consecutive_losses >= self.edge_config['double_tp_after_losses']):
            if signal.side == 'LONG':
                new_tp = signal.entry_price + (signal.take_profit - signal.entry_price) * 2
                signal.take_profit = new_tp
            else:
                new_tp = signal.entry_price - (signal.entry_price - signal.take_profit) * 2
                signal.take_profit = new_tp

        return signal

    def update_after_trade(self, won):
        super().update_after_trade(won)
        # Reset reverse flag quand on gagne
        if won:
            self.side_reversed = False
            self.skip_next = False

# ============ TESTER CHAQUE EDGE ============

results_summary = []

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

    strategy = EdgeStrategy(
        edge_config=edge,
        base_position_size=10.0,
        max_martingale_level=5,
        base_leverage=100,
        max_leverage=1000,
        stop_loss_pct=0.003,
        take_profit_ratio=3.0,
        min_signal_score=0.6
    )

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

    if result:
        results_summary.append({
            'name': edge['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': edge['name'],
            'roi': 0,
            'win_rate': 0,
            'profit_factor': 0,
            'trades': 0,
            'max_dd': 0,
            'final_capital': 1000
        })

# ============ CLASSEMENT ============

print("\n" + "="*80)
print("🏆 CLASSEMENT DES EDGES")
print("="*80)

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

print(f"\n{'RANG':<5} {'EDGE':<45} {'ROI %':>10} {'WR %':>8} {'PF':>6} {'Trades':>7} {'DD %':>8}")
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}"
    roi_emoji = "✅" if res['roi'] > 0 else "⚠️" if res['roi'] > -2 else "❌"
    print(f"{emoji:<5} {res['name']:<45} {res['roi']:>9.2f}% {res['win_rate']*100:>7.1f}% "
          f"{res['profit_factor']:>5.2f} {res['trades']:>7} {res['max_dd']:>7.2f}% {roi_emoji}")

# Meilleur edge
best = results_summary[0]
print(f"\n{'='*80}")
print(f"🏆 MEILLEUR EDGE: {best['name']}")
print(f"{'='*80}")
print(f"   ROI:           {best['roi']:+.2f}% {'✅ POSITIF!' if best['roi'] > 0 else '❌ Négatif'}")
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}")

if best['roi'] > 0:
    print(f"\n🎉 EDGE TROUVÉ! Stratégie PROFITABLE!")
    print(f"   Gain: ${best['final_capital'] - 1000:.2f}")
else:
    print(f"\n⚠️  Meilleur edge mais toujours négatif")
    print(f"   Continuer la recherche avec d'autres combinaisons")

print(f"{'='*80}")

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

print("\n💾 Résultats: edge_test_results.json")
