#!/usr/bin/env python3
"""
PURE RANDOM MARTINGALE OPTIMIZER

Hypothèse: Avec les BONS paramètres mathématiques, même du pur random est profitable.

On cherche:
- Position de base optimale
- Max level (combien de doublements)
- Stop Loss %
- Take Profit ratio
- Leverage range

Le signal = pur random (50/50 LONG/SHORT)
L'edge = paramètres mathématiques parfaits
"""

from martingale_backtester import MartingaleBacktester
from pure_math_edge import PureMathStrategy
import numpy as np
import json
from itertools import product

print("=" * 80)
print("🎲 OPTIMISEUR PURE RANDOM MARTINGALE")
print("=" * 80)
print("\nHypothèse: Les paramètres mathématiques sont l'EDGE, pas les signaux")
print("Signal = 50/50 random | Edge = maths parfaites\n")

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

print("📥 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")

# ============ ESPACE DE RECHERCHE ============

# On va tester des combinaisons intelligentes
param_space = {
    'base_position_size': [1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 15],
    'max_martingale_level': [4, 5, 6, 7, 8, 9, 10],
    'base_leverage': [5, 10, 15, 20, 25, 30, 40, 50],
    'max_leverage': [200, 300, 500, 750, 1000],
    'stop_loss_pct': [0.002, 0.0025, 0.003, 0.0035, 0.004, 0.005],
    'take_profit_ratio': [2.0, 2.5, 3.0, 3.5, 4.0, 5.0]
}

print("📊 ESPACE DE RECHERCHE:")
total_combinations = 1
for param, values in param_space.items():
    print(f"   {param}: {len(values)} valeurs")
    total_combinations *= len(values)

print(f"\n   Total combinaisons possibles: {total_combinations:,}")
print(f"   ⚠️  Trop pour tester toutes! On va faire du SMART SAMPLING\n")

# ============ SMART SAMPLING ============

def smart_sample_params():
    """Génère des combinaisons intelligentes au lieu de random pur"""

    # 1. Configs conservatrices (petit, beaucoup de levels)
    conservative = [
        {
            'base_position_size': np.random.choice([1, 2, 3]),
            'max_martingale_level': np.random.choice([8, 9, 10]),
            'base_leverage': np.random.choice([5, 10, 15]),
            'max_leverage': np.random.choice([200, 300, 500]),
            'stop_loss_pct': np.random.choice([0.004, 0.005]),
            'take_profit_ratio': np.random.choice([3.0, 3.5, 4.0])
        }
        for _ in range(10)
    ]

    # 2. Configs agressives (gros, peu de levels)
    aggressive = [
        {
            'base_position_size': np.random.choice([8, 10, 12, 15]),
            'max_martingale_level': np.random.choice([4, 5, 6]),
            'base_leverage': np.random.choice([20, 25, 30, 40, 50]),
            'max_leverage': np.random.choice([500, 750, 1000]),
            'stop_loss_pct': np.random.choice([0.002, 0.0025, 0.003]),
            'take_profit_ratio': np.random.choice([2.0, 2.5, 3.0])
        }
        for _ in range(10)
    ]

    # 3. Configs balancées (milieu)
    balanced = [
        {
            'base_position_size': np.random.choice([4, 5, 6, 7]),
            'max_martingale_level': np.random.choice([6, 7]),
            'base_leverage': np.random.choice([15, 20, 25]),
            'max_leverage': np.random.choice([500, 750]),
            'stop_loss_pct': np.random.choice([0.003, 0.0035]),
            'take_profit_ratio': np.random.choice([2.5, 3.0, 3.5])
        }
        for _ in range(15)
    ]

    # 4. Configs extrêmes (très petits, max levels)
    extreme = [
        {
            'base_position_size': 0.5,
            'max_martingale_level': np.random.choice([10, 11, 12]),
            'base_leverage': np.random.choice([5, 10]),
            'max_leverage': np.random.choice([200, 300]),
            'stop_loss_pct': np.random.choice([0.005, 0.006]),
            'take_profit_ratio': np.random.choice([4.0, 5.0])
        }
        for _ in range(5)
    ]

    # 5. Configs optimisées autour des meilleurs résultats connus
    optimized = [
        {
            'base_position_size': 11.0 + np.random.uniform(-2, 2),
            'max_martingale_level': 6,
            'base_leverage': 20 + np.random.randint(-5, 10),
            'max_leverage': 1000,
            'stop_loss_pct': 0.003 + np.random.uniform(-0.001, 0.001),
            'take_profit_ratio': 3.0 + np.random.uniform(-0.5, 1.0)
        }
        for _ in range(10)
    ]

    return conservative + aggressive + balanced + extreme + optimized

# Générer configs
configs = smart_sample_params()
print(f"🎯 {len(configs)} configurations à tester\n")

# ============ TESTS ============

results = []
best_roi = -999
best_config = None

for i, config in enumerate(configs, 1):
    # Ajout min_signal_score (on s'en fout, c'est random)
    config['min_signal_score'] = 0.0

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

    try:
        strategy = PureMathStrategy(
            math_rule='random',  # PURE RANDOM!
            **config
        )

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

        if result:
            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
            }

            # Score composite
            score = (
                metrics['roi'] * 3.0 +
                (100 - abs(metrics['max_dd'])) * 0.5 +
                metrics['profit_factor'] * 10.0 +
                (metrics['win_rate'] * 100) * 0.2
            )
            metrics['score'] = score

            results.append(metrics)

            # Track best
            if metrics['roi'] > best_roi:
                best_roi = metrics['roi']
                best_config = config.copy()

    except Exception as e:
        # Skip failed configs
        pass

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

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

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

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 "⚠️" if res['roi'] > -2 else "❌"

    lev_str = f"{int(cfg['base_leverage'])}→{int(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']:>7.2f}% {res['win_rate']*100:>4.1f}% {res['profit_factor']:>5.2f} "
          f"{res['max_dd']:>6.2f}% {res['trades']:>3} {res['score']:>7.1f} {status}")

# Meilleure config
if results:
    best = results[0]

    print(f"\n\n{'=' * 80}")
    print(f"🏆 MEILLEURE CONFIGURATION PURE RANDOM")
    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:       {best['max_consec_losses']}")
    print(f"   Score:            {best['score']:.2f}")

    print(f"\n⚙️  PARAMÈTRES MATHÉMATIQUES OPTIMAUX:")
    cfg = best['config']
    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:            {int(cfg['base_leverage'])}x → {int(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")

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

    # Stats trades
    if best['trades'] > 0:
        print(f"\n💰 STATISTIQUES TRADES:")
        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")

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

    # Code Python
    print(f"\n📝 CODE POUR UTILISER:")
    print("=" * 80)
    print(f"""
from true_martingale import PureMathStrategy

strategy = PureMathStrategy(
    math_rule='random',  # PURE RANDOM 50/50
    base_position_size={cfg['base_position_size']},
    max_martingale_level={cfg['max_martingale_level']},
    base_leverage={int(cfg['base_leverage'])},
    max_leverage={int(cfg['max_leverage'])},
    stop_loss_pct={cfg['stop_loss_pct']},
    take_profit_ratio={cfg['take_profit_ratio']},
    min_signal_score=0.0  # Pas de filtre, c'est random!
)

# ROI attendu: {best['roi']:+.2f}%
# Probabilité de ruine: {(0.5 ** (cfg['max_martingale_level'] + 1)) * 100:.4f}%
""")
    print("=" * 80)

    # Sauvegarder
    with open('pure_random_optimization.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: pure_random_optimization.json")

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

else:
    print("\n❌ Aucun résultat valide!")
