#!/usr/bin/env python3
"""
OPTIMISER LA STRATÉGIE GAGNANTE

Meilleure trouvée: ETH 1h Volatility Expansion (+1.71%, 100% WR)

On optimise:
1. Leverage (actuellement 12x)
2. Seuils TP/SL
3. Taille de position
4. Multiplicateur ATR
5. Combo avec d'autres filtres
"""

import pandas as pd
import numpy as np
from martingale_backtester import MartingaleBacktester
import json

print("=" * 80)
print("🔥 OPTIMISATION STRATÉGIE GAGNANTE - VOLATILITY EXPANSION")
print("=" * 80)

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

print("\n📥 Téléchargement ETH 1h...")
df = backtester.fetch_binance_data('ETHUSDT', '1h', 500)  # Plus de données!
print(f"✅ {len(df)} bougies\n")

def backtest_volatility(df, leverage=12, tp_pct=1.5, sl_pct=1.0, atr_multi=2.0, position_size=10):
    """Backtest Volatility Expansion optimisé"""

    capital = 1000.0
    position = None
    trades = []
    max_dd = 0
    peak = capital

    for i in range(51, len(df)):
        current = df.iloc[i]
        recent = df.iloc[i-50:i]

        # Sortie de position
        if position is not None:
            # TP/SL
            if position['side'] == 'LONG':
                tp = position['entry'] * (1 + tp_pct/100)
                sl = position['entry'] * (1 - sl_pct/100)
                hit_tp = current['close'] >= tp
                hit_sl = current['close'] <= sl
            else:
                tp = position['entry'] * (1 - tp_pct/100)
                sl = position['entry'] * (1 + sl_pct/100)
                hit_tp = current['close'] <= tp
                hit_sl = current['close'] >= sl

            if hit_tp or hit_sl:
                # Calculer PnL
                if position['side'] == 'LONG':
                    pnl_pct = (current['close'] - position['entry']) / position['entry']
                else:
                    pnl_pct = (position['entry'] - current['close']) / position['entry']

                pnl_pct *= leverage
                pnl_pct -= 0.001  # Frais

                pnl_usd = position_size * pnl_pct
                capital += pnl_usd

                # Drawdown
                if capital > peak:
                    peak = capital
                dd = ((peak - capital) / peak) * 100
                if dd > max_dd:
                    max_dd = dd

                trades.append({
                    'pnl_usd': pnl_usd,
                    'pnl_pct': pnl_pct * 100,
                    'won': pnl_usd > 0,
                    'exit_type': 'TP' if hit_tp else 'SL'
                })

                position = None

        # Entrée de position
        if position is None:
            # ATR
            high_low = recent['high'] - recent['low']
            atr = high_low.mean()
            current_range = current['high'] - current['low']

            # Range actuel > atr_multi x ATR moyen
            if current_range > atr * atr_multi:
                # Direction du mouvement
                if current['close'] > current['open']:
                    side = 'LONG'
                else:
                    side = 'SHORT'

                position = {
                    'entry': current['close'],
                    'side': side
                }

    # Stats
    if not trades:
        return None

    wins = [t for t in trades if t['won']]
    losses = [t for t in trades if not t['won']]

    total_return = ((capital - 1000) / 1000) * 100
    win_rate = len(wins) / len(trades)
    avg_win = np.mean([t['pnl_pct'] for t in wins]) if wins else 0
    avg_loss = np.mean([t['pnl_pct'] for t in losses]) if losses else 0
    profit_factor = abs(sum([t['pnl_usd'] for t in wins]) / sum([t['pnl_usd'] for t in losses])) if losses else 999

    return {
        'roi': total_return,
        'capital': capital,
        'trades': len(trades),
        'win_rate': win_rate,
        'avg_win': avg_win,
        'avg_loss': avg_loss,
        'profit_factor': profit_factor,
        'max_dd': max_dd
    }

# ============ OPTIMISATION ============

print("🔬 OPTIMISATION PARAMÈTRES...")
print("=" * 80)

results = []

# Grilles de paramètres à tester
leverages = [5, 8, 10, 12, 15, 20, 25, 30, 50]
tp_pcts = [1.0, 1.5, 2.0, 2.5, 3.0, 4.0, 5.0]
sl_pcts = [0.5, 0.75, 1.0, 1.25, 1.5, 2.0]
atr_multis = [1.5, 2.0, 2.5, 3.0]
position_sizes = [10, 15, 20, 25, 30, 40, 50]

# Smart sampling
num_tests = 200
best_roi = -999

for i in range(num_tests):
    lev = np.random.choice(leverages)
    tp = np.random.choice(tp_pcts)
    sl = np.random.choice(sl_pcts)
    atr_m = np.random.choice(atr_multis)
    pos_size = np.random.choice(position_sizes)

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

    try:
        result = backtest_volatility(df, lev, tp, sl, atr_m, pos_size)

        if result:
            result['config'] = {
                'leverage': lev,
                'tp_pct': tp,
                'sl_pct': sl,
                'atr_multi': atr_m,
                'position_size': pos_size
            }
            results.append(result)

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

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

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

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

