# source: https://raw.githubusercontent.com/vigoferrel/qbtc-unified/ef7ffc8f45cc7ab041884cd0c08a2043acc1f0cb/freqtrade_qbtc/strategies/QBTCSimpleTest.py
# pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement
# flake8: noqa: F401
# isort: skip_file

"""
🌌 QBTC SIMPLE TEST STRATEGY - Para validar generación de trades 🌌
Estrategia super simple diseñada para generar trades garantizados en backtesting
"""

import numpy as np
import pandas as pd
from pandas import DataFrame
from typing import Optional, Union, Dict, List, Tuple, Any
import logging

# Freqtrade imports
from freqtrade.strategy import (
    IStrategy,
    Trade,
    Order,
    PairLocks,
    informative,
    BooleanParameter,
    CategoricalParameter,
    DecimalParameter,
    IntParameter,
    RealParameter,
    timeframe_to_minutes,
    merge_informative_pair,
    stoploss_from_absolute,
    stoploss_from_open,
)

import talib.abstract as ta
from technical import qtpylib


class Github_vigoferrel_qbtc_unified__QBTCSimpleTest__20251009_202533(IStrategy):
    """
    🌊 QBTC Simple Test Strategy - Solo para testing
    
    Estrategia ultra-simple que genera trades basada en:
    - RSI oversold/overbought básico
    - MACD cruzamientos simples 
    - Condiciones muy permisivas
    """
    
    # ==================== CONFIGURACIÓN BÁSICA ====================
    
    INTERFACE_VERSION = 3
    can_short: bool = False
    
    # Configuración de timeframes
    timeframe = '15m'
    startup_candle_count: int = 50  # Mínimo para funcionar
    
    # ==================== ROI Y STOP LOSS SIMPLES ====================
    
    minimal_roi = {
        "0": 0.10,      # 10% ROI inmediato
        "30": 0.05,     # 5% después de 30 min  
        "60": 0.02,     # 2% después de 1h
        "120": 0.01,    # 1% después de 2h
    }
    
    stoploss = -0.05  # Stop loss simple 5%
    
    # Sin trailing stop para simplicidad
    trailing_stop = False
    
    # ==================== PARÁMETROS DE COMPRA Y VENTA ====================
    
    # Parámetros de entrada (BUY) - MUY PERMISIVOS
    rsi_buy = IntParameter(20, 40, default=35, space="buy", optimize=True)
    
    # Parámetros de salida (SELL) - MUY PERMISIVOS
    rsi_sell = IntParameter(60, 80, default=65, space="sell", optimize=True)
    
    def __init__(self, config: dict) -> None:
        super().__init__(config)
        self.logger = logging.getLogger(__name__)
    
    # ==================== INDICADORES TÉCNICOS MÍNIMOS ====================
    
    def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        """
        Indicadores súper simples - solo lo esencial
        """
        
        # RSI básico
        dataframe['rsi'] = ta.RSI(dataframe, timeperiod=14)
        
        # MACD básico
        macd = ta.MACD(dataframe, fastperiod=12, slowperiod=26, signalperiod=9)
        dataframe['macd'] = macd['macd']
        dataframe['macdsignal'] = macd['macdsignal']
        
        # EMA simple para tendencia
        dataframe['ema20'] = ta.EMA(dataframe, timeperiod=20)
        
        # Volumen simple
        dataframe['volume_sma'] = ta.SMA(dataframe['volume'], timeperiod=10)
        
        return dataframe
    
    # ==================== LÓGICA DE ENTRADA ULTRA-SIMPLE ====================
    
    def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        """
        Lógica de entrada súper simple - casi cualquier condición genera trade
        """
        
        dataframe.loc[
            (
                # RSI oversold simple
                (dataframe['rsi'] < self.rsi_buy.value) &
                
                # MACD cruzamiento alcista
                (dataframe['macd'] > dataframe['macdsignal']) &
                
                # Precio por encima de EMA (tendencia alcista básica)
                (dataframe['close'] > dataframe['ema20']) &
                
                # Volumen mínimo
                (dataframe['volume'] > dataframe['volume_sma'] * 0.8) &
                
                # Condición básica de validez
                (dataframe['volume'] > 0)
            ),
            'enter_long'] = 1
        
        return dataframe
    
    # ==================== LÓGICA DE SALIDA ULTRA-SIMPLE ====================
    
    def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        """
        Lógica de salida súper simple - vende en overbought o divergencia
        """
        
        dataframe.loc[
            (
                # RSI overbought simple
                (dataframe['rsi'] > self.rsi_sell.value) |
                
                # MACD cruzamiento bajista
                (
                    (dataframe['macd'] < dataframe['macdsignal']) &
                    (dataframe['rsi'] > 50)  # Solo si no está muy oversold
                ) |
                
                # Precio por debajo de EMA con RSI alto
                (
                    (dataframe['close'] < dataframe['ema20']) &
                    (dataframe['rsi'] > 55)
                )
            ),
            'exit_long'] = 1
        
        return dataframe
