# source: https://raw.githubusercontent.com/kalebCard/MemeHunter/b43704ac2bb204618bb79528999f9f385fb5a921/user_data/strategies/MemeHunter_Moonshot_10x.py
# directory_url: https://github.com/kalebCard/MemeHunter/blob/main/user_data/strategies/
# User: kalebCard
# Repository: MemeHunter
# --------------------"""
Github_kalebCard_MemeHunter__MemeHunter_Moonshot_10x__20261015_051728 - High-Volatility Exponential Compounding Strategy (10x Challenge).
Diseñada específicamente para el experimento de estrés:
- Capital inicial: 10 USDT (Simulado o Aislado).
- Meta cuantitativa: 100 USDT en 7 días (+900% ROI).
- Perfil de riesgo: Ultra-Agresivo (100% Drawdown tolerado por el operador).
- Apalancamiento: 10.0x aislado.
- Timeframe: 15 minutos (Alta frecuencia intradiaria).
"""

from datetime import datetime
from typing import Optional, Dict
import logging

from freqtrade.strategy import IStrategy
from pandas import DataFrame, Series
import pandas_ta as ta
import numpy as np

LOG = logging.getLogger("Moonshot10x")


class Github_kalebCard_MemeHunter__MemeHunter_Moonshot_10x__20261015_051728(IStrategy):
    INTERFACE_VERSION = 3
    timeframe = "15m"
    can_short = True

    # Take Profit Escalonado de Alta Frecuencia (en términos de ROI de posición)
    # A 10x de apalancamiento, 0.10 significa +1% de movimiento en el precio subyacente.
    minimal_roi = {
        "0": 0.25,     # +25% de ROI inmediato (+2.5% precio)
        "15": 0.12,    # +12% si se mantiene 15 min
        "45": 0.06,    # +6% si se mantiene 45 min
        "120": 0.02
    }

    # Stoploss duro preventivo (-4.5% del precio = -45% de margen, evita liquidación en 10x)
    stoploss = -0.045

    # Trailing Stop Dinámico Ultra-Apretado
    trailing_stop = True
    trailing_stop_positive = 0.020           # 2% de retroceso permitido una vez activado
    trailing_stop_positive_offset = 0.050    # Se activa al alcanzar +5% de ganancia en el trade
    trailing_only_offset_is_reached = True

    process_only_new_candles = True
    startup_candle_count: int = 60

    order_types = {
        "entry": "market",
        "exit": "market",
        "emergency_exit": "market",
        "force_entry": "market",
        "force_exit": "market",
        "stoploss": "market",
        "stoploss_on_exchange": False
    }

    order_time_in_force = {
        "entry": "GTC",
        "exit": "GTC"
    }

    def leverage(self, pair: str, current_time: datetime, current_rate: float,
                 proposed_leverage: float, max_leverage: float, entry_tag: Optional[str],
                 side: str, **kwargs) -> float:
        """Apalancamiento agresivo fijo 10.0x para el experimento de aceleración exponencial."""
        return 10.0

    def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        """Cálculo de momentum, volumen relativo y volatilidad en 15m."""
        if dataframe.empty:
            return dataframe

        # 1. EMAs de Momentum Rápido
        dataframe["ema_8"] = ta.ema(dataframe["close"], length=8)
        dataframe["ema_21"] = ta.ema(dataframe["close"], length=21)
        dataframe["ema_55"] = ta.ema(dataframe["close"], length=55)

        # 2. RSI Rápido
        dataframe["rsi"] = ta.rsi(dataframe["close"], length=14)

        # 3. Bandas de Bollinger para atrapar expansiones de volatilidad
        bb = ta.bbands(dataframe["close"], length=20, std=2.0)
        if bb is not None and not bb.empty:
            dataframe["bb_lower"] = bb.iloc[:, 0]
            dataframe["bb_middle"] = bb.iloc[:, 1]
            dataframe["bb_upper"] = bb.iloc[:, 2]
        else:
            dataframe["bb_lower"] = dataframe["close"] * 0.95
            dataframe["bb_upper"] = dataframe["close"] * 1.05

        # 4. Volumen Relativo (RVOL)
        vol_ma = dataframe["volume"].rolling(20, min_periods=1).mean().replace(0, 1.0)
        dataframe["rvol"] = dataframe["volume"] / vol_ma

        # 5. VWAP Intradiario
        typical = (dataframe["high"] + dataframe["low"] + dataframe["close"]) / 3.0
        cum_vol = dataframe["volume"].cumsum().replace(0, 1.0)
        dataframe["vwap"] = (typical * dataframe["volume"]).cumsum() / cum_vol

        return dataframe

    def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        """Gatillos de entrada explosivos en Long y Short."""
        dataframe["enter_long"] = 0
        dataframe["enter_short"] = 0
        dataframe["enter_tag"] = ""

        # GATILLO LONG (Breakout de Momentum con Volumen Anómalo)
        long_cond = (
            (dataframe["close"] > dataframe["vwap"]) &
            (dataframe["ema_8"] > dataframe["ema_21"]) &
            (dataframe["close"] > dataframe["ema_8"]) &
            (dataframe["rvol"] > 1.8) &
            (dataframe["rsi"] > 52) &
            (dataframe["rsi"] < 75)
        )
        dataframe.loc[long_cond, "enter_long"] = 1
        dataframe.loc[long_cond, "enter_tag"] = "moonshot_long_breakout"

        # GATILLO SHORT (Desinflado Rápido post-pump / Caída con volumen)
        short_cond = (
            (dataframe["close"] < dataframe["vwap"]) &
            (dataframe["ema_8"] < dataframe["ema_21"]) &
            (dataframe["close"] < dataframe["ema_8"]) &
            (dataframe["rvol"] > 1.6) &
            (dataframe["rsi"] < 48) &
            (dataframe["rsi"] > 22)
        )
        dataframe.loc[short_cond, "enter_short"] = 1
        dataframe.loc[short_cond, "enter_tag"] = "moonshot_short_exhaustion"

        return dataframe

    def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        """Las salidas principales son gestionadas por Trailing Stop y ROI dinámico."""
        dataframe["exit_long"] = 0
        dataframe["exit_short"] = 0
        return dataframe
