From c778afdcb6ccec0065312b056128c2a328502821 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=96=87=E8=96=87=E5=AE=89?= Date: Sat, 17 Jan 2026 19:18:09 +0800 Subject: [PATCH] a --- backend/api/routes/config.py | 62 +++++++++++++++++++------ frontend/src/components/ConfigPanel.jsx | 17 +++++-- trading_system/risk_manager.py | 53 ++++++++++----------- 3 files changed, 89 insertions(+), 43 deletions(-) diff --git a/backend/api/routes/config.py b/backend/api/routes/config.py index 28182f9..0b2ef5a 100644 --- a/backend/api/routes/config.py +++ b/backend/api/routes/config.py @@ -75,23 +75,56 @@ async def check_config_feasibility(): required_position_value = min_margin_usdt * leverage required_position_percent = required_position_value / available_balance if available_balance > 0 else 0 - # 检查是否可行 - is_feasible = required_position_percent <= max_position_percent + # 计算使用最小仓位百分比时,实际能得到的保证金 + min_position_value = available_balance * min_position_percent + actual_min_margin = min_position_value / leverage if leverage > 0 else min_position_value + + # 检查是否可行: + # 1. 需要的仓位百分比不能超过最大允许的仓位百分比 + # 2. 使用最小仓位百分比时,实际保证金必须 >= 最小保证金要求 + is_feasible = (required_position_percent <= max_position_percent) and (actual_min_margin >= min_margin_usdt) suggestions = [] if not is_feasible: # 不可行,给出建议 - # 方案1:降低最小保证金 - suggested_min_margin = (available_balance * max_position_percent) / leverage - suggestions.append({ - "type": "reduce_min_margin", - "title": "降低最小保证金", - "description": f"将 MIN_MARGIN_USDT 调整为 {suggested_min_margin:.2f} USDT(当前: {min_margin_usdt:.2f} USDT)", - "config_key": "MIN_MARGIN_USDT", - "suggested_value": round(suggested_min_margin, 2), - "reason": f"当前配置需要 {required_position_percent*100:.1f}% 的仓位价值,但最大允许 {max_position_percent*100:.1f}%" - }) + # 判断是哪个条件不满足 + if required_position_percent > max_position_percent: + # 条件1不满足:需要的仓位百分比超过最大允许 + # 方案1:降低最小保证金 + suggested_min_margin = (available_balance * max_position_percent) / leverage + suggestions.append({ + "type": "reduce_min_margin", + "title": "降低最小保证金", + "description": f"将 MIN_MARGIN_USDT 调整为 {suggested_min_margin:.2f} USDT(当前: {min_margin_usdt:.2f} USDT)", + "config_key": "MIN_MARGIN_USDT", + "suggested_value": round(suggested_min_margin, 2), + "reason": f"当前配置需要 {required_position_percent*100:.1f}% 的仓位价值,但最大允许 {max_position_percent*100:.1f}%" + }) + + if actual_min_margin < min_margin_usdt: + # 条件2不满足:使用最小仓位时,实际保证金不足 + # 方案1:降低最小保证金到实际能支持的值 + suggestions.append({ + "type": "reduce_min_margin_to_supported", + "title": "降低最小保证金到可支持值", + "description": f"将 MIN_MARGIN_USDT 调整为 {actual_min_margin:.2f} USDT(当前: {min_margin_usdt:.2f} USDT,实际只支持 {actual_min_margin:.2f} USDT)", + "config_key": "MIN_MARGIN_USDT", + "suggested_value": round(actual_min_margin, 2), + "reason": f"当前账户余额和配置下,使用最小仓位 {min_position_percent*100:.1f}% 时,实际保证金只有 {actual_min_margin:.2f} USDT,无法满足 {min_margin_usdt:.2f} USDT 的要求" + }) + + # 方案2:提高最小仓位百分比 + required_min_position_percent = (min_margin_usdt * leverage) / available_balance if available_balance > 0 else 0 + if required_min_position_percent <= max_position_percent: + suggestions.append({ + "type": "increase_min_position", + "title": "提高最小仓位百分比", + "description": f"将 MIN_POSITION_PERCENT 调整为 {required_min_position_percent*100:.2f}%(当前: {min_position_percent*100:.1f}%)", + "config_key": "MIN_POSITION_PERCENT", + "suggested_value": round(required_min_position_percent, 4), + "reason": f"需要至少 {required_min_position_percent*100:.2f}% 的仓位才能满足 {min_margin_usdt:.2f} USDT 的保证金要求" + }) # 方案2:增加账户余额 required_balance = required_position_value / max_position_percent @@ -141,7 +174,10 @@ async def check_config_feasibility(): "calculated_values": { "required_position_value": required_position_value, "required_position_percent": required_position_percent * 100, - "max_allowed_position_percent": max_position_percent * 100 + "max_allowed_position_percent": max_position_percent * 100, + "min_position_value": min_position_value, + "actual_min_margin": actual_min_margin, + "min_position_percent": min_position_percent * 100 }, "suggestions": suggestions } diff --git a/frontend/src/components/ConfigPanel.jsx b/frontend/src/components/ConfigPanel.jsx index 470b870..73c3a3c 100644 --- a/frontend/src/components/ConfigPanel.jsx +++ b/frontend/src/components/ConfigPanel.jsx @@ -301,10 +301,19 @@ const ConfigPanel = () => { 最小保证金: {feasibilityCheck.current_config?.min_margin_usdt?.toFixed(2) || 'N/A'} USDT

