"""
Backtest RAPIDE - Focus sur les meilleures configs
"""
import pandas as pd
import numpy as np
from apollo_client import ApolloDegenClient

print('\n' + '='*100)
print('⚡ FAST BACKTEST - Configurations optimales')
print('='*100)

client = ApolloDegenClient()
df = client.get_klines('BTCUSDT', '1m', limit=1500)

print(f'✅ {len(df)} bougies chargées')
print(f'📅 Période: {df.iloc[0]["timestamp"]} → {df.iloc[-1]["timestamp"]}')
print()

# Calculer MA
for period in [10, 20, 30, 50]:
    df[f'ma_{period}'] = df['close'].rolling(period).mean()

# Calculer EMA
df['ema_10'] = df['close'].ewm(span=10).mean()
df['ema_30'] = df['close'].ewm(span=30).mean()
df['ema_12'] = df['close'].ewm(span=12).mean()
df['ema_26'] = df['close'].ewm(span=26).mean()

def backtest_ma(df, ma_period, sl_pct, tp_ratio, leverage):
    """Backtest stratégie MA simple"""
    capital = 100
    trades = []
    ma_col = f'ma_{ma_period}'

    position = None

    for i in range(ma_period + 10, len(df)):
        if pd.isna(df.iloc[i][ma_col]):
            continue

        close = df.iloc[i]['close']
        ma = df.iloc[i][ma_col]

        # Gérer position ouverte
        if position:
            # Check SL/TP
            if position['side'] == 'LONG':
                if close <= position['sl']:
                    pnl_pct = (close - position['entry']) / position['entry']
                    pnl = pnl_pct * leverage * position['margin']
                    capital += pnl
                    trades.append(pnl)
                    position = None
                    continue
                elif close >= position['tp']:
                    pnl_pct = (close - position['entry']) / position['entry']
                    pnl = pnl_pct * leverage * position['margin']
                    capital += pnl
                    trades.append(pnl)
                    position = None
                    continue
            else:  # SHORT
                if close >= position['sl']:
                    pnl_pct = (position['entry'] - close) / position['entry']
                    pnl = pnl_pct * leverage * position['margin']
                    capital += pnl
                    trades.append(pnl)
                    position = None
                    continue
                elif close <= position['tp']:
                    pnl_pct = (position['entry'] - close) / position['entry']
                    pnl = pnl_pct * leverage * position['margin']
                    capital += pnl
                    trades.append(pnl)
                    position = None
                    continue

        # Nouveau signal si pas de position
        if not position and capital > 0:
            side = 'LONG' if close > ma else 'SHORT'

            if side == 'LONG':
                sl = close * (1 - sl_pct)
                tp = close * (1 + sl_pct * tp_ratio)
            else:
                sl = close * (1 + sl_pct)
                tp = close * (1 - sl_pct * tp_ratio)

            margin = capital * 0.05  # 5% risk
            position = {
                'side': side,
                'entry': close,
                'sl': sl,
                'tp': tp,
                'margin': margin
            }

    # Fermer position finale
    if position:
        close = df.iloc[-1]['close']
        if position['side'] == 'LONG':
            pnl_pct = (close - position['entry']) / position['entry']
        else:
            pnl_pct = (position['entry'] - close) / position['entry']
        pnl = pnl_pct * leverage * position['margin']
        capital += pnl
        trades.append(pnl)

    if not trades:
        return None

    ret = ((capital - 100) / 100) * 100
    wins = [t for t in trades if t > 0]
    wr = (len(wins) / len(trades)) * 100 if trades else 0

    return {
        'return': round(ret, 2),
        'trades': len(trades),
        'win_rate': round(wr, 1),
        'wins': len(wins),
        'losses': len(trades) - len(wins),
        'capital': round(capital, 2)
    }

