# source: https://raw.githubusercontent.com/remiotore/freqtrade/44beaeb6a420cd8e9f2e4ea93e11d6cfa192ee03/strategies/NASOSv4Futures_20250131_1445.py
from freqtrade.strategy.interface import IStrategy
from pandas import DataFrame
import talib.abstract as ta
import freqtrade.vendor.qtpylib.indicators as qtpylib
from freqtrade.strategy import stoploss_from_open
from functools import reduce
import logging

logger = logging.getLogger(__name__)

class Github_remiotore_freqtrade__NASOSv4Futures_20250131_1445__20260111_210550(IStrategy):
    INTERFACE_VERSION = 3

    # ✅ Ativar suporte para Futures (Long e Short)
    can_short = True  

    # ✅ ROI otimizado para Futures (lucro rápido e seguro)
    minimal_roi = {
        "0": 0.04,   # 4% imediato
        "30": 0.03,  # 3% após 30 min
        "120": 0.02, # 2% após 2h
        "240": 0     # Sem limite após 4h
    }

    # ✅ Stoploss reduzido para evitar liquidações
    stoploss = -0.025  # Apenas 2.5% de perda

    # ✅ Trailing Stop ativado para capturar lucros
    trailing_stop = True
    trailing_stop_positive = 0.015  # 1.5%
    trailing_stop_positive_offset = 0.02  # 2%
    trailing_only_offset_is_reached = True

    timeframe = "5m"
    startup_candle_count = 50  

    # ✅ Definição dos tipos de ordem para evitar slippage
    order_types = {
        "buy": "market",
        "sell": "market",
        "stoploss": "market",
        "forcebuy": "market",
        "stoploss_on_exchange": False
    }

    def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        """Calcula indicadores técnicos essenciais para Futures."""

        dataframe["ema_50"] = ta.EMA(dataframe, timeperiod=50)
        dataframe["ema_200"] = ta.EMA(dataframe, timeperiod=200)
        dataframe["rsi"] = ta.RSI(dataframe, timeperiod=14)
        dataframe["atr"] = ta.ATR(dataframe, timeperiod=14)
        dataframe["volume_mean"] = dataframe["volume"].rolling(window=20).mean()

        # ✅ Proteção contra volatilidade extrema
        dataframe["atr_percent"] = dataframe["atr"] / dataframe["close"]

        return dataframe

    def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        """Define regras para abrir posições LONG e SHORT."""

        # ✅ Condições para entrada em LONG (compra)
        long_conditions = [
            (dataframe["rsi"] < 50),  
            (dataframe["volume"] > dataframe["volume_mean"] * 0.8),  
            (dataframe["atr_percent"] < dataframe["atr_percent"].rolling(window=50).mean() * 2),  
            (dataframe["close"] > dataframe["ema_50"]) | (dataframe["close"] < dataframe["ema_50"] * 1.02)
        ]

        dataframe.loc[
            reduce(lambda x, y: x & y, long_conditions), "enter_long"
        ] = 1

        # ✅ Condições para entrada em SHORT (venda primeiro)
        short_conditions = [
            (dataframe["rsi"] > 60),  
            (dataframe["volume"] > dataframe["volume_mean"] * 0.8),  
            (dataframe["atr_percent"] < dataframe["atr_percent"].rolling(window=50).mean() * 2),  
            (dataframe["close"] < dataframe["ema_50"]) | (dataframe["close"] > dataframe["ema_50"] * 0.98)
        ]

        dataframe.loc[
            reduce(lambda x, y: x & y, short_conditions), "enter_short"
        ] = 1

        return dataframe

    def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        """Define regras para fechar posições LONG e SHORT."""

        # ✅ Condições para saída de LONG (venda)
        long_exit_conditions = [
            (dataframe["rsi"] > 70),
            (dataframe["close"] < dataframe["ema_50"]),
            (dataframe["atr_percent"] > dataframe["atr_percent"].rolling(window=50).mean() * 1.5)
        ]

        dataframe.loc[
            reduce(lambda x, y: x & y, long_exit_conditions), "exit_long"
        ] = 1

        # ✅ Condições para saída de SHORT (recompra)
        short_exit_conditions = [
            (dataframe["rsi"] < 40),
            (dataframe["close"] > dataframe["ema_50"]),
            (dataframe["atr_percent"] > dataframe["atr_percent"].rolling(window=50).mean() * 1.5)
        ]

        dataframe.loc[
            reduce(lambda x, y: x & y, short_exit_conditions), "exit_short"
        ] = 1

        return dataframe

    def leverage(self, pair: str, current_time, current_rate: float, proposed_leverage: float, max_leverage: float, side: str, **kwargs) -> float:
        """Ajusta a alavancagem dinamicamente com base no ATR."""

        dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
        atr = dataframe["atr"].iloc[-1]

        # ✅ Maior volatilidade = menor alavancagem
        dynamic_leverage = max(1.0, min(max_leverage, 2.0 / atr))
        return dynamic_leverage
