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: