# source: https://raw.githubusercontent.com/waleedba19/trading-bot-live/f7eef7897ed63f7c33203aa06a4725d7a8e3c42b/user_data/strategies/FreqaiLgbmRegime.py
# directory_url: https://github.com/waleedba19/trading-bot-live/blob/main/user_data/strategies/
# User: waleedba19
# Repository: trading-bot-live
# --------------------import logging
from functools import reduce

import talib.abstract as ta
from pandas import DataFrame

from freqtrade.strategy import DecimalParameter, IStrategy, informative


logger = logging.getLogger(__name__)


class Github_waleedba19_trading_bot_live__FreqaiLgbmRegime__20261026_210640(IStrategy):
    """
    FreqAI spot long-only strategy used with `--freqaimodel LightGBMRegressor`
    and `user_data/config_freqai.json`.

    Predicts a forward return (`&-fwd_ret`) and enters long when the prediction
    exceeds a hyperoptable threshold and BTC trades above its daily EMA200.
    """

    INTERFACE_VERSION = 3

    timeframe = "1h"
    can_short = False

    process_only_new_candles = True
    startup_candle_count = 4900

    stoploss = -0.05
    trailing_stop = False
    minimal_roi = {"0": 0.10, "720": 0.04, "1440": 0.01}

    entry_thr = DecimalParameter(0.002, 0.03, decimals=3, default=0.01, space="buy")
    exit_thr = DecimalParameter(-0.02, 0.0, decimals=3, default=-0.003, space="sell")

    def feature_engineering_expand_all(
        self, dataframe: DataFrame, period: int, metadata: dict, **kwargs
    ) -> DataFrame:
        dataframe["%-rsi-period"] = ta.RSI(dataframe, timeperiod=period)
        dataframe["%-adx-period"] = ta.ADX(dataframe, timeperiod=period)
        dataframe["%-atr_pct-period"] = ta.ATR(dataframe, timeperiod=period) / dataframe["close"]
        dataframe["%-roc-period"] = ta.ROC(dataframe, timeperiod=period)
        return dataframe

    def feature_engineering_expand_basic(
        self, dataframe: DataFrame, metadata: dict, **kwargs
    ) -> DataFrame:
        dataframe["%-pct-change"] = dataframe["close"].pct_change()
        dataframe["%-ret_4"] = dataframe["close"].pct_change(4)
        dataframe["%-volume_z"] = dataframe["volume"] / dataframe["volume"].rolling(48).mean()
        return dataframe

    def feature_engineering_standard(
        self, dataframe: DataFrame, metadata: dict, **kwargs
    ) -> DataFrame:
        dataframe["%-hour_of_day"] = dataframe["date"].dt.hour
        dataframe["%-day_of_week"] = dataframe["date"].dt.dayofweek
        return dataframe

    def set_freqai_targets(self, dataframe: DataFrame, metadata: dict, **kwargs) -> DataFrame:
        label_period_candles = self.freqai_info["feature_parameters"]["label_period_candles"]
        dataframe["&-fwd_ret"] = (
            dataframe["close"].shift(-label_period_candles) / dataframe["close"] - 1
        )
        return dataframe

    def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        dataframe = self.freqai.start(dataframe, metadata, self)
        return dataframe

    @informative("1d", "BTC/USDT")
    def populate_indicators_btc_1d(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        dataframe["ema200"] = ta.EMA(dataframe, timeperiod=200)
        return dataframe

    def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        enter_long_conditions = [
            dataframe["do_predict"] == 1,
            dataframe["&-fwd_ret"] > self.entry_thr.value,
            dataframe["btc_usdt_close_1d"] > dataframe["btc_usdt_ema200_1d"],
            dataframe["volume"] > 0,
        ]
        if enter_long_conditions:
            dataframe.loc[
                reduce(lambda x, y: x & y, enter_long_conditions), ["enter_long", "enter_tag"]
            ] = (1, "fwd_ret_long")
        return dataframe

    def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        exit_long_conditions = [
            dataframe["do_predict"] == 1,
            dataframe["&-fwd_ret"] < self.exit_thr.value,
        ]
        if exit_long_conditions:
            dataframe.loc[reduce(lambda x, y: x & y, exit_long_conditions), "exit_long"] = 1
        return dataframe
