# source: https://raw.githubusercontent.com/prcasley/options-profit-calculator/5701063dafb1a70d16ab2bab516d4b8cc023de06/trading-backend/freqtrade/user_data/strategies/RSIMACDStrategy.py
"""
RSI + MACD Strategy for Freqtrade
Combines RSI oversold/overbought with MACD crossovers
"""
import talib.abstract as ta
from pandas import DataFrame
from freqtrade.strategy import IStrategy, IntParameter, DecimalParameter
from freqtrade.persistence import Trade
from datetime import datetime
import logging

logger = logging.getLogger(__name__)


class Github_prcasley_options_profit_calculator__RSIMACDStrategy__20260125_054625(IStrategy):
    """
    RSI + MACD Crossover Strategy

    Buy when:
    - RSI is oversold (< 35)
    - MACD crosses above signal line
    - Price is above 200 EMA (trend filter)

    Sell when:
    - RSI is overbought (> 75)
    - MACD crosses below signal line
    """

    # Strategy interface version
    INTERFACE_VERSION = 3

    # Optimal timeframe for this strategy
    timeframe = '5m'

    # Can this strategy go short?
    can_short = False

    # Minimal ROI designed for the strategy
    minimal_roi = {
        "0": 0.10,    # 10% profit target
        "30": 0.05,   # 5% after 30 minutes
        "60": 0.025,  # 2.5% after 1 hour
        "120": 0.01   # 1% after 2 hours
    }

    # Optimal stoploss
    stoploss = -0.10  # -10%

    # Trailing stop
    trailing_stop = True
    trailing_stop_positive = 0.01
    trailing_stop_positive_offset = 0.02
    trailing_only_offset_is_reached = True

    # Run "populate_indicators()" only for new candle
    process_only_new_candles = True

    # Use exit signal
    use_exit_signal = True
    exit_profit_only = False
    ignore_roi_if_entry_signal = False

    # Hyperoptable parameters
    buy_rsi = IntParameter(20, 40, default=35, space="buy", optimize=True)
    sell_rsi = IntParameter(60, 85, default=75, space="sell", optimize=True)

    # Protections
    startup_candle_count: int = 200

    @property
    def protections(self):
        return [
            {
                "method": "CooldownPeriod",
                "stop_duration_candles": 5
            },
            {
                "method": "MaxDrawdown",
                "trade_limit": 20,
                "stop_duration_candles": 30,
                "max_allowed_drawdown": 0.20  # 20% max drawdown
            },
            {
                "method": "StoplossGuard",
                "trade_limit": 4,
                "stop_duration_candles": 30,
                "only_per_pair": False
            }
        ]

    def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        """
        Adds several different TA indicators to the given DataFrame
        """
        # RSI
        dataframe['rsi'] = ta.RSI(dataframe, timeperiod=14)

        # MACD
        macd = ta.MACD(dataframe, fastperiod=12, slowperiod=26, signalperiod=9)
        dataframe['macd'] = macd['macd']
        dataframe['macdsignal'] = macd['macdsignal']
        dataframe['macdhist'] = macd['macdhist']

        # Moving Averages
        dataframe['sma_20'] = ta.SMA(dataframe, timeperiod=20)
        dataframe['sma_50'] = ta.SMA(dataframe, timeperiod=50)
        dataframe['ema_200'] = ta.EMA(dataframe, timeperiod=200)

        # Bollinger Bands
        bollinger = ta.BBANDS(dataframe, timeperiod=20, nbdevup=2.0, nbdevdn=2.0)
        dataframe['bb_upper'] = bollinger['upperband']
        dataframe['bb_middle'] = bollinger['middleband']
        dataframe['bb_lower'] = bollinger['lowerband']

        # ATR for volatility
        dataframe['atr'] = ta.ATR(dataframe, timeperiod=14)

        # Volume indicators
        dataframe['volume_sma'] = ta.SMA(dataframe['volume'], timeperiod=20)

        return dataframe

    def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        """
        Based on TA indicators, populates the entry signal for the given dataframe
        """
        dataframe.loc[
            (
                # RSI oversold
                (dataframe['rsi'] < self.buy_rsi.value) &
                # MACD bullish crossover
                (dataframe['macd'] > dataframe['macdsignal']) &
                (dataframe['macd'].shift(1) <= dataframe['macdsignal'].shift(1)) &
                # Price above 200 EMA (uptrend)
                (dataframe['close'] > dataframe['ema_200']) &
                # Volume confirmation
                (dataframe['volume'] > dataframe['volume_sma'] * 0.5) &
                # Ensure we have data
                (dataframe['volume'] > 0)
            ),
            'enter_long'] = 1

        return dataframe

    def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        """
        Based on TA indicators, populates the exit signal for the given dataframe
        """
        dataframe.loc[
            (
                # RSI overbought
                (dataframe['rsi'] > self.sell_rsi.value) &
                # MACD bearish crossover
                (dataframe['macd'] < dataframe['macdsignal']) &
                (dataframe['macd'].shift(1) >= dataframe['macdsignal'].shift(1)) &
                # Volume confirmation
                (dataframe['volume'] > 0)
            ),
            'exit_long'] = 1

        return dataframe

    def custom_stake_amount(
        self,
        pair: str,
        current_time: datetime,
        current_rate: float,
        proposed_stake: float,
        min_stake: float | None,
        max_stake: float,
        leverage: float,
        entry_tag: str | None,
        side: str,
        **kwargs
    ) -> float:
        """
        Custom stake amount - uses 10% of available balance per trade
        """
        return proposed_stake * 0.10

    def leverage(
        self,
        pair: str,
        current_time: datetime,
        current_rate: float,
        proposed_leverage: float,
        max_leverage: float,
        entry_tag: str | None,
        side: str,
        **kwargs
    ) -> float:
        """
        Customize leverage for each new trade - no leverage for this strategy
        """
        return 1.0
