#!/usr/bin/env python3
"""
ULTIMATE MARTINGALE - Stratégie mathématique pure optimale

Règles:
1. Choisir LONG ou SHORT au hasard pour le 1er trade
2. Martingaler (doubler) dans le MÊME sens jusqu'à gagner
3. Quand on GAGNE → CHANGER DE CÔTÉ pour le prochain
4. Répéter

Avantages:
- Pas de TA inutile (50% WR suffit)
- Équilibrage automatique LONG/SHORT
- Edge purement mathématique
"""

from true_martingale import TrueMartingaleStrategy
from martingale_backtester import MartingaleBacktester
import pandas as pd
import numpy as np
from typing import Optional, Tuple
import json

class UltimateMartingale(TrueMartingaleStrategy):
    """Martingale pure avec alternance des côtés après win"""

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.last_winning_side = None
        np.random.seed(42)  # Reproductibilité

    def generate_base_signal(self, df: pd.DataFrame) -> Optional[Tuple[str, float]]:
        """
        Génère signal en alternant les côtés après chaque win
        """
        # Premier trade OU après un win: choisir le côté opposé
        if self.last_winning_side is None:
            # Premier trade: random
            side = 'LONG' if np.random.random() > 0.5 else 'SHORT'
        else:
            # Après un win: inverser
            side = 'SHORT' if self.last_winning_side == 'LONG' else 'LONG'

        return (side, 1.0)

    def update_after_trade(self, won: bool):
        """Met à jour l'état après un trade"""
        if won:
            # Mémoriser le côté gagnant pour l'inverser au prochain
            self.last_winning_side = self.current_side
            self.consecutive_losses = 0
            self.current_level = 0
            self.current_side = None
            self.locked_in_martingale = False
        else:
            # Perte: martingale
            self.consecutive_losses += 1
            self.current_level = min(self.current_level + 1, self.max_martingale_level)
            self.locked_in_martingale = True

print("=" * 80)
print("🎯 ULTIMATE MARTINGALE - Mathématiques pures + Alternance")
print("=" * 80)

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:
    exit(1)

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

# ============ GRILLE D'OPTIMISATION ============

print("🔬 OPTIMISATION PARAMÈTRES MATHÉMATIQUES")
print("=" * 80)

# Grille intelligente
configs = []

# 1. Petites positions, beaucoup de levels (conservative)
for pos in [0.5, 1, 2, 3]:
    for max_lv in [8, 9, 10]:
        for sl in [0.003, 0.004, 0.005]:
            configs.append({
                'base_position_size': pos,
                'max_martingale_level': max_lv,
                'base_leverage': 10,
                'max_leverage': 500,
                'stop_loss_pct': sl,
                'take_profit_ratio': 3.0
            })

# 2. Moyennes positions, levels moyens (balanced)
for pos in [5, 7, 9, 11]:
    for max_lv in [6, 7]:
        for sl in [0.0025, 0.003, 0.0035]:
            configs.append({
                'base_position_size': pos,
                'max_martingale_level': max_lv,
                'base_leverage': 20,
                'max_leverage': 1000,
                'stop_loss_pct': sl,
                'take_profit_ratio': 3.0
            })

# 3. Grosses positions, peu de levels (aggressive)
for pos in [15, 20, 25]:
    for max_lv in [4, 5]:
        for sl in [0.002, 0.0025]:
            configs.append({
                'base_position_size': pos,
                'max_martingale_level': max_lv,
                'base_leverage': 30,
                'max_leverage': 1000,
                'stop_loss_pct': sl,
                'take_profit_ratio': 2.5
            })

print(f"🎯 {len(configs)} configurations à tester\n")

results = []
best_roi = -999

for i, config in enumerate(configs, 1):
    config['min_signal_score'] = 0.0  # Pas de filtre

    print(f"\r🧪 Test {i}/{len(configs)} | Meilleur ROI: {best_roi:+.2f}%", end="", flush=True)

    try:
        strategy = UltimateMartingale(**config)
        result = backtester.run_backtest(df, 'BTCUSDT', strategy, verbose=False)

        if result and result.total_trades > 0:
            metrics = {
                'config': config.copy(),
                '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,
                'capital': result.final_capital,
                'max_consec_losses': result.max_consecutive_losses,
                'avg_win': result.avg_win_pct,
                'avg_loss': result.avg_loss_pct
            }

            results.append(metrics)

            if metrics['roi'] > best_roi:
                best_roi = metrics['roi']
    except:
        pass

print("\n\n" + "=" * 80)
print("🏆 TOP 20 CONFIGURATIONS")
print("=" * 80)

if not results:
    print("\n❌ Aucun résultat valide!")
    exit(1)

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

print(f"\n{'#':<3} {'Pos$':>6} {'Lv':>3} {'Leg':>8} {'SL%':>5} {'TP':>4} "
      f"{'ROI%':>7} {'WR%':>5} {'PF':>6} {'DD%':>7} {'Tr':>3}")
print("-" * 80)