{!feasibilityCheck.feasible && ( -

- 需要仓位价值: {feasibilityCheck.calculated_values?.required_position_percent?.toFixed(1)}% | - 最大允许: {feasibilityCheck.calculated_values?.max_allowed_position_percent?.toFixed(1)}% -

+
+

+ 需要仓位价值: {feasibilityCheck.calculated_values?.required_position_percent?.toFixed(1)}% | + 最大允许: {feasibilityCheck.calculated_values?.max_allowed_position_percent?.toFixed(1)}% +

+ {feasibilityCheck.calculated_values?.actual_min_margin !== undefined && ( +

+ 实际支持保证金: {feasibilityCheck.calculated_values.actual_min_margin.toFixed(2)} USDT + (使用最小仓位 {feasibilityCheck.calculated_values.min_position_percent?.toFixed(1)}%) | + 要求: {feasibilityCheck.current_config?.min_margin_usdt?.toFixed(2)} USDT +

+ )} +
)} {feasibilityCheck.suggestions && feasibilityCheck.suggestions.length > 0 && ( diff --git a/trading_system/risk_manager.py b/trading_system/risk_manager.py index 90b4570..7c63474 100644 --- a/trading_system/risk_manager.py +++ b/trading_system/risk_manager.py @@ -24,7 +24,8 @@ class RiskManager: client: 币安客户端 """ self.client = client - self.config = config.TRADING_CONFIG + # 不保存引用,每次都从 config.TRADING_CONFIG 读取最新配置 + # self.config = config.TRADING_CONFIG # 移除,避免使用旧配置 async def check_position_size(self, symbol: str, quantity: float) -> bool: """ @@ -57,11 +58,11 @@ class RiskManager: current_price = ticker['price'] position_value = quantity * current_price - # 检查单笔仓位是否超过最大限制 - max_position_value = available_balance * self.config['MAX_POSITION_PERCENT'] - min_position_value = available_balance * self.config['MIN_POSITION_PERCENT'] - max_position_pct = self.config['MAX_POSITION_PERCENT'] * 100 - min_position_pct = self.config['MIN_POSITION_PERCENT'] * 100 + # 检查单笔仓位是否超过最大限制(每次都从最新配置读取) + max_position_value = available_balance * config.TRADING_CONFIG['MAX_POSITION_PERCENT'] + min_position_value = available_balance * config.TRADING_CONFIG['MIN_POSITION_PERCENT'] + max_position_pct = config.TRADING_CONFIG['MAX_POSITION_PERCENT'] * 100 + min_position_pct = config.TRADING_CONFIG['MIN_POSITION_PERCENT'] * 100 logger.info(f" 数量: {quantity:.4f}") logger.info(f" 价格: {current_price:.4f} USDT") @@ -150,8 +151,8 @@ class RiskManager: logger.warning("账户总余额为0,无法开仓") return False - max_total_position = total_balance * self.config['MAX_TOTAL_POSITION_PERCENT'] - max_total_position_pct = self.config['MAX_TOTAL_POSITION_PERCENT'] * 100 + max_total_position = total_balance * config.TRADING_CONFIG['MAX_TOTAL_POSITION_PERCENT'] + max_total_position_pct = config.TRADING_CONFIG['MAX_TOTAL_POSITION_PERCENT'] * 100 # 详细日志 logger.info("=" * 60) @@ -243,9 +244,9 @@ class RiskManager: logger.info(f" 当前价格: {current_price:.4f} USDT") # 根据涨跌幅调整仓位大小(涨跌幅越大,仓位可以适当增加) - base_position_percent = self.config['MAX_POSITION_PERCENT'] - max_position_percent = self.config['MAX_POSITION_PERCENT'] - min_position_percent = self.config['MIN_POSITION_PERCENT'] + base_position_percent = config.TRADING_CONFIG['MAX_POSITION_PERCENT'] + max_position_percent = config.TRADING_CONFIG['MAX_POSITION_PERCENT'] + min_position_percent = config.TRADING_CONFIG['MIN_POSITION_PERCENT'] # 涨跌幅超过5%时,可以适当增加仓位(但不超过1.5倍) if abs(change_percent) > 5: @@ -303,9 +304,9 @@ class RiskManager: position_value = required_quantity * current_price # 检查最小保证金要求(如果保证金小于此值,自动调整到0.5U保证金) - min_margin_usdt = self.config.get('MIN_MARGIN_USDT', 0.5) # 默认0.5 USDT + min_margin_usdt = config.TRADING_CONFIG.get('MIN_MARGIN_USDT', 0.5) # 默认0.5 USDT # 使用传入的实际杠杆,如果没有传入则使用配置的基础杠杆 - actual_leverage = leverage if leverage is not None else self.config.get('LEVERAGE', 10) + actual_leverage = leverage if leverage is not None else config.TRADING_CONFIG.get('LEVERAGE', 10) # 计算实际需要的保证金 = 仓位价值 / 杠杆 required_margin = position_value / actual_leverage @@ -378,7 +379,7 @@ class RiskManager: 是否应该交易 """ # 检查最小涨跌幅阈值 - if abs(change_percent) < self.config['MIN_CHANGE_PERCENT']: + if abs(change_percent) < config.TRADING_CONFIG['MIN_CHANGE_PERCENT']: logger.debug(f"{symbol} 涨跌幅 {change_percent:.2f}% 小于阈值") return False @@ -427,8 +428,8 @@ class RiskManager: margin = position_value / leverage if leverage > 0 else position_value # 优先使用ATR动态止损(如果启用且ATR可用) - use_atr_stop = self.config.get('USE_ATR_STOP_LOSS', True) - atr_multiplier = self.config.get('ATR_STOP_LOSS_MULTIPLIER', 1.8) + use_atr_stop = config.TRADING_CONFIG.get('USE_ATR_STOP_LOSS', True) + atr_multiplier = config.TRADING_CONFIG.get('ATR_STOP_LOSS_MULTIPLIER', 1.8) if use_atr_stop and atr is not None and atr > 0: # 基于ATR的动态止损 @@ -449,7 +450,7 @@ class RiskManager: logger.debug(f"ATR不可用,使用固定百分比止损") # 获取止损百分比(相对于保证金) - stop_loss_percent = stop_loss_pct or self.config['STOP_LOSS_PERCENT'] + stop_loss_percent = stop_loss_pct or config.TRADING_CONFIG['STOP_LOSS_PERCENT'] # 计算止损金额(相对于保证金) stop_loss_amount = margin * stop_loss_percent @@ -464,7 +465,7 @@ class RiskManager: # 同时计算基于价格百分比的止损价(作为最小值保护) # 获取最小价格变动百分比(如果配置了) - min_price_change_pct = self.config.get('MIN_STOP_LOSS_PRICE_PCT', None) + min_price_change_pct = config.TRADING_CONFIG.get('MIN_STOP_LOSS_PRICE_PCT', None) if min_price_change_pct is not None: # 基于价格百分比的止损价 if side == 'BUY': @@ -584,8 +585,8 @@ class RiskManager: margin = position_value / leverage if leverage > 0 else position_value # 优先使用ATR动态止盈(如果启用且ATR可用) - use_atr_stop = self.config.get('USE_ATR_STOP_LOSS', True) - atr_tp_multiplier = self.config.get('ATR_TAKE_PROFIT_MULTIPLIER', 3.0) + use_atr_stop = config.TRADING_CONFIG.get('USE_ATR_STOP_LOSS', True) + atr_tp_multiplier = config.TRADING_CONFIG.get('ATR_TAKE_PROFIT_MULTIPLIER', 3.0) if use_atr_stop and atr is not None and atr > 0: # 基于ATR的动态止盈(对应3:1盈亏比) @@ -606,7 +607,7 @@ class RiskManager: logger.debug(f"ATR不可用,使用固定百分比止盈") # 获取止盈百分比(相对于保证金) - take_profit_percent = take_profit_pct or self.config['TAKE_PROFIT_PERCENT'] + take_profit_percent = take_profit_pct or config.TRADING_CONFIG['TAKE_PROFIT_PERCENT'] # 计算止盈金额(相对于保证金) take_profit_amount = margin * take_profit_percent @@ -621,7 +622,7 @@ class RiskManager: # 同时计算基于价格百分比的止盈价(作为最小值保护) # 获取最小价格变动百分比(如果配置了) - min_price_change_pct = self.config.get('MIN_TAKE_PROFIT_PRICE_PCT', None) + min_price_change_pct = config.TRADING_CONFIG.get('MIN_TAKE_PROFIT_PRICE_PCT', None) if min_price_change_pct is not None: # 基于价格百分比的止盈价 if side == 'BUY': @@ -671,10 +672,10 @@ class RiskManager: 杠杆倍数 """ # 获取配置参数 - use_dynamic_leverage = self.config.get('USE_DYNAMIC_LEVERAGE', True) - base_leverage = self.config.get('LEVERAGE', 10) - max_leverage = self.config.get('MAX_LEVERAGE', 20) - min_signal_strength = self.config.get('MIN_SIGNAL_STRENGTH', 7) + 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) # 如果未启用动态杠杆,返回基础杠杆 if not use_dynamic_leverage: