# source: https://raw.githubusercontent.com/Aymane-lahlou/Trading_Binance/148f98ac091892ec2846a4f1f51dc566e8dfd47e/user_data/strategies/HalalSpotStrategy.py
from pandas import DataFrame
import talib.abstract as ta

from freqtrade.strategy import IStrategy, merge_informative_pair


class Github_Aymane_lahlou_Trading_Binance__HalalSpotStrategy__20260614_131529(IStrategy):
    INTERFACE_VERSION = 3

    timeframe = "15m"
    # Higher timeframe used to confirm the broader trend before entering.
    informative_timeframe = "4h"
    can_short = False

    minimal_roi = {
        "0": 0.03,
        "60": 0.015,
        "180": 0.005,
    }

    stoploss = -0.06

    # Trailing stop lets winners run past the 3% ROI cap.
    trailing_stop = True
    trailing_stop_positive = 0.015
    trailing_stop_positive_offset = 0.03
    trailing_only_offset_is_reached = True

    process_only_new_candles = True
    startup_candle_count = 200

    # Protections guard against whipsaw re-entries and drawdown clusters.
    @property
    def protections(self):
        return [
            {
                "method": "CooldownPeriod",
                "stop_duration_candles": 4,
            },
            {
                "method": "StoplossGuard",
                "lookback_period_candles": 24,
                "trade_limit": 2,
                "stop_duration_candles": 12,
                "only_per_pair": True,
            },
            {
                "method": "MaxDrawdown",
                "lookback_period_candles": 48,
                "trade_limit": 4,
                "stop_duration_candles": 12,
                "max_allowed_drawdown": 0.1,
            },
        ]

    def informative_pairs(self):
        pairs = self.dp.current_whitelist()
        return [(pair, self.informative_timeframe) for pair in pairs]

    def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        dataframe["rsi"] = ta.RSI(dataframe, timeperiod=14)
        dataframe["sma_fast"] = ta.SMA(dataframe, timeperiod=20)
        dataframe["sma_slow"] = ta.SMA(dataframe, timeperiod=50)
        dataframe["volume_mean"] = dataframe["volume"].rolling(20).mean()

        # Higher-timeframe trend filter (4h SMA50).
        informative = self.dp.get_pair_dataframe(
            pair=metadata["pair"], timeframe=self.informative_timeframe
        )
        informative["sma_trend"] = ta.SMA(informative, timeperiod=50)
        dataframe = merge_informative_pair(
            dataframe, informative, self.timeframe, self.informative_timeframe, ffill=True
        )

        return dataframe

    def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        htf_close = f"close_{self.informative_timeframe}"
        htf_trend = f"sma_trend_{self.informative_timeframe}"
        dataframe.loc[
            (
                (dataframe["rsi"] < 35)
                & (dataframe["sma_fast"] > dataframe["sma_slow"])
                # Only buy dips while the 4h trend is up.
                & (dataframe[htf_close] > dataframe[htf_trend])
                & (dataframe["volume"] > dataframe["volume_mean"])
                & (dataframe["volume"] > 0)
            ),
            "enter_long",
        ] = 1
        return dataframe

    def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        dataframe.loc[
            (
                (dataframe["rsi"] > 70)
                | (dataframe["sma_fast"] < dataframe["sma_slow"])
            ),
            "exit_long",
        ] = 1
        return dataframe
