# source: https://raw.githubusercontent.com/vigoferrel/qbtc-unified/ef7ffc8f45cc7ab041884cd0c08a2043acc1f0cb/freqtrade_qbtc/strategies/QBTCMomentum.py
"""
Github_vigoferrel_qbtc_unified__QBTCMomentum__20251009_202533 - Estrategia Ultra Simple de Momentum Puro
====================================================

FILOSOFÍA: Solo opera cuando el momentum es OBVIO y FUERTE.
Sin complejidades. Sin múltiples señales. SOLO MOMENTUM + VOLUMEN.

Reglas brutalmente simples:
1. ENTRADA: Precio rompe máximo + volumen alto + tendencia alcista clara
2. SALIDA: Momentum se rompe O objetivo alcanzado
3. STOP: -2% máximo
4. TARGET: +3-5%

Target: 60%+ win rate, profits consistentes, máximo 5 trades por día.

Creado: 2025-09-10
Autor: QBTC Trading System - Momentum Pure
"""

import talib.abstract as ta
import pandas as pd
import numpy as np
from pandas import DataFrame
from freqtrade.strategy.interface import IStrategy
from freqtrade.strategy import DecimalParameter, IntParameter
import logging
from datetime import datetime

class Github_vigoferrel_qbtc_unified__QBTCMomentum__20251009_202533(IStrategy):
    
    # Metadatos ultra simples
    INTERFACE_VERSION = 3
    timeframe = '5m'
    can_short = False
    stoploss = -0.02  # 2% stop loss simple y efectivo
    
    # ROI ultra simple - lo que sabemos que funciona
    minimal_roi = {
        "0": 0.05,    # 5% inmediato
        "30": 0.03,   # 3% después de 30min
        "120": 0.02,  # 2% después de 2h
        "360": 0.01   # 1% después de 6h
    }
    
    # Sin trailing stop - simplicidad pura
    trailing_stop = False
    
    # Configuración conservadora
    max_open_trades = 3  # Máximo 3 trades simultáneos
    stake_currency = 'USDT'
    stake_amount = 100
    use_exit_signal = True
    exit_profit_only = False
    ignore_roi_if_entry_signal = False  # Tomar profits cuando aparezcan
    
    # Órdenes simples
    order_types = {
        'entry': 'market',
        'exit': 'limit',     # Limit para salidas para evitar problemas de config
        'stoploss': 'market',
        'stoploss_on_exchange': False  # Menos complicaciones
    }
    
    order_time_in_force = {
        'entry': 'gtc',
        'exit': 'gtc'
    }
    
    # Parámetros MUY simples - solo los esenciales
    momentum_periods = IntParameter(10, 25, default=20, space="buy")
    volume_multiplier = DecimalParameter(1.5, 3.0, default=2.0, space="buy")
    trend_threshold = DecimalParameter(0.01, 0.03, default=0.015, space="buy")
    
    def __init__(self, config: dict) -> None:
        super().__init__(config)
        self.logger = logging.getLogger(__name__)
        
    def informative_pairs(self):
        return []
    
    def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        """Indicadores MÍNIMOS - solo lo esencial"""
        
        # EMA simple para trend
        dataframe['ema20'] = ta.EMA(dataframe, timeperiod=20)
        dataframe['ema50'] = ta.EMA(dataframe, timeperiod=50)
        
        # RSI solo para evitar comprar muy overbought
        dataframe['rsi'] = ta.RSI(dataframe, timeperiod=14)
        
        # Volumen
        dataframe['volume_sma'] = ta.SMA(dataframe['volume'], timeperiod=20)
        dataframe['volume_ratio'] = dataframe['volume'] / dataframe['volume_sma']
        
        # Máximos para momentum
        dataframe['high_max'] = dataframe['high'].rolling(window=self.momentum_periods.value).max()
        
        # Trend strength simple
        dataframe['trend_strength'] = (dataframe['close'] - dataframe['ema50']) / dataframe['ema50']
        
        return dataframe
    
    def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        """ENTRADA: Solo cuando momentum es OBVIO"""
        
        pair = metadata['pair']
        
        # CONDICIONES ULTRA SIMPLES:
        # 1. Precio rompe máximo reciente
        # 2. Volumen alto
        # 3. Tendencia alcista clara
        # 4. No muy overbought
        
        momentum_breakout = (
            (dataframe['close'] > dataframe['high_max'].shift(1)) &          # Rompe máximo
            (dataframe['volume_ratio'] >= self.volume_multiplier.value) &    # Volumen alto
            (dataframe['close'] > dataframe['ema20']) &                      # Por encima EMA20
            (dataframe['ema20'] > dataframe['ema50']) &                      # EMA20 > EMA50
            (dataframe['trend_strength'] >= self.trend_threshold.value) &    # Trend fuerte
            (dataframe['rsi'] < 75)                                          # No muy overbought
        )
        
        dataframe.loc[momentum_breakout, 'enter_long'] = 1
        dataframe.loc[momentum_breakout, 'enter_tag'] = 'momentum_breakout'
        
        # Log simple
        if momentum_breakout.any():
            self.logger.info(f"🚀 MOMENTUM BREAKOUT: {pair} | Price={dataframe['close'].iloc[-1]:.4f} | Volume={dataframe['volume_ratio'].iloc[-1]:.2f}x")
        
        return dataframe
    
    def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        """SALIDA: Solo cuando momentum se ROMPE claramente"""
        
        # SALIDA ULTRA SIMPLE:
        # 1. Precio por debajo de EMA20 (momentum roto)
        # 2. RSI muy alto (tomar profits)
        
        momentum_broken = (
            (dataframe['close'] < dataframe['ema20']) &     # Momentum roto
            (dataframe['close'] < dataframe['close'].shift(2))  # Confirmación con 2 períodos
        )
        
        take_profits = (
            (dataframe['rsi'] >= 80)  # Muy overbought - tomar profits
        )
        
        exit_conditions = momentum_broken | take_profits
        
        dataframe.loc[exit_conditions, 'exit_long'] = 1
        dataframe.loc[momentum_broken, 'exit_tag'] = 'momentum_broken'
        dataframe.loc[take_profits, 'exit_tag'] = 'take_profits'
        
        return dataframe
    
    def confirm_trade_entry(self, pair: str, order_type: str, amount: float,
                           rate: float, time_in_force: str, current_time: datetime,
                           entry_tag: str, side: str, **kwargs) -> bool:
        """Confirmación final - mantener simplicidad"""
        
        # Solo confirmar si es día de semana (crypto 24/7 pero evitar fines de semana de baja liquidez)
        if current_time.weekday() >= 5:  # Sábado y Domingo
            return False
            
        self.logger.info(f"✅ MOMENTUM ENTRY CONFIRMED: {pair} | Tag: {entry_tag}")
        return True
