# source: https://raw.githubusercontent.com/huckhuck12/freqtrade-futures-lab/40a97470897a3ebfe2853eca7586a325598dc0f0/user_data/strategies/FutureMeanRevV1.py
from freqtrade.strategy import IStrategy
from pandas import DataFrame
from typing import List
import talib.abstract as ta


class Github_huckhuck12_freqtrade_futures_lab__FutureMeanRevV1__20260122_145205(IStrategy):
    """
    Futures Mean Reversion Strategy V1

    Strategy logic:
    - Uses Bollinger Bands and RSI for mean reversion trading
    - Buy when price touches lower Bollinger Band and RSI < 35
    - Sell when price touches upper Bollinger Band or RSI > 75
    """

    # Base configuration from BaseFuturesStrategy
    minimal_roi = {
        "0": 0.05
    }
    stoploss = -0.03
    trailing_stop = False
    trailing_stop_positive = 0.01
    trailing_stop_positive_offset = 0.02
    trailing_only_offset_is_reached = False
    order_types = {
        'entry': 'limit',
        'exit': 'limit',
        'stoploss': 'market',
        'stoploss_on_exchange': False
    }
    timeframe = '5m'
    stake_amount = 0.01
    startup_candle_count = 300
    unfilledtimeout = {
        'entry': 10,
        'exit': 10,
        'exit_timeout_count': 0,
        'unit': 'seconds'
    }

    # Strategy-specific parameters
    bb_period = 20
    bb_std = 2.0
    rsi_period = 14
    rsi_oversold = 35
    rsi_overbought = 75

    def informative_pairs(self) -> List[tuple]:
        """
        Define informative pairs.
        """
        return []

    def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        """
        Calculate indicators for the strategy.
        """
        bb = ta.BBANDS(dataframe, timeperiod=self.bb_period, nbdevup=self.bb_std, nbdevdn=self.bb_std)
        dataframe['bb_lower'] = bb['lowerband']
        dataframe['bb_middle'] = bb['middleband']
        dataframe['bb_upper'] = bb['upperband']

        dataframe['rsi'] = ta.RSI(dataframe, timeperiod=self.rsi_period)

        dataframe['bb_position'] = (dataframe['close'] - dataframe['bb_lower']) / (dataframe['bb_upper'] - dataframe['bb_lower'])

        return dataframe

    def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        """
        Entry signal logic.
        """
        dataframe.loc[
            (dataframe['bb_position'] < 0.05) &
            (dataframe['rsi'] < self.rsi_oversold) &
            (dataframe['volume'] > 0),
            'enter_long'
        ] = 1

        return dataframe

    def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        """
        Exit signal logic.
        """
        dataframe.loc[
            (
                (dataframe['bb_position'] > 0.95) |
                (dataframe['rsi'] > self.rsi_overbought)
            ) &
            (dataframe['volume'] > 0),
            'exit'
        ] = 1

        return dataframe
