# source: https://raw.githubusercontent.com/secondlinger/WinnieBari/ea1eff5f193dadf9dcd7940d6bdd9c874968fb05/user_data/strategies/CustomRLStrategy.py
import talib.abstract as ta
from pandas import DataFrame
from sklearn.preprocessing import StandardScaler

from freqtrade.strategy import IStrategy


class Github_secondlinger_WinnieBari__CustomRLStrategy__20250927_010448(IStrategy):
    """
    An effective Reinforcement Learning strategy for FreqAI.
    """
    timeframe = "5m"
    can_short = True

    # RL agent controls exits, so these are disabled.
    stoploss = -0.99
    minimal_roi = {"0": 100}
    trailing_stop = False

    process_only_new_candles = True
    startup_candle_count = 200

    def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        """
        Base indicators for the strategy.
        Keep this minimal as the RL model uses features from feature_engineering_*.
        The main purpose here is to start the FreqAI process.
        """
        # Start FreqAI processing
        dataframe = self.freqai.start(dataframe, metadata, self)
        return dataframe

    def feature_engineering_standard(self, dataframe: DataFrame, **kwargs) -> DataFrame:
        """
        Generate and NORMALIZE features for the RL model.
        All feature columns must be prefixed with '%-'.
        """
        # Create a copy to avoid SettingWithCopyWarning
        df = dataframe.copy()

        # --- Feature Generation ---
        df['%-adx'] = ta.ADX(df)
        df['%-rsi'] = ta.RSI(df)
        ema_20 = ta.EMA(df, timeperiod=20)
        ema_50 = ta.EMA(df, timeperiod=50)

        # Required raw price data (will be normalized)
        df["%-raw_close"] = df["close"]
        df["%-raw_open"] = df["open"]
        df["%-raw_high"] = df["high"]
        df["%-raw_low"] = df["low"]

        for i in range(1, 5):
            df[f'%-return_shift_{i}'] = df['close'].pct_change(i)

        df['%-atr_14'] = ta.ATR(df, timeperiod=14)
        df['%-ema_20_dist'] = (df['close'] - ema_20) / ema_20
        df['%-ema_50_dist'] = (df['close'] - ema_50) / ema_50

        # Fill NaNs created by indicators *before* scaling
        df.fillna(0, inplace=True)

        # --- Feature Normalization ---
        feature_cols = [col for col in df.columns if col.startswith('%-')]
        scaler = StandardScaler()
        df[feature_cols] = scaler.fit_transform(df[feature_cols])

        # Return the modified dataframe
        return df

    def set_freqai_targets(self, dataframe: DataFrame, **kwargs) -> DataFrame:
        """
        This method is required by FreqAI.
        For RL, we simply initialize the action column.
        """
        dataframe["&-action"] = 0
        return dataframe

    def populate_entry_trend(self, df: DataFrame, metadata: dict) -> DataFrame:
        """
        Interpret the RL agent's actions for entries.
        """
        # Long Entry: Action 1
        df.loc[
            (df["do_predict"] == 1) & (df["&-action"] == 1),
            ["enter_long", "enter_tag"]
        ] = (1, f"{metadata['pair']}_long")

        # Short Entry: Action 3
        df.loc[
            (df["do_predict"] == 1) & (df["&-action"] == 3),
            ["enter_short", "enter_tag"]
        ] = (1, f"{metadata['pair']}_short")

        return df

    def populate_exit_trend(self, df: DataFrame, metadata: dict) -> DataFrame:
        """
        Interpret the RL agent's actions for exits.
        """
        # Long Exit: Action 2
        df.loc[
            (df["do_predict"] == 1) & (df["&-action"] == 2),
            "exit_long"
        ] = 1

        # Short Exit: Action 4
        df.loc[
            (df["do_predict"] == 1) & (df["&-action"] == 4),
            "exit_short"
        ] = 1

        return df
