# source: https://raw.githubusercontent.com/ncu571633/finance/8937995531bd7a90f4ff504ddaeedcfbe790b3d1/freqtrade-bot/user_data/strategies/RSIMeanReversion.py
# directory_url: https://github.com/ncu571633/finance/blob/main/freqtrade-bot/user_data/strategies/
# User: ncu571633
# Repository: finance
# --------------------# Github_ncu571633_finance__RSIMeanReversion__20260918_213038 — a textbook RSI strategy that ACTUALLY trades.
#
# Why this exists: SampleRSIStrategy's entry ("RSI<30 AND close>ema50") never
# fires on 5m data — when RSI(14) drops below 30, price is essentially always
# already below the 50-EMA, so the two conditions are mutually exclusive (0 trades).
#
# This version is the classic mean-reversion setup so we can see real backtest
# numbers. It is STILL not a proven money-maker — pure RSI reversion on crypto
# typically bleeds to fees. Treat the output as a baseline to beat, not a signal.

from pandas import DataFrame
import talib.abstract as ta

from freqtrade.strategy import IStrategy


class Github_ncu571633_finance__RSIMeanReversion__20260918_213038(IStrategy):
    """
    Buy when RSI is oversold (crosses below 30). Sell when RSI is overbought
    (crosses above 70) — plus the ROI ladder and stop-loss below.
    Long-only, spot.
    """

    INTERFACE_VERSION = 3

    timeframe = "5m"
    can_short = False

    # Take-profit ladder: minutes held -> min ROI to exit.
    minimal_roi = {
        "0": 0.03,
        "30": 0.02,
        "60": 0.01,
    }

    stoploss = -0.05
    trailing_stop = False

    startup_candle_count = 30

    def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        dataframe["rsi"] = ta.RSI(dataframe, timeperiod=14)
        return dataframe

    def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        dataframe.loc[
            (
                (dataframe["rsi"] < 30)        # oversold
                & (dataframe["volume"] > 0)    # tradable candle
            ),
            "enter_long",
        ] = 1
        return dataframe

    def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        dataframe.loc[
            (
                (dataframe["rsi"] > 70)        # overbought
                & (dataframe["volume"] > 0)
            ),
            "exit_long",
        ] = 1
        return dataframe
