From 81526052e7e82f5df2818544da969d40ff0d5395 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=96=87=E8=96=87=E5=AE=89?= Date: Thu, 15 Jan 2026 13:08:41 +0800 Subject: [PATCH] a --- backend/config_manager.py | 1 + backend/database/init.sql | 1 + trading_system/config.py | 1 + trading_system/position_manager.py | 1 + trading_system/risk_manager.py | 52 +++++++++++++++++++++++++++++- 5 files changed, 55 insertions(+), 1 deletion(-) diff --git a/backend/config_manager.py b/backend/config_manager.py index b38d1e3..46bf084 100644 --- a/backend/config_manager.py +++ b/backend/config_manager.py @@ -112,6 +112,7 @@ class ConfigManager: 'MAX_POSITION_PERCENT': self.get('MAX_POSITION_PERCENT', 0.05), 'MAX_TOTAL_POSITION_PERCENT': self.get('MAX_TOTAL_POSITION_PERCENT', 0.30), 'MIN_POSITION_PERCENT': self.get('MIN_POSITION_PERCENT', 0.01), + 'MIN_MARGIN_USDT': self.get('MIN_MARGIN_USDT', 0.5), # 最小保证金要求(USDT) # 涨跌幅阈值 'MIN_CHANGE_PERCENT': self.get('MIN_CHANGE_PERCENT', 2.0), diff --git a/backend/database/init.sql b/backend/database/init.sql index 95b3a88..4a46658 100644 --- a/backend/database/init.sql +++ b/backend/database/init.sql @@ -133,6 +133,7 @@ INSERT INTO `trading_config` (`config_key`, `config_value`, `config_type`, `cate ('MAX_POSITION_PERCENT', '0.05', 'number', 'position', '单笔最大仓位:账户余额的5%'), ('MAX_TOTAL_POSITION_PERCENT', '0.30', 'number', 'position', '总仓位上限:账户余额的30%'), ('MIN_POSITION_PERCENT', '0.01', 'number', 'position', '单笔最小仓位:账户余额的1%'), +('MIN_MARGIN_USDT', '0.5', 'number', 'position', '最小保证金要求:0.5 USDT(避免手续费侵蚀收益)'), -- 涨跌幅阈值 ('MIN_CHANGE_PERCENT', '2.0', 'number', 'scan', '最小涨跌幅阈值:2%'), diff --git a/trading_system/config.py b/trading_system/config.py index 63fdacc..0b1788e 100644 --- a/trading_system/config.py +++ b/trading_system/config.py @@ -164,6 +164,7 @@ def _get_trading_config(): 'MAX_POSITION_PERCENT': 0.05, 'MAX_TOTAL_POSITION_PERCENT': 0.30, 'MIN_POSITION_PERCENT': 0.01, + 'MIN_MARGIN_USDT': 0.5, # 最小保证金要求(USDT),避免手续费侵蚀收益 'MIN_CHANGE_PERCENT': 2.0, 'TOP_N_SYMBOLS': 10, # 每次扫描后处理的交易对数量 'MAX_SCAN_SYMBOLS': 500, # 扫描的最大交易对数量(0表示扫描所有) diff --git a/trading_system/position_manager.py b/trading_system/position_manager.py index c4afb96..6e82a86 100644 --- a/trading_system/position_manager.py +++ b/trading_system/position_manager.py @@ -103,6 +103,7 @@ class PositionManager: logger.warning(f" 2. 单笔仓位超过限制") logger.warning(f" 3. 总仓位超过限制") logger.warning(f" 4. 无法获取价格数据") + logger.warning(f" 5. 保证金不足最小要求(MIN_MARGIN_USDT)") return None logger.info(f"✓ {symbol} 仓位计算成功: {quantity:.4f}") diff --git a/trading_system/risk_manager.py b/trading_system/risk_manager.py index 020535c..7a8c521 100644 --- a/trading_system/risk_manager.py +++ b/trading_system/risk_manager.py @@ -301,10 +301,60 @@ class RiskManager: quantity = required_quantity position_value = required_quantity * current_price + # 检查最小保证金要求(避免手续费侵蚀收益) + min_margin_usdt = self.config.get('MIN_MARGIN_USDT', 0.5) # 默认0.5 USDT + leverage = self.config.get('LEVERAGE', 10) + + # 计算实际需要的保证金 = 仓位价值 / 杠杆 + required_margin = position_value / leverage + logger.info(f" 计算保证金: {required_margin:.4f} USDT (仓位价值: {position_value:.2f} USDT / 杠杆: {leverage}x)") + + if required_margin < min_margin_usdt: + # 保证金不足,需要增加仓位价值 + required_position_value = min_margin_usdt * leverage + logger.warning( + f" ⚠ 保证金 {required_margin:.4f} USDT < 最小保证金要求 {min_margin_usdt:.2f} USDT" + ) + logger.info( + f" 需要的最小仓位价值: {required_position_value:.2f} USDT " + f"(最小保证金 {min_margin_usdt:.2f} USDT × 杠杆 {leverage}x)" + ) + + # 检查是否可以使用更大的仓位价值(但不超过最大仓位限制) + max_position_value = available_balance * max_position_percent + if required_position_value <= max_position_value: + # 可以增加仓位价值以满足最小保证金要求 + position_value = required_position_value + quantity = position_value / current_price + logger.info( + f" ✓ 调整仓位价值到 {position_value:.2f} USDT " + f"以满足最小保证金要求 (保证金: {min_margin_usdt:.2f} USDT)" + ) + else: + # 即使使用最大仓位也无法满足最小保证金要求 + max_margin = max_position_value / leverage + logger.warning( + f" ❌ 无法满足最小保证金要求: " + f"需要 {min_margin_usdt:.2f} USDT 保证金 (仓位价值 {required_position_value:.2f} USDT)," + f"但最大允许 {max_margin:.2f} USDT 保证金 (仓位价值 {max_position_value:.2f} USDT)" + ) + logger.warning( + f" 💡 建议: 增加账户余额到至少 " + f"{required_position_value / max_position_percent:.2f} USDT " + f"才能满足最小保证金要求" + ) + return None + # 检查是否通过风险控制 logger.info(f" 检查仓位大小是否符合风险控制要求...") if await self.check_position_size(symbol, quantity): - logger.info(f"✓ {symbol} 仓位计算成功: {quantity:.4f} (价值: {position_value:.2f} USDT, 名义价值: {quantity * current_price:.2f} USDT)") + final_margin = (quantity * current_price) / leverage + logger.info( + f"✓ {symbol} 仓位计算成功: {quantity:.4f} " + f"(仓位价值: {position_value:.2f} USDT, " + f"名义价值: {quantity * current_price:.2f} USDT, " + f"保证金: {final_margin:.4f} USDT)" + ) return quantity else: logger.warning(f"❌ {symbol} 仓位检查未通过,无法开仓")