diff --git a/trading_system/risk_manager.py b/trading_system/risk_manager.py index 0ac7e38..e627d95 100644 --- a/trading_system/risk_manager.py +++ b/trading_system/risk_manager.py @@ -230,16 +230,22 @@ class RiskManager: async def calculate_dynamic_leverage( self, - symbol: str, - entry_price: float, + *args, + symbol: Optional[str] = None, + entry_price: Optional[float] = None, stop_loss_price: Optional[float] = None, atr: Optional[float] = None, side: Optional[str] = None, - signal_strength: Optional[int] = None + signal_strength: Optional[int] = None, + **kwargs ) -> int: """ 计算动态杠杆 - 综合考虑信号强度和风险控制 + 兼容两种调用方式: + 1. 新版本:calculate_dynamic_leverage(symbol=..., entry_price=..., stop_loss_price=..., ...) + 2. 旧版本:calculate_dynamic_leverage(signal_strength, symbol, atr=..., entry_price=...) + Args: symbol: 交易对 entry_price: 入场价格 @@ -251,6 +257,28 @@ class RiskManager: Returns: 建议杠杆倍数 """ + # 兼容旧调用方式:第一个位置参数可能是 signal_strength + if args and len(args) > 0: + first_arg = args[0] + if isinstance(first_arg, int) and 0 <= first_arg <= 10: + signal_strength = first_arg + elif isinstance(first_arg, str): + symbol = first_arg + if len(args) > 1 and isinstance(args[1], str) and symbol is None: + symbol = args[1] + if len(args) > 2 and isinstance(args[2], (int, float)) and entry_price is None: + entry_price = args[2] + + # 从 kwargs 中提取(兼容旧调用) + if 'signal_strength' in kwargs and signal_strength is None: + signal_strength = kwargs.get('signal_strength') + if 'symbol' in kwargs and symbol is None: + symbol = kwargs.get('symbol') + if 'entry_price' in kwargs and entry_price is None: + entry_price = kwargs.get('entry_price') + if 'atr' in kwargs and atr is None: + atr = kwargs.get('atr') + # 默认使用配置杠杆 default_leverage = config.TRADING_CONFIG.get('LEVERAGE', 10) @@ -273,7 +301,7 @@ class RiskManager: signal_leverage = base_leverage + leverage_increase signal_leverage = min(signal_leverage, max_leverage) - logger.info(f" 📊 信号强度杠杆 ({symbol}): 信号={signal_strength} -> {int(signal_leverage)}x") + logger.info(f" 📊 信号强度杠杆 ({symbol or 'N/A'}): 信号={signal_strength} -> {int(signal_leverage)}x") # 2. 基于ATR波动率的限制 (小众币保护) atr_limit_leverage = 100 # 初始设为很高 @@ -311,7 +339,7 @@ class RiskManager: theoretical_leverage = max_loss_pct / stop_loss_width risk_safe_leverage = int(theoretical_leverage) - logger.info(f" 🛡️ 风险安全杠杆 ({symbol}):") + logger.info(f" 🛡️ 风险安全杠杆 ({symbol or 'N/A'}):") logger.info(f" 止损宽度: {stop_loss_width*100:.2f}%") logger.info(f" 最大单笔亏损限制: {max_loss_pct*100:.1f}%") logger.info(f" -> 理论最大杠杆: {theoretical_leverage:.2f}x") @@ -1236,82 +1264,3 @@ class RiskManager: + f"止盈金额={take_profit_amount:.4f} USDT ({take_profit_percent*100:.1f}% of margin)" ) return take_profit_price - - async def calculate_dynamic_leverage(self, signal_strength: int, symbol: str = None, atr: Optional[float] = None, entry_price: Optional[float] = None) -> int: - """ - 根据信号强度计算动态杠杆倍数 - 信号强度越高,杠杆倍数越高,以最大化收益 - 同时检查交易对支持的最大杠杆限制 - - Args: - signal_strength: 信号强度 (0-10) - symbol: 交易对符号(可选,用于检查交易对的最大杠杆限制) - - Returns: - 杠杆倍数 - """ - # 获取配置参数 - use_dynamic_leverage = config.TRADING_CONFIG.get('USE_DYNAMIC_LEVERAGE', True) - base_leverage = config.TRADING_CONFIG.get('LEVERAGE', 10) - max_leverage = config.TRADING_CONFIG.get('MAX_LEVERAGE', 20) - min_signal_strength = config.TRADING_CONFIG.get('MIN_SIGNAL_STRENGTH', 7) - - # ⚠️ 优化7:阶梯杠杆 - 小众币限制最高杠杆 - max_leverage_small_cap = config.TRADING_CONFIG.get('MAX_LEVERAGE_SMALL_CAP', 5) - atr_leverage_reduction_threshold = config.TRADING_CONFIG.get('ATR_LEVERAGE_REDUCTION_THRESHOLD', 0.05) # 5% - - # 检查是否为小众币(高波动率) - is_small_cap = False - if atr and entry_price and entry_price > 0: - atr_percent = atr / entry_price - if atr_percent >= atr_leverage_reduction_threshold: - is_small_cap = True - logger.info(f" ⚠️ {symbol} ATR波动率 {atr_percent*100:.2f}% >= {atr_leverage_reduction_threshold*100:.0f}%,识别为小众币,限制最大杠杆为{max_leverage_small_cap}x") - max_leverage = min(max_leverage, max_leverage_small_cap) - - # 如果未启用动态杠杆,返回基础杠杆 - if not use_dynamic_leverage: - final_leverage = int(base_leverage) - else: - # 如果信号强度低于最小要求,使用基础杠杆 - if signal_strength < min_signal_strength: - final_leverage = int(base_leverage) - else: - # 计算动态杠杆:信号强度越高,杠杆越高 - # 公式:杠杆 = 基础杠杆 + (信号强度 - 最小信号强度) * (最大杠杆 - 基础杠杆) / (10 - 最小信号强度) - signal_range = 10 - min_signal_strength # 信号强度范围 - leverage_range = max_leverage - base_leverage # 杠杆范围 - - if signal_range > 0: - # 计算信号强度超出最小值的比例 - strength_above_min = signal_strength - min_signal_strength - leverage_increase = (strength_above_min / signal_range) * leverage_range - dynamic_leverage = base_leverage + leverage_increase - else: - dynamic_leverage = base_leverage - - # 确保杠杆在合理范围内(不超过配置的最大杠杆) - final_leverage = max(int(base_leverage), min(int(dynamic_leverage), int(max_leverage))) - - # 如果提供了交易对符号,检查交易对支持的最大杠杆限制 - if symbol: - try: - symbol_info = await self.client.get_symbol_info(symbol) - if symbol_info and 'maxLeverage' in symbol_info: - symbol_max_leverage = symbol_info['maxLeverage'] - if final_leverage > symbol_max_leverage: - logger.warning( - f"{symbol} 交易对最大杠杆限制为 {symbol_max_leverage}x, " - f"计算杠杆 {final_leverage}x 超过限制,调整为 {symbol_max_leverage}x" - ) - final_leverage = symbol_max_leverage - except Exception as e: - logger.warning(f"获取 {symbol} 交易对杠杆限制失败: {e},使用计算值 {final_leverage}x") - - logger.info( - f"动态杠杆计算: 信号强度={signal_strength}/10, " - f"基础杠杆={base_leverage}x, 计算杠杆={final_leverage}x" - + (f", 交易对={symbol}" if symbol else "") - ) - - return final_leverage