for rank, res in enumerate(top_20, 1):
    cfg = res['config']
    emoji = "🥇" if rank == 1 else "🥈" if rank == 2 else "🥉" if rank == 3 else f"{rank:2}"
    status = "✅" if res['roi'] > 0 else "❌"

    lev_str = f"{cfg['base_leverage']}→{cfg['max_leverage']}"

    print(f"{emoji:<3} {cfg['base_position_size']:>6.1f} {cfg['max_martingale_level']:>3} "
          f"{lev_str:>8} {cfg['stop_loss_pct']*100:>4.2f} {cfg['take_profit_ratio']:>4.1f} "
          f"{res['roi']:>6.2f}% {res['win_rate']*100:>4.1f}% {res['profit_factor']:>6.2f} "
          f"{res['max_dd']:>6.2f}% {res['trades']:>3} {status}")

# Meilleur
best = top_20[0]

print(f"\n\n{'=' * 80}")
print(f"🏆 CONFIGURATION OPTIMALE - ULTIMATE MARTINGALE")
print(f"{'=' * 80}")

print(f"\n📊 PERFORMANCE:")
print(f"   ROI:               {best['roi']:+.2f}% {'✅ PROFITABLE!' if best['roi'] > 0 else '❌'}")
print(f"   Capital final:     ${best['capital']:.2f}")
print(f"   Gain:              ${best['capital'] - 1000:.2f}")
print(f"   Win Rate:          {best['win_rate']*100:.1f}%")
print(f"   Profit Factor:     {best['profit_factor']:.2f}")
print(f"   Max Drawdown:      {best['max_dd']:.2f}%")
print(f"   Trades:            {best['trades']}")
print(f"   Max pertes consec: {best['max_consec_losses']}")

if best['trades'] > 0:
    print(f"\n💰 STATISTIQUES:")
    print(f"   Gain moyen:        +{best['avg_win']:.2f}%")
    print(f"   Perte moyenne:     {best['avg_loss']:.2f}%")
    ratio = abs(best['avg_win'] / best['avg_loss']) if best['avg_loss'] != 0 else 0
    print(f"   Ratio Gain/Perte:  {ratio:.2f}x")

cfg = best['config']
print(f"\n⚙️  PARAMÈTRES MATHÉMATIQUES OPTIMAUX:")
print(f"   Position de base:  ${cfg['base_position_size']:.2f}")
print(f"   Max level:         {cfg['max_martingale_level']} (x{2**cfg['max_martingale_level']})")
print(f"   Leverage:          {cfg['base_leverage']}x → {cfg['max_leverage']}x")
print(f"   Stop Loss:         {cfg['stop_loss_pct']*100:.3f}%")
print(f"   Take Profit:       {cfg['take_profit_ratio']:.1f}x SL")

max_position = cfg['base_position_size'] * (2 ** cfg['max_martingale_level'])
print(f"\n🧮 ANALYSE MATHÉMATIQUE:")
print(f"   Position max:      ${max_position:.2f}")
print(f"   Marge sécurité:    {(1000 / max_position):.2f}x")
print(f"   Proba ruine:       {(0.5 ** (cfg['max_martingale_level'] + 1)) * 100:.4f}%")

print(f"\n💡 LOGIQUE:")
print(f"   1. Premier trade: 50/50 random LONG ou SHORT")
print(f"   2. Si perte → doubler dans le MÊME sens")
print(f"   3. Si win → CHANGER de côté au prochain")
print(f"   4. Répéter")

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

# Code
print(f"\n📝 CODE:")
print("=" * 80)
print(f"""
from ultimate_martingale import UltimateMartingale

strategy = UltimateMartingale(
    base_position_size={cfg['base_position_size']},
    max_martingale_level={cfg['max_martingale_level']},
    base_leverage={cfg['base_leverage']},
    max_leverage={cfg['max_leverage']},
    stop_loss_pct={cfg['stop_loss_pct']},
    take_profit_ratio={cfg['take_profit_ratio']},
    min_signal_score=0.0
)

# ROI: {best['roi']:+.2f}%
# Alterne LONG/SHORT automatiquement après chaque win
""")
print("=" * 80)

# Sauvegarder
with open('ultimate_martingale_results.json', 'w') as f:
    json.dump({
        'best_config': best['config'],
        'best_metrics': best,
        'top_20': top_20,
        'all_results': results
    }, f, indent=2, default=str)

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

# Stats globales
profitable = [r for r in results if r['roi'] > 0]
print(f"\n📈 STATS GLOBALES:")
print(f"   Configs testées:     {len(results)}")
print(f"   Configs profitables: {len(profitable)} ({len(profitable)/len(results)*100:.1f}%)")
if profitable:
    avg_roi = np.mean([r['roi'] for r in profitable])
    print(f"   ROI moyen:           +{avg_roi:.2f}%")

print(f"\n{'=' * 80}")
print("🎉 OPTIMISATION ULTIMATE MARTINGALE TERMINÉE!")
print(f"{'=' * 80}")
