# source: https://raw.githubusercontent.com/sanweisg/jadebot/7f10332553b784bf5846ebc7056b2d4c7d04c917/user_data/strategies/MultiIndicatorRSI.py
# directory_url: https://github.com/sanweisg/jadebot/blob/main/user_data/strategies/
# User: sanweisg
# Repository: jadebot
# --------------------from freqtrade.strategy import IStrategy
from pandas import DataFrame
import talib.abstract as ta
from technical import qtpylib
from freqtrade.strategy import IntParameter, CategoricalParameter


class Github_sanweisg_jadebot__MultiIndicatorRSI__20261025_174729(IStrategy):
    """
    多指标RSI策略 - 增强版
    - RSI + MACD + 布林带 + ATR
    - 多条件确认，提高信号质量
    - 动态止损（基于ATR）
    """
    
    INTERFACE_VERSION = 3
    timeframe = '1h'
    can_short = False
    
    # ROI配置
    minimal_roi = {
        "0": 0.15,      # 任何时刻保留15%利润
        "60": 0.08,     # 持有60分钟后保留8%
        "180": 0.03     # 持有180分钟后保留3%
    }
    
    # 参数定义
    buy_rsi = IntParameter(low=20, high=40, default=30, space='buy')
    sell_rsi = IntParameter(low=60, high=80, default=70, space='sell')
    
    # 止损配置（必须）
    stoploss = -0.05
    
    # 动态止损系数（基于ATR）
    atr_stop_multiplier = 2.0
    
    # 不使用trailing stop
    trailing_stop = False
    
    def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        # RSI
        dataframe['rsi'] = ta.RSI(dataframe, timeperiod=14)
        
        # MACD
        macd = ta.MACD(dataframe)
        dataframe['macd'] = macd['macd']
        dataframe['macdsignal'] = macd['macdsignal']
        dataframe['macdhist'] = macd['macdhist']
        
        # 布林带
        bollinger = qtpylib.bollinger_bands(qtpylib.typical_price(dataframe), window=20, stds=2)
        dataframe['bb_lower'] = bollinger['lower']
        dataframe['bb_middle'] = bollinger['mid']
        dataframe['bb_upper'] = bollinger['upper']
        
        # ATR（用于动态止损）
        dataframe['atr'] = ta.ATR(dataframe, timeperiod=14)
        
        # 趋势过滤
        dataframe['ema_200'] = ta.EMA(dataframe, timeperiod=200)
        dataframe['ema_50'] = ta.EMA(dataframe, timeperiod=50)
        
        return dataframe
    
    def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        # 买入条件：多个指标确认
        dataframe.loc[
            (
                # RSI超卖
                (dataframe['rsi'] < self.buy_rsi.value) &
                # 价格在布林带下轨附近（超卖区域）
                (dataframe['close'] < dataframe['bb_lower'] * 1.02) &
                # MACD金叉或即将金叉
                (dataframe['macd'] > dataframe['macdsignal']) &
                # 上升趋势
                (dataframe['close'] > dataframe['ema_200']) &
                # 成交量正常
                (dataframe['volume'] > 0)
            ),
            'enter_long'] = 1
        
        return dataframe
    
    def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        # 卖出条件：多个指标确认
        dataframe.loc[
            (
                # RSI超买
                (dataframe['rsi'] > self.sell_rsi.value) &
                # MACD死叉
                (dataframe['macd'] < dataframe['macdsignal']) &
                # 价格在布林带上轨附近
                (dataframe['close'] > dataframe['bb_upper'] * 0.98)
            ),
            'exit_long'] = 1
        
        return dataframe
    
    def custom_stoploss(self, pair: str, trade: 'Trade', current_time, current_rate, current_profit, **kwargs) -> float:
        """动态止损：基于ATR"""
        # 获取最近的ATR值
        dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
        last_candle = dataframe.iloc[-1]
        
        if last_candle is None:
            return self.stoploss
        
        atr = last_candle['atr']
        if atr == 0:
            return self.stoploss
        
        # 动态止损距离
        dynamic_stop = self.atr_stop_multiplier * atr / current_rate
        
        # 取保守的止损
        return min(abs(self.stoploss), dynamic_stop)