def backtest_ema_cross(df, fast, slow, sl_pct, tp_ratio, leverage):
    """Backtest EMA cross"""
    capital = 100
    trades = []

    ema_fast = f'ema_{fast}'
    ema_slow = f'ema_{slow}'

    position = None

    for i in range(slow + 10, len(df)):
        if pd.isna(df.iloc[i][ema_fast]) or pd.isna(df.iloc[i][ema_slow]):
            continue

        close = df.iloc[i]['close']
        fast_val = df.iloc[i][ema_fast]
        slow_val = df.iloc[i][ema_slow]

        # Gérer position ouverte
        if position:
            # Check SL/TP
            if position['side'] == 'LONG':
                if close <= position['sl']:
                    pnl_pct = (close - position['entry']) / position['entry']
                    pnl = pnl_pct * leverage * position['margin']
                    capital += pnl
                    trades.append(pnl)
                    position = None
                    continue
                elif close >= position['tp']:
                    pnl_pct = (close - position['entry']) / position['entry']
                    pnl = pnl_pct * leverage * position['margin']
                    capital += pnl
                    trades.append(pnl)
                    position = None
                    continue
            else:  # SHORT
                if close >= position['sl']:
                    pnl_pct = (position['entry'] - close) / position['entry']
                    pnl = pnl_pct * leverage * position['margin']
                    capital += pnl
                    trades.append(pnl)
                    position = None
                    continue
                elif close <= position['tp']:
                    pnl_pct = (position['entry'] - close) / position['entry']
                    pnl = pnl_pct * leverage * position['margin']
                    capital += pnl
                    trades.append(pnl)
                    position = None
                    continue

        # Nouveau signal (crossover)
        if not position and capital > 0 and i > 0:
            prev_fast = df.iloc[i-1][ema_fast]
            prev_slow = df.iloc[i-1][ema_slow]

            side = None
            if fast_val > slow_val and prev_fast <= prev_slow:
                side = 'LONG'  # Bullish cross
            elif fast_val < slow_val and prev_fast >= prev_slow:
                side = 'SHORT'  # Bearish cross

            if side:
                if side == 'LONG':
                    sl = close * (1 - sl_pct)
                    tp = close * (1 + sl_pct * tp_ratio)
                else:
                    sl = close * (1 + sl_pct)
                    tp = close * (1 - sl_pct * tp_ratio)

                margin = capital * 0.05
                position = {
                    'side': side,
                    'entry': close,
                    'sl': sl,
                    'tp': tp,
                    'margin': margin
                }

    # Fermer position finale
    if position:
        close = df.iloc[-1]['close']
        if position['side'] == 'LONG':
            pnl_pct = (close - position['entry']) / position['entry']
        else:
            pnl_pct = (position['entry'] - close) / position['entry']
        pnl = pnl_pct * leverage * position['margin']
        capital += pnl
        trades.append(pnl)

    if not trades:
        return None

    ret = ((capital - 100) / 100) * 100
    wins = [t for t in trades if t > 0]
    wr = (len(wins) / len(trades)) * 100 if trades else 0

    return {
        'return': round(ret, 2),
        'trades': len(trades),
        'win_rate': round(wr, 1),
        'wins': len(wins),
        'losses': len(trades) - len(wins),
        'capital': round(capital, 2)
    }

# TESTS
results = []

print('='*100)
print('🧪 TEST 1: STRATÉGIES MA SIMPLES')
print('='*100)
print()

configs_tested = 0
for ma in [10, 20, 30, 50]:
    for sl in [0.0001, 0.00025, 0.0005, 0.001, 0.002]:
        for tp_ratio in [3, 4, 5, 6, 8, 10]:
            for lev in [100, 150, 200, 250]:
                configs_tested += 1
                if configs_tested % 50 == 0:
                    print(f'⏳ Testé: {configs_tested} configs...')

                result = backtest_ma(df, ma, sl, tp_ratio, lev)
                if result:
                    results.append({
                        'strategy': f'MA{ma}',
                        'ma_period': ma,
                        'sl_pct': sl,
                        'tp_ratio': tp_ratio,
                        'leverage': lev,
                        **result
                    })

print(f'✅ {configs_tested} configs MA testées')
print()

print('='*100)
print('🧪 TEST 2: STRATÉGIES EMA CROSS')
print('='*100)
print()

configs_tested = 0
for fast, slow in [(10, 30), (12, 26)]:
    for sl in [0.0001, 0.00025, 0.0005, 0.001, 0.002]:
        for tp_ratio in [3, 4, 5, 6, 8, 10]:
            for lev in [100, 150, 200, 250]:
                configs_tested += 1
                if configs_tested % 50 == 0:
                    print(f'⏳ Testé: {configs_tested} configs...')

                result = backtest_ema_cross(df, fast, slow, sl, tp_ratio, lev)
                if result:
                    results.append({
                        'strategy': f'EMA{fast}x{slow}',
                        'fast': fast,
                        'slow': slow,
                        'sl_pct': sl,
                        'tp_ratio': tp_ratio,
                        'leverage': lev,
                        **result
                    })

print(f'✅ {configs_tested} configs EMA testées')
print()

# Trier et afficher
results.sort(key=lambda x: x['return'], reverse=True)

print('='*100)
print('🏆 TOP 30 CONFIGURATIONS PAR PROFIT TOTAL')
print('='*100)
print()

for i, r in enumerate(results[:30], 1):
    print(f"{i}. {r['strategy']}")
    print(f"   💵 Return: {r['return']:+.2f}% (Capital: ${r['capital']:.2f})")
    print(f"   ✅ Win Rate: {r['win_rate']:.1f}% ({r['wins']}W/{r['losses']}L)")
    print(f"   📈 Trades: {r['trades']}")
    print(f"   ⚙️  SL: {r['sl_pct']*100:.3f}% | TP Ratio: {r['tp_ratio']}:1 | Leverage: {r['leverage']}x")
    print()

# Champion
if results:
    champion = results[0]
    print('='*100)
    print('👑 CHAMPION ABSOLU')
    print('='*100)
    print(f"Stratégie: {champion['strategy']}")
    print(f"Return: {champion['return']:+.2f}%")
    print(f"Win Rate: {champion['win_rate']:.1f}%")
    print(f"Trades: {champion['trades']}")
    print(f"SL: {champion['sl_pct']*100:.3f}%")
    print(f"TP Ratio: {champion['tp_ratio']}:1")
    print(f"Leverage: {champion['leverage']}x")
    print(f"Capital final: ${champion['capital']:.2f}")
    print('='*100)
