# source: https://raw.githubusercontent.com/vaskosmihaylov/nfi-custom-strategies/b23e746f700dc883ac477519ed366fc8cb8c66d1/user_data/strategies/e0v1e/binance_shorts_ai.py
from datetime import datetime, timedelta
from typing import Optional, Union
import logging
import talib.abstract as ta
import pandas_ta as pta
from freqtrade.persistence import Trade
from freqtrade.strategy.interface import IStrategy
from pandas import DataFrame
from freqtrade.strategy import DecimalParameter, IntParameter
from functools import reduce


logger = logging.getLogger(__name__)


class Github_vaskosmihaylov_nfi_custom_strategies__binance_shorts_ai__20260319_072537(IStrategy):
    INTERFACE_VERSION = 3
    can_short = True

    minimal_roi = {
        "0": 0.03
    }

    timeframe = "5m"
    process_only_new_candles = True
    startup_candle_count = 120

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

    stoploss = -0.25
    use_custom_stoploss = True

    is_optimize_32 = False
    buy_rsi_fast_32 = IntParameter(20, 70, default=45, space="buy", optimize=is_optimize_32)
    buy_rsi_32 = IntParameter(15, 50, default=35, space="buy", optimize=is_optimize_32)
    buy_sma15_32 = DecimalParameter(0.900, 1, default=0.961, decimals=3, space="buy", optimize=is_optimize_32)
    buy_cti_32 = DecimalParameter(-1, 0, default=-0.58, decimals=2, space="buy", optimize=is_optimize_32)

    sell_fastx = IntParameter(50, 100, default=75, space="sell", optimize=False)

    def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        dataframe["sma_15"] = ta.SMA(dataframe, timeperiod=15)
        dataframe["cti"] = pta.cti(dataframe["close"], length=20)
        dataframe["rsi"] = ta.RSI(dataframe, timeperiod=14)
        dataframe["rsi_fast"] = ta.RSI(dataframe, timeperiod=4)
        dataframe["rsi_slow"] = ta.RSI(dataframe, timeperiod=20)
        stoch_fast = ta.STOCHF(dataframe, 5, 3, 0, 3, 0)
        dataframe["fastk"] = stoch_fast["fastk"]
        dataframe["rsi_shifted"] = dataframe["rsi_slow"].shift(1)
        return dataframe

    def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        enter_short_conditions = [
            (dataframe["rsi_slow"] > dataframe["rsi_shifted"]),
            (dataframe["rsi_fast"] > self.buy_rsi_fast_32.value),
            (dataframe["rsi"] < self.buy_rsi_32.value),
            (dataframe["close"] > dataframe["sma_15"] * self.buy_sma15_32.value),
            (dataframe["cti"] > self.buy_cti_32.value),
        ]

        if enter_short_conditions:
            dataframe.loc[
                reduce(lambda x, y: x & y, enter_short_conditions),
                ["enter_short", "enter_tag"],
            ] = (1, "short_ai")

        return dataframe

    def custom_stoploss(
        self,
        pair: str,
        trade: Trade,
        current_time: datetime,
        current_rate: float,
        current_profit: float,
        **kwargs,
    ) -> float:
        dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
        current_candle = dataframe.iloc[-1].squeeze()

        if current_profit >= 0.08:
            return -0.01

        if current_profit > 0:
            if current_candle["fastk"] > self.sell_fastx.value:
                return -0.001

        if current_time - timedelta(hours=4) > trade.open_date_utc:
            if current_profit > -0.03:
                return -0.005

        return self.stoploss

    def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        dataframe.loc[:, ["exit_short", "exit_tag"]] = (0, "short_out")
        return dataframe