print(f"\n{'#':<3} {'Lev':>4} {'TP%':>5} {'SL%':>5} {'ATR':>5} {'Size':>5} "
      f"{'ROI%':>7} {'WR%':>5} {'PF':>6} {'Tr':>4} {'DD%':>6}")
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'] > 10 else "⚠️" if res['roi'] > 5 else "🔵" if res['roi'] > 0 else "❌"

    print(f"{emoji:<3} {cfg['leverage']:>4}x {cfg['tp_pct']:>4.1f}% {cfg['sl_pct']:>4.1f}% "
          f"{cfg['atr_multi']:>4.1f}x {cfg['position_size']:>5.0f} "
          f"{res['roi']:>6.2f}% {res['win_rate']*100:>4.1f}% {res['profit_factor']:>6.2f} "
          f"{res['trades']:>4} {res['max_dd']:>5.2f}% {status}")

# Meilleur
best = top_20[0]

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

cfg = best['config']

print(f"\n📊 PERFORMANCE:")
print(f"   Symbol:            ETHUSDT")
print(f"   Timeframe:         1h")
print(f"   Stratégie:         Volatility Expansion (optimisée)")
print(f"   ROI:               {best['roi']:+.2f}% {'🚀 EXCELLENT!' if best['roi'] > 20 else '✅ TRÈS BON!' if best['roi'] > 10 else '✅ BON' if best['roi'] > 5 else '⚠️'}")
print(f"   Capital final:     ${best['capital']:.2f}")
print(f"   Gain:              ${best['capital'] - 1000:.2f}")
print(f"   Trades:            {best['trades']}")
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}%")

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 999
    print(f"   Ratio Gain/Perte:  {ratio:.2f}x")

print(f"\n⚙️  PARAMÈTRES OPTIMAUX:")
print(f"   Leverage:          {cfg['leverage']}x")
print(f"   Take Profit:       {cfg['tp_pct']:.1f}%")
print(f"   Stop Loss:         {cfg['sl_pct']:.1f}%")
print(f"   ATR Multiplier:    {cfg['atr_multi']:.1f}x")
print(f"   Position Size:     ${cfg['position_size']:.0f}")

print(f"\n💡 LOGIQUE:")
print(f"   1. Calculer ATR moyen des 50 dernières bougies 1h")
print(f"   2. Si bougie actuelle range > {cfg['atr_multi']:.1f}x ATR → SIGNAL")
print(f"   3. Direction: bougie verte = LONG, bougie rouge = SHORT")
print(f"   4. Leverage {cfg['leverage']}x, TP {cfg['tp_pct']:.1f}%, SL {cfg['sl_pct']:.1f}%")

print(f"\n🧮 EXPECTANCY:")
win_expectancy = best['win_rate'] * best['avg_win']
loss_expectancy = (1 - best['win_rate']) * abs(best['avg_loss'])
expectancy = win_expectancy - loss_expectancy
print(f"   Expectancy par trade: {expectancy:+.2f}%")
print(f"   Sur 100 trades:       {expectancy * 100:+.2f}%")

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

# Code Python
print(f"\n📝 CODE PRÊT À L'EMPLOI:")
print("=" * 80)
print(f"""
# Volatility Expansion - ETH 1h - Configuration Optimale

def volatility_expansion_signal(df, i):
    recent = df.iloc[i-50:i]
    current = df.iloc[i]

    # ATR
    high_low = recent['high'] - recent['low']
    atr = high_low.mean()
    current_range = current['high'] - current['low']

    # Signal si range > {cfg['atr_multi']:.1f}x ATR
    if current_range > atr * {cfg['atr_multi']}:
        if current['close'] > current['open']:
            return 'LONG'
        else:
            return 'SHORT'
    return None

# Paramètres:
LEVERAGE = {cfg['leverage']}
TAKE_PROFIT = {cfg['tp_pct']:.1f}%  # {cfg['tp_pct']/100 * cfg['leverage']:.1f}% avec leverage
STOP_LOSS = {cfg['sl_pct']:.1f}%   # {cfg['sl_pct']/100 * cfg['leverage']:.1f}% avec leverage
POSITION_SIZE = ${cfg['position_size']:.0f}

# Performance attendue:
# ROI: {best['roi']:+.2f}%
# Win Rate: {best['win_rate']*100:.1f}%
# Expectancy: {expectancy:+.2f}% par trade
""")
print("=" * 80)

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

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

# Comparaison
print(f"\n📊 COMPARAISON:")
print(f"   Martingale (always_long):         +3.67% ROI")
print(f"   Volatility Expansion (baseline):  +1.71% ROI")
print(f"   Volatility Expansion (OPTIMISÉ):  {best['roi']:+.2f}% ROI")

if best['roi'] > 3.67:
    improvement = best['roi'] - 3.67
    print(f"\n🎉 MEILLEUR QUE LA MARTINGALE! +{improvement:.2f}%")
elif best['roi'] > 10:
    print(f"\n🚀 EXCELLENTE ESPÉRANCE POSITIVE TROUVÉE!")
elif best['roi'] > 5:
    print(f"\n✅ BONNE ESPÉRANCE POSITIVE!")

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