diff --git a/backend/api/routes/config.py b/backend/api/routes/config.py index 898dca4..e083dc6 100644 --- a/backend/api/routes/config.py +++ b/backend/api/routes/config.py @@ -223,6 +223,12 @@ CORE_STRATEGY_CONFIG_DEFAULTS = { "category": "strategy", "description": "最小止盈距离(%)。例如 0.02 表示 2%。防止止盈过近。", }, + "POSITION_DETAILED_LOG_ENABLED": { + "value": False, + "type": "boolean", + "category": "strategy", + "description": "是否启用持仓详细监控日志(记录每次检查的当前价/止损/止盈/ROE 等)。仅用于排查问题时临时打开,平时建议关闭以减少日志噪音。", + }, } diff --git a/backend/config_manager.py b/backend/config_manager.py index 60582e9..67323df 100644 --- a/backend/config_manager.py +++ b/backend/config_manager.py @@ -907,6 +907,9 @@ class ConfigManager: 'ENTRY_CONFIRM_TIMEOUT_SEC': eff_get('ENTRY_CONFIRM_TIMEOUT_SEC', 30), 'ENTRY_MAX_DRIFT_PCT_TRENDING': eff_get('ENTRY_MAX_DRIFT_PCT_TRENDING', 0.006), 'ENTRY_MAX_DRIFT_PCT_RANGING': eff_get('ENTRY_MAX_DRIFT_PCT_RANGING', 0.3), + + # 持仓详细监控日志开关(用于排查问题时观察每次检查的当前价/目标价/ROE 等) + 'POSITION_DETAILED_LOG_ENABLED': eff_get('POSITION_DETAILED_LOG_ENABLED', False), # 动态过滤优化 'BETA_FILTER_ENABLED': eff_get('BETA_FILTER_ENABLED', True), # 大盘共振过滤:BTC/ETH下跌时屏蔽多单 diff --git a/frontend/src/components/GlobalConfig.jsx b/frontend/src/components/GlobalConfig.jsx index 6e2e124..8922d8f 100644 --- a/frontend/src/components/GlobalConfig.jsx +++ b/frontend/src/components/GlobalConfig.jsx @@ -440,6 +440,7 @@ const GlobalConfig = () => { ATR_STOP_LOSS_MULTIPLIER: { value: 3.0, type: 'number', category: 'risk', description: 'ATR 止损倍数(2026-02-12:3 减少噪音止损)。' }, USE_FIXED_RISK_SIZING: { value: true, type: 'boolean', category: 'risk', description: '是否使用固定风险仓位计算(基于止损距离和账户余额)。' }, FIXED_RISK_PERCENT: { value: 0.03, type: 'number', category: 'risk', description: '每笔交易固定风险百分比(如 0.01=1%)。' }, + POSITION_DETAILED_LOG_ENABLED: { value: false, type: 'boolean', category: 'strategy', description: '是否启用持仓详细监控日志(记录每次检查的当前价/止损/止盈/ROE 等)。仅排查问题时临时打开,平时建议关闭。' }, // 仓位/同步相关(保证全局配置页能看到) SYNC_RECOVER_MISSING_POSITIONS: { value: true, type: 'boolean', category: 'position', description: '同步时补建「币安有仓、DB 无记录」的交易记录。' }, SYNC_RECOVER_ONLY_WHEN_HAS_SLTP: { value: true, type: 'boolean', category: 'position', description: '仅当该持仓存在止损/止盈单时才补建(未配置 SYSTEM_ORDER_ID_PREFIX 时生效)。' }, diff --git a/trading_system/config.py b/trading_system/config.py index fc91086..73fba91 100644 --- a/trading_system/config.py +++ b/trading_system/config.py @@ -310,6 +310,9 @@ DEFAULT_TRADING_CONFIG = { 'LIMIT_ORDER_OFFSET_PCT': 0.5, # 限价单偏移百分比(默认0.5%) 'MIN_HOLD_TIME_SEC': 0, # 默认30分钟(1800秒),已取消 + # 持仓监控详细日志:用于排查问题时观察每次检查的当前价/目标价/ROE 等 + 'POSITION_DETAILED_LOG_ENABLED': False, + # ===== 系统单标识(用于同步时区分本系统开仓 vs 手动开仓)===== # 下单时写入 newClientOrderId = SYSTEM_ORDER_ID_PREFIX_时间戳_随机,同步/补建时根据订单 clientOrderId 前缀判断是否系统单 'SYSTEM_ORDER_ID_PREFIX': 'SYS', diff --git a/trading_system/position_manager.py b/trading_system/position_manager.py index 7b25053..accaf42 100644 --- a/trading_system/position_manager.py +++ b/trading_system/position_manager.py @@ -1709,6 +1709,18 @@ class PositionManager: pnl_percent_price = ((current_price - entry_price) / entry_price) * 100 else: pnl_percent_price = ((entry_price - current_price) / entry_price) * 100 + + if bool(config.TRADING_CONFIG.get('POSITION_DETAILED_LOG_ENABLED', False)): + stop_loss_snapshot = position_info.get('stopLoss') + take_profit_1_snapshot = position_info.get('takeProfit1') + take_profit_2_snapshot = position_info.get('takeProfit2', position_info.get('takeProfit')) + logger.info( + f"{symbol} [持仓监控快照] side={position_info['side']} | entry={entry_price:.6f} | " + f"price={current_price:.6f} | sl={stop_loss_snapshot if stop_loss_snapshot is not None else '-'} | " + f"tp1={take_profit_1_snapshot if take_profit_1_snapshot is not None else '-'} | " + f"tp2={take_profit_2_snapshot if take_profit_2_snapshot is not None else '-'} | " + f"roe_margin={pnl_percent_margin:.2f}% | price_change={pnl_percent_price:.2f}%" + ) # 更新最大盈利(基于保证金) max_profit = float(position_info.get('maxProfit', 0) or 0)