# source: https://raw.githubusercontent.com/t734070824/my-projects/46ad956305d3d8963ef8f95eda89ffeb271c40ac/my-btc-trade-system/buy_sell_notify/freqtrade/strategies/TripleTimeframeTrendStrategyV2_3.py
# pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement

from freqtrade.strategy.interface import IStrategy
from typing import Dict, List, Optional
from functools import reduce

import talib.abstract as ta
import numpy as np  
import pandas as pd
from pandas import DataFrame

class Github_t734070824_my_projects__TripleTimeframeTrendStrategyV2_3__20250808_143826(IStrategy):
    """
    三重时间框架趋势跟踪策略 V2.3 - 抗干扰优化版
    
    V2.3核心改进：解决困难市场期间0交易问题
    
    基于V2_2多时段测试结果的关键优化：
    1. 应急交易模式：5天无交易时启用降级模式
    2. 自适应阈值：根据无交易时长动态降低门槛
    3. 单时间框架备用：三时间框架失效时的后备机制
    4. 精准币种权重：基于300天实际数据重新校准
    5. 渐进式参数松动：避免过度反应导致亏损
    
    测试数据分析：
    V2_2表现：300天145.1%，219天88.01%，但7月期间仅1笔交易，8月0笔
    目标：保持长期收益优势的同时，确保困难期间仍能适度交易
    """

    # 策略参数
    INTERFACE_VERSION = 3
    
    # 基于V2_2微调的ROI - 更现实的目标
    minimal_roi = {
        "0": 0.18,   # 18% (从20%降至18%，更容易达到)
        "30": 0.13,  # 30分钟后13%
        "60": 0.09,  # 1小时后9% 
        "120": 0.06, # 2小时后6%
        "240": 0.04, # 4小时后4%
        "480": 0.02  # 8小时后2%
    }

    # 渐进式止损策略
    stoploss = -0.05  # 5% 基础止损（稍微放宽）

    # 时间框架
    timeframe = '1h'
    
    # 启用位置堆叠
    position_stacking = False
    
    # 可以做多做空
    can_short = True

    # 启用使用卖出信号
    use_exit_signal = True
    exit_profit_only = False
    ignore_roi_if_entry_signal = False

    # 优化追踪止损
    trailing_stop = True
    trailing_stop_positive = 0.022  # 2.2%后启用
    trailing_stop_positive_offset = 0.032  # 3.2%追踪止损偏移
    trailing_only_offset_is_reached = True

    # 技术指标参数 - 保持V2_2设置
    sma_short_period = 18    
    sma_long_period = 46     
    
    macd_fast = 11      
    macd_slow = 25      
    macd_signal = 9     
    
    rsi_period = 14
    rsi_overbought = 75  
    rsi_oversold = 25    
    
    bb_period = 20
    bb_std = 2.0
    
    ichimoku_conversion = 9
    ichimoku_base = 26
    ichimoku_lagging = 52
    
    atr_period = 14

    # 基于300天真实测试数据优化的币种权重
    pair_weights = {
        # 顶级表现组 - 基于V2_2的300天数据
        'ADA/USDT': 1.3,     # 从0.5→1.3，300天测试表现优异
        'WIF/USDT': 1.4,     # 从1.2→1.4，持续优秀表现
        'DOGE/USDT': 1.3,    # 保持1.3，表现稳定
        'XRP/USDT': 1.2,     # 保持1.2，长期表现良好
        
        # 优秀表现组
        'SUI/USDT': 1.1,     # 从1.1保持，中等偏上表现
        'ETH/USDT': 1.0,     # 保持1.0，主流稳定
        'SOL/USDT': 1.0,     # 从0.8→1.0，有所提升
        'BNB/USDT': 0.9,     # 保持0.9，中等表现
        
        # 标准表现组
        'AVAX/USDT': 0.9,    # 保持0.9
        'DOT/USDT': 0.9,     # 保持0.9
        'LINK/USDT': 0.8,    # 保持0.8
        
        # 谨慎交易组
        'NEAR/USDT': 0.3,    # 从0.7→0.3，300天表现较差
        'UNI/USDT': 0.5,     # 保持0.5
        'BTC/USDT': 0.4,     # 保持0.4，意外表现不佳
    }
    
    # V2_3核心创新：分级信号阈值系统
    strong_signal_threshold = 2       # 标准强信号
    weak_signal_threshold = 1         # 标准弱信号
    emergency_threshold = 0           # 应急模式阈值
    
    # 应急交易系统参数
    no_trade_emergency_days = 5       # 5天无交易启用应急模式
    emergency_mode_duration = 24     # 应急模式持续24小时
    last_trade_time = None           # 追踪最后交易时间
    emergency_mode_start = None      # 应急模式开始时间
    
    # 市场状态参数
    market_volatility_period = 50
    trending_threshold = 0.016       # 从0.018→0.016 稍微放宽趋势判断

    def informative_pairs(self):
        pairs = self.dp.current_whitelist()
        informative_pairs = []
        for pair in pairs:
            informative_pairs.extend([
                (pair, '1d'),
                (pair, '4h')
            ])
        return informative_pairs

    def populate_indicators(self, dataframe: DataFrame, metadata: Dict) -> DataFrame:
        inf_1d = self.dp.get_pair_dataframe(pair=metadata['pair'], timeframe='1d')
        inf_4h = self.dp.get_pair_dataframe(pair=metadata['pair'], timeframe='4h')
        
        # 1小时指标
        dataframe['sma_short'] = ta.SMA(dataframe, timeperiod=self.sma_short_period)
        dataframe['sma_long'] = ta.SMA(dataframe, timeperiod=self.sma_long_period)
        
        macd = ta.MACD(dataframe, fastperiod=self.macd_fast, slowperiod=self.macd_slow, signalperiod=self.macd_signal)
        dataframe['macd'] = macd['macd']
        dataframe['macdsignal'] = macd['macdsignal'] 
        dataframe['macdhist'] = macd['macdhist']
        
        dataframe['rsi'] = ta.RSI(dataframe, timeperiod=self.rsi_period)
        
        bollinger = ta.BBANDS(dataframe, timeperiod=self.bb_period, nbdevup=float(self.bb_std), nbdevdn=float(self.bb_std))
        dataframe['bb_lower'] = bollinger['lowerband']
        dataframe['bb_middle'] = bollinger['middleband']
        dataframe['bb_upper'] = bollinger['upperband']
        dataframe['bb_percent'] = (dataframe['close'] - dataframe['bb_lower']) / (dataframe['bb_upper'] - dataframe['bb_lower'])
        
        dataframe['atr'] = ta.ATR(dataframe, timeperiod=self.atr_period)
        
        # 市场状态指标
        dataframe['volume_sma'] = ta.SMA(dataframe['volume'], timeperiod=20)
        dataframe['volume_ratio'] = dataframe['volume'] / dataframe['volume_sma']
        dataframe['market_volatility'] = dataframe['close'].rolling(self.market_volatility_period).std() / dataframe['close'].rolling(self.market_volatility_period).mean()
        dataframe['is_trending'] = dataframe['market_volatility'] > self.trending_threshold
        
        # 新增：价格动量指标
        dataframe['price_momentum'] = dataframe['close'].pct_change(5)  # 5周期价格变化率
        dataframe['volume_momentum'] = dataframe['volume'].pct_change(3)  # 3周期成交量变化率
        
        # 市场趋势方向
        dataframe['market_trend'] = np.where(
            dataframe['sma_short'] > dataframe['sma_long'], 1,
            np.where(dataframe['sma_short'] < dataframe['sma_long'], -1, 0)
        )
        
        dataframe['h1_score'] = self.calculate_adaptive_score(dataframe)
        
        # 处理日线数据
        if len(inf_1d) > 0:
            inf_1d['sma_short'] = ta.SMA(inf_1d, timeperiod=self.sma_short_period)
            inf_1d['sma_long'] = ta.SMA(inf_1d, timeperiod=self.sma_long_period) 
            inf_1d['rsi'] = ta.RSI(inf_1d, timeperiod=self.rsi_period)
            
            macd_1d = ta.MACD(inf_1d, fastperiod=self.macd_fast, slowperiod=self.macd_slow, signalperiod=self.macd_signal)
            inf_1d['macd'] = macd_1d['macd']
            inf_1d['macdsignal'] = macd_1d['macdsignal']
            inf_1d['macdhist'] = macd_1d['macdhist']
            
            bollinger_1d = ta.BBANDS(inf_1d, timeperiod=self.bb_period, nbdevup=float(self.bb_std), nbdevdn=float(self.bb_std))
            inf_1d['bb_lower'] = bollinger_1d['lowerband']
            inf_1d['bb_middle'] = bollinger_1d['middleband'] 
            inf_1d['bb_upper'] = bollinger_1d['upperband']
            
            inf_1d['daily_score'] = self.calculate_adaptive_score(inf_1d)
            
            dataframe = pd.merge(dataframe, inf_1d[['date', 'daily_score']], on='date', how='left')
            dataframe['daily_score'] = dataframe['daily_score'].fillna(method='ffill')
        
        # 处理4小时数据
        if len(inf_4h) > 0:
            inf_4h['sma_short'] = ta.SMA(inf_4h, timeperiod=self.sma_short_period)
            inf_4h['sma_long'] = ta.SMA(inf_4h, timeperiod=self.sma_long_period)
            inf_4h['rsi'] = ta.RSI(inf_4h, timeperiod=self.rsi_period)
            
            macd_4h = ta.MACD(inf_4h, fastperiod=self.macd_fast, slowperiod=self.macd_slow, signalperiod=self.macd_signal)
            inf_4h['macd'] = macd_4h['macd'] 
            inf_4h['macdsignal'] = macd_4h['macdsignal']
            inf_4h['macdhist'] = macd_4h['macdhist']
            
            bollinger_4h = ta.BBANDS(inf_4h, timeperiod=self.bb_period, nbdevup=float(self.bb_std), nbdevdn=float(self.bb_std))
            inf_4h['bb_lower'] = bollinger_4h['lowerband']
            inf_4h['bb_middle'] = bollinger_4h['middleband']
            inf_4h['bb_upper'] = bollinger_4h['upperband']
            
            inf_4h['h4_score'] = self.calculate_adaptive_score(inf_4h)
            
            dataframe = pd.merge(dataframe, inf_4h[['date', 'h4_score']], on='date', how='left') 
            dataframe['h4_score'] = dataframe['h4_score'].fillna(method='ffill')
            
        dataframe['daily_score'] = dataframe['daily_score'].fillna(0)
        dataframe['h4_score'] = dataframe['h4_score'].fillna(0)
        
        dataframe['signal_strength'] = self.calculate_signal_strength(dataframe)
        
        return dataframe

    def calculate_adaptive_score(self, df: DataFrame) -> pd.Series:
        """自适应评分计算 - V2_3改进版"""
        score = pd.Series(0.0, index=df.index)
        
        # SMA趋势评分：±2分
        sma_trend = np.where(
            (df['close'] > df['sma_short']) & (df['sma_short'] > df['sma_long']), 2,
            np.where(
                (df['close'] < df['sma_short']) & (df['sma_short'] < df['sma_long']), -2,
                np.where(df['close'] > df['sma_short'], 1, -1)
            )
        )
        score += sma_trend
        
        # MACD评分：±2分
        if 'macdhist' in df.columns:
            macd_score = np.where(
                (df['macd'] > df['macdsignal']) & (df['macdhist'] > 0), 2,
                np.where(
                    (df['macd'] < df['macdsignal']) & (df['macdhist'] < 0), -2,
                    np.where(df['macd'] > df['macdsignal'], 1, -1)
                )
            )
        else:
            macd_score = np.where(df['macd'] > df['macdsignal'], 1, -1)
        score += macd_score
        
        # RSI评分：±1分 - 调整阈值增加灵敏度
        rsi_score = np.where(
            df['rsi'] > 62, 1,  # 65→62 更敏感
            np.where(df['rsi'] < 38, -1, 0)  # 35→38 更敏感
        )
        score += rsi_score
        
        # 布林带评分：±0.5分
        if 'bb_upper' in df.columns and 'bb_lower' in df.columns:
            bb_score = np.where(
                df['close'] > df['bb_upper'], 0.5,
                np.where(df['close'] < df['bb_lower'], -0.5, 0)
            )
            score += bb_score
        
        return score

    def calculate_signal_strength(self, dataframe: DataFrame) -> pd.Series:
        """计算信号强度 - V2_3优化版"""
        strength = pd.Series(0.0, index=dataframe.index)
        
        # 基础三时间框架权重 - 均衡分配
        daily_weight = abs(dataframe['daily_score']) * 0.35   
        h4_weight = abs(dataframe['h4_score']) * 0.35        
        h1_weight = abs(dataframe['h1_score']) * 0.30        
        
        # 成交量确认 - 降低要求
        volume_confirm = np.where(dataframe['volume_ratio'] > 0.9, 0.5, 0)  # 1.1→0.9
        
        # 趋势市场加分
        trend_bonus = np.where(dataframe['is_trending'], 0.3, 0)  
        
        # 新增：动量加分
        momentum_bonus = np.where(
            (abs(dataframe.get('price_momentum', 0)) > 0.01) & 
            (dataframe.get('volume_momentum', 0) > 0), 0.2, 0
        )
        
        strength = daily_weight + h4_weight + h1_weight + volume_confirm + trend_bonus + momentum_bonus
        
        return np.clip(strength, 0, 10)

    def is_emergency_mode_active(self) -> bool:
        """检查是否应该启用应急交易模式"""
        if not hasattr(self, '_trades_count_checked'):
            self._trades_count_checked = True
            # 这里可以通过API检查最近的交易记录
            # 简化实现：假设通过外部机制设置emergency_mode_start
        
        if self.emergency_mode_start is not None:
            # 检查应急模式是否仍在有效期内
            return True  # 简化实现
        
        return False

    def get_adaptive_thresholds(self, pair_weight: float) -> tuple:
        """获取自适应阈值"""
        # 基础阈值
        strong_threshold = self.strong_signal_threshold
        weak_threshold = self.weak_signal_threshold
        
        # 应急模式：大幅降低阈值
        if self.is_emergency_mode_active():
            strong_threshold = self.emergency_threshold  # 0
            weak_threshold = 0
            return strong_threshold, weak_threshold
        
        # 根据币种权重微调
        if pair_weight >= 1.2:      # 优秀币种
            strong_threshold = max(0, strong_threshold - 1)  # 2→1
            weak_threshold = max(0, weak_threshold - 1)      # 1→0
        elif pair_weight <= 0.5:   # 表现差币种
            strong_threshold += 1   # 2→3
            weak_threshold += 1     # 1→2
            
        return strong_threshold, weak_threshold

    def populate_entry_trend(self, dataframe: DataFrame, metadata: Dict) -> DataFrame:
        """V2_3优化入场条件 - 抗干扰设计"""
        pair = metadata['pair']
        pair_weight = self.pair_weights.get(pair, 1.0)
        
        # 获取自适应阈值
        current_strong_threshold, current_weak_threshold = self.get_adaptive_thresholds(pair_weight)
        
        conditions_long = []
        conditions_short = []
        conditions_weak_long = []
        conditions_emergency = []  # 新增：应急交易条件
        
        # === 标准做多信号 ===
        conditions_long.append(dataframe['daily_score'] >= 0)   
        conditions_long.append(dataframe['h4_score'] >= 0)     
        conditions_long.append(dataframe['h1_score'] >= current_strong_threshold)
        
        # === 弱做多信号 ===
        weak_long_cond_1 = (
            (dataframe['daily_score'] >= -1) &  
            (dataframe['h4_score'] >= 0) & 
            (dataframe['h1_score'] >= current_weak_threshold) &
            (dataframe['signal_strength'] >= 2.2)  # 2.5→2.2
        )
        
        weak_long_cond_2 = (
            (dataframe['is_trending']) &
            (dataframe['daily_score'] >= 0) &
            (dataframe['h1_score'] >= current_weak_threshold) &
            (dataframe['signal_strength'] >= 2.8)  # 3→2.8
        )
        
        conditions_weak_long.append(weak_long_cond_1)
        conditions_weak_long.append(weak_long_cond_2)
        
        # === V2_3创新：应急交易条件 ===
        if self.is_emergency_mode_active():
            # 应急模式1：单时间框架突破
            emergency_cond_1 = (
                (dataframe['h1_score'] >= 0) &  # 仅要求1小时非负
                (dataframe['rsi'] < 65) &       # 宽松RSI
                (dataframe['signal_strength'] >= 1.5)  # 很低的信号强度要求
            )
            
            # 应急模式2：动量突破
            emergency_cond_2 = (
                (dataframe.get('price_momentum', 0) > 0.008) &  # 0.8%的价格上涨
                (dataframe['volume_ratio'] > 0.8) &
                (dataframe['rsi'] < 70)
            )
            
            conditions_emergency.append(emergency_cond_1)
            conditions_emergency.append(emergency_cond_2)
        
        # === 做空信号（保守） ===
        # 只在明确熊市信号时做空
        if dataframe['daily_score'].iloc[-1] <= -2 and dataframe['h4_score'].iloc[-1] <= -1:
            conditions_short.append(dataframe['daily_score'] <= -1)
            conditions_short.append(dataframe['h4_score'] <= -1) 
            conditions_short.append(dataframe['h1_score'] <= -current_strong_threshold)
        
        # 通用过滤条件
        common_filters = [
            dataframe['volume'] > 0,
            dataframe['volume_ratio'] > 0.5  # 0.6→0.5 进一步放宽
        ]
        
        # 币种权重差异化RSI过滤
        if pair_weight >= 1.2:
            rsi_filter_long = dataframe['rsi'] < 78   # 80→78
            rsi_filter_short = dataframe['rsi'] > 22  # 20→22
        elif pair_weight >= 0.8:
            rsi_filter_long = dataframe['rsi'] < self.rsi_overbought
            rsi_filter_short = dataframe['rsi'] > self.rsi_oversold
        else:
            rsi_filter_long = dataframe['rsi'] < 72   # 70→72
            rsi_filter_short = dataframe['rsi'] > 28  # 30→28
        
        # === 执行交易信号 ===
        
        # 应急模式交易（最高优先级）
        if conditions_emergency and common_filters:
            emergency_filters = common_filters + [rsi_filter_long]
            emergency_signal = reduce(lambda x, y: x | y, conditions_emergency)
            emergency_signal = emergency_signal & reduce(lambda x, y: x & y, emergency_filters)
            dataframe.loc[emergency_signal, 'buy'] = 1
            dataframe.loc[emergency_signal, 'buy_tag'] = 'emergency_v2_3'
        
        # 标准强信号
        elif conditions_long and common_filters:
            long_filters = common_filters + [rsi_filter_long]
            strong_long = reduce(lambda x, y: x & y, conditions_long + long_filters)
            dataframe.loc[strong_long, 'buy'] = 1
            dataframe.loc[strong_long, 'buy_tag'] = 'strong_long_v2_3'
        
        # 弱信号（如果没有强信号）
        if conditions_weak_long and common_filters:
            long_filters = common_filters + [rsi_filter_long]
            weak_long = reduce(lambda x, y: x | y, conditions_weak_long)
            weak_long = weak_long & reduce(lambda x, y: x & y, long_filters)
            
            if 'buy' in dataframe.columns:
                weak_long = weak_long & (dataframe['buy'] != 1)
            
            dataframe.loc[weak_long, 'buy'] = 1
            dataframe.loc[weak_long, 'buy_tag'] = 'weak_long_v2_3'

        # 做空信号
        if conditions_short and common_filters:
            short_filters = common_filters + [rsi_filter_short]
            strong_short = reduce(lambda x, y: x & y, conditions_short + short_filters)
            dataframe.loc[strong_short, 'sell'] = 1
            dataframe.loc[strong_short, 'sell_tag'] = 'strong_short_v2_3'

        return dataframe

    def populate_exit_trend(self, dataframe: DataFrame, metadata: Dict) -> DataFrame:
        """V2_3优化退出条件"""
        conditions_strong_exit = []
        conditions_weak_exit = []
        
        # 强烈退出信号 - 收紧条件
        conditions_strong_exit.append(dataframe['daily_score'] < -2)
        conditions_strong_exit.append(dataframe['h4_score'] < -2)
        conditions_strong_exit.append(dataframe['h1_score'] <= -2)
        
        # 保护性退出信号
        weak_exit_cond_1 = (
            (dataframe['signal_strength'] < 1.3) &  # 1.5→1.3 更敏感
            (dataframe['h1_score'] <= -1) &
            (dataframe['rsi'] > 76)  # 78→76
        )
        
        weak_exit_cond_2 = (
            (dataframe['rsi'] > 80) &  # 82→80 更保守
            (dataframe['close'] > dataframe['bb_upper']) &
            (dataframe['macdhist'] < 0)
        )
        
        conditions_weak_exit.append(weak_exit_cond_1)
        conditions_weak_exit.append(weak_exit_cond_2)
        
        # 通用退出过滤条件
        common_filters = [
            dataframe['volume'] > 0,
            dataframe['rsi'] > self.rsi_oversold
        ]
        
        # 强烈退出
        if conditions_strong_exit and common_filters:
            strong_exit = reduce(lambda x, y: x & y, conditions_strong_exit + common_filters)
            dataframe.loc[strong_exit, 'sell'] = 1
            dataframe.loc[strong_exit, 'exit_tag'] = 'strong_bearish_v2_3'
        
        # 保护性退出
        if conditions_weak_exit and common_filters:
            weak_exit = reduce(lambda x, y: x | y, conditions_weak_exit)
            weak_exit = weak_exit & reduce(lambda x, y: x & y, common_filters)
            
            if 'sell' in dataframe.columns:
                weak_exit = weak_exit & (dataframe['sell'] != 1)
            
            dataframe.loc[weak_exit, 'sell'] = 1
            dataframe.loc[weak_exit, 'exit_tag'] = 'protect_profit_v2_3'

        return dataframe

    def custom_stoploss(self, pair: str, trade: 'Trade', current_time,
                       current_rate: float, current_profit: float, **kwargs) -> float:
        """V2_3动态止损策略"""
        dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
        if len(dataframe) < 1:
            return self.stoploss
            
        last_candle = dataframe.iloc[-1]
        pair_weight = self.pair_weights.get(pair, 1.0)
        
        if 'atr' in last_candle:
            atr_value = last_candle['atr']
            
            # 应急模式下的宽松止损
            if self.is_emergency_mode_active():
                atr_multiplier = 2.5  # 更宽松的止损
                max_loss = 0.07       # 最大7%止损
            else:
                # 根据币种表现和市场状态调整止损
                if pair_weight >= 1.2:      # 优秀币种
                    atr_multiplier = 2.3    # 2.2→2.3 稍微放宽
                    max_loss = 0.065        # 0.06→0.065
                elif pair_weight >= 0.8:    # 标准币种
                    atr_multiplier = 2.1    # 2.0→2.1
                    max_loss = 0.058        # 0.055→0.058  
                else:                       # 表现差的币种
                    atr_multiplier = 1.9    # 1.8→1.9
                    max_loss = 0.052        # 0.05→0.052
            
            # 时间衰减止损
            minutes_elapsed = (current_time - trade.open_date_utc).total_seconds() / 60
            if minutes_elapsed > 480:  # 8小时后
                time_factor = 0.88     # 0.85→0.88 不那么激进
            elif minutes_elapsed > 240:  # 4小时后
                time_factor = 0.92     # 0.9→0.92
            else:
                time_factor = 1.0
            
            atr_stoploss = atr_multiplier * atr_value / current_rate * time_factor
            
            return max(-max_loss, min(-0.028, -atr_stoploss))  # -0.025→-0.028
        
        return self.stoploss

    def custom_exit(self, pair: str, trade: 'Trade', current_time, current_rate: float,
                   current_profit: float, **kwargs) -> Optional[str]:
        """V2_3智能出场逻辑"""
        dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
        if len(dataframe) < 1:
            return None
            
        last_candle = dataframe.iloc[-1]
        signal_strength = last_candle.get('signal_strength', 5)
        pair_weight = self.pair_weights.get(pair, 1.0)
        
        # 基于币种权重和应急模式的差异化止盈
        if self.is_emergency_mode_active():
            # 应急模式：快速止盈
            first_target = 0.04      # 4%
            second_target = 0.08     # 8%
        elif pair_weight >= 1.2:    # 优秀币种
            first_target = 0.055     # 6%→5.5%
            second_target = 0.11     # 12%→11%
        elif pair_weight >= 0.8:     # 标准币种
            first_target = 0.038     # 4%→3.8%
            second_target = 0.076    # 8%→7.6%
        else:                        # 表现差币种
            first_target = 0.028     # 3%→2.8%
            second_target = 0.056    # 6%→5.6%
        
        # 分批止盈
        if current_profit > first_target and not hasattr(trade, 'first_exit_done'):
            trade.first_exit_done = True
            return 'first_target_v2_3'
        
        if current_profit > second_target and not hasattr(trade, 'second_exit_done'):
            trade.second_exit_done = True
            return 'second_target_v2_3'
        
        # 信号恶化时快速出场 - 更敏感
        if signal_strength < 1.3 and current_profit > 0.012:  # 1.5→1.3, 0.015→0.012
            return 'signal_weak_v2_3'
        
        # 极度超买时出场
        if last_candle.get('rsi', 50) > 83 and current_profit > 0.018:  # 85→83, 0.02→0.018
            return 'rsi_extreme_v2_3'
        
        return None

    def position_sizing(self, pair: str, current_time, current_rate: float, 
                       proposed_stake: float, min_stake: float, max_stake: float, 
                       side: str, **kwargs) -> float:
        """V2_3基于表现和模式的动态仓位"""
        dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
        pair_weight = self.pair_weights.get(pair, 1.0)
        
        base_multiplier = pair_weight
        
        if len(dataframe) > 0:
            last_candle = dataframe.iloc[-1]
            signal_strength = last_candle.get('signal_strength', 5)
            
            # 信号强度调整
            if signal_strength >= 8:
                strength_multiplier = 1.25   # 1.3→1.25 稍微保守
            elif signal_strength >= 6:
                strength_multiplier = 1.08   # 1.1→1.08
            elif signal_strength >= 4:
                strength_multiplier = 1.0
            else:
                strength_multiplier = 0.85   # 0.8→0.85
                
            # 应急模式仓位调整
            if self.is_emergency_mode_active():
                strength_multiplier *= 0.7   # 应急模式减少仓位
        else:
            strength_multiplier = 1.0
        
        # 最终倍数限制
        final_multiplier = base_multiplier * strength_multiplier
        final_multiplier = max(0.35, min(final_multiplier, 1.35))  # 0.4→0.35, 1.4→1.35
        
        final_stake = proposed_stake * final_multiplier
        return max(min_stake, min(final_stake, max_stake))
        
    def leverage(self, pair: str, current_time, current_rate: float,
                 proposed_leverage: float, max_leverage: float, side: str,
                 **kwargs) -> float:
        """V2_3保守杠杆策略"""
        pair_weight = self.pair_weights.get(pair, 1.0)
        
        # 应急模式使用更低杠杆
        if self.is_emergency_mode_active():
            return min(2.0, max_leverage)
        
        if pair_weight >= 1.2:
            target_leverage = 2.8      # 3.0→2.8 稍微保守
        elif pair_weight >= 0.8:
            target_leverage = 2.3      # 2.5→2.3
        else:
            target_leverage = 1.8      # 2.0→1.8
        
        return min(target_leverage, max_leverage, 3.0)  # 全局最大保持3倍