diff --git a/backend/api/routes/config.py b/backend/api/routes/config.py index 2db9ee6..82e8b33 100644 --- a/backend/api/routes/config.py +++ b/backend/api/routes/config.py @@ -152,6 +152,41 @@ AUTO_TRADE_FILTER_DEFAULTS = { } +# 核心策略参数(仅管理员可见/在全局策略账号中修改) +CORE_STRATEGY_CONFIG_DEFAULTS = { + "ATR_STOP_LOSS_MULTIPLIER": { + "value": 2.5, + "type": "number", + "category": "strategy", + "description": "ATR止损倍数。建议 2.0-3.0。放宽止损可以给波动留出空间,提高胜率。", + }, + "ATR_TAKE_PROFIT_MULTIPLIER": { + "value": 1.5, + "type": "number", + "category": "strategy", + "description": "ATR止盈倍数。建议 1.0-2.0。对应盈亏比 1:1 到 2:1,更容易触及目标。", + }, + "RISK_REWARD_RATIO": { + "value": 1.5, + "type": "number", + "category": "strategy", + "description": "目标盈亏比(止损距离的倍数)。配合ATR止盈使用。", + }, + "MIN_STOP_LOSS_PRICE_PCT": { + "value": 0.02, + "type": "number", + "category": "strategy", + "description": "最小止损距离(%)。例如 0.02 表示 2%。防止止损过紧。", + }, + "MIN_TAKE_PROFIT_PRICE_PCT": { + "value": 0.02, + "type": "number", + "category": "strategy", + "description": "最小止盈距离(%)。例如 0.02 表示 2%。防止止盈过近。", + }, +} + + @router.get("") @router.get("/") async def get_all_configs( @@ -231,6 +266,10 @@ async def get_all_configs( if k not in result: result[k] = meta + for k, meta in CORE_STRATEGY_CONFIG_DEFAULTS.items(): + if k not in result: + result[k] = meta + # 普通用户:只展示风险旋钮 + 账号密钥(尽量傻瓜化,避免改坏策略) # 管理员:若当前不是“全局策略账号”,同样只展示风险旋钮,避免误以为这里改策略能生效 is_admin = (user.get("role") or "user") == "admin" diff --git a/backend/config_manager.py b/backend/config_manager.py index 480a3bf..85bf326 100644 --- a/backend/config_manager.py +++ b/backend/config_manager.py @@ -543,9 +543,9 @@ class ConfigManager: 'MIN_STOP_LOSS_PRICE_PCT': eff_get('MIN_STOP_LOSS_PRICE_PCT', 0.02), # 默认2% 'MIN_TAKE_PROFIT_PRICE_PCT': eff_get('MIN_TAKE_PROFIT_PRICE_PCT', 0.02), # 默认2%(防止ATR过小时计算出不切实际的微小止盈距离) 'USE_ATR_STOP_LOSS': eff_get('USE_ATR_STOP_LOSS', True), # 是否使用ATR动态止损 - 'ATR_STOP_LOSS_MULTIPLIER': eff_get('ATR_STOP_LOSS_MULTIPLIER', 1.8), # ATR止损倍数(1.5-2倍) - 'ATR_TAKE_PROFIT_MULTIPLIER': eff_get('ATR_TAKE_PROFIT_MULTIPLIER', 1.5), # ATR止盈倍数(从4.5降至1.5,将盈亏比从3:1降至更现实、可达成的1.5:1,提升止盈触发率) - 'RISK_REWARD_RATIO': eff_get('RISK_REWARD_RATIO', 1.5), # 盈亏比(止损距离的倍数,从3.0降至1.5,更容易达成) + 'ATR_STOP_LOSS_MULTIPLIER': eff_get('ATR_STOP_LOSS_MULTIPLIER', 2.5), # ATR止损倍数(放宽至2.5,提升胜率) + 'ATR_TAKE_PROFIT_MULTIPLIER': eff_get('ATR_TAKE_PROFIT_MULTIPLIER', 1.5), # ATR止盈倍数(1.5:1盈亏比) + 'RISK_REWARD_RATIO': eff_get('RISK_REWARD_RATIO', 1.5), # 盈亏比(止损距离的倍数,1.5倍) 'ATR_PERIOD': eff_get('ATR_PERIOD', 14), # ATR计算周期 'USE_DYNAMIC_ATR_MULTIPLIER': eff_get('USE_DYNAMIC_ATR_MULTIPLIER', False), # 是否根据波动率动态调整ATR倍数 'ATR_MULTIPLIER_MIN': eff_get('ATR_MULTIPLIER_MIN', 1.5), # 动态ATR倍数最小值 diff --git a/trading_system/config.py b/trading_system/config.py index b58944d..8532267 100644 --- a/trading_system/config.py +++ b/trading_system/config.py @@ -192,9 +192,9 @@ def _get_trading_config(): 'MIN_STOP_LOSS_PRICE_PCT': 0.02, # 最小止损价格变动百分比(如0.02表示2%),防止止损过紧,默认2% 'MIN_TAKE_PROFIT_PRICE_PCT': 0.02, # 最小止盈价格变动百分比(如0.02表示2%),防止ATR过小时计算出不切实际的微小止盈距离,默认2% 'USE_ATR_STOP_LOSS': True, # 是否使用ATR动态止损(优先于固定百分比) - 'ATR_STOP_LOSS_MULTIPLIER': 1.8, # ATR止损倍数(1.5-2倍ATR,默认1.8) - 'ATR_TAKE_PROFIT_MULTIPLIER': 1.5, # ATR止盈倍数(从4.5降至1.5,将盈亏比从3:1降至更现实、可达成的1.5:1,提升止盈触发率) - 'RISK_REWARD_RATIO': 1.5, # 盈亏比(止损距离的倍数,用于计算止盈,从3.0降至1.5,更容易达成) + 'ATR_STOP_LOSS_MULTIPLIER': 2.5, # ATR止损倍数(放宽至2.5,配合固定风险2%,提升胜率) + 'ATR_TAKE_PROFIT_MULTIPLIER': 1.5, # ATR止盈倍数(1.5:1盈亏比,更容易达成) + 'RISK_REWARD_RATIO': 1.5, # 盈亏比(配合止盈倍数) 'ATR_PERIOD': 14, # ATR计算周期(默认14) 'USE_DYNAMIC_ATR_MULTIPLIER': False, # 是否根据波动率动态调整ATR倍数 'ATR_MULTIPLIER_MIN': 1.5, # 动态ATR倍数最小值 diff --git a/trading_system/position_manager.py b/trading_system/position_manager.py index 5ec2155..bde5cd6 100644 --- a/trading_system/position_manager.py +++ b/trading_system/position_manager.py @@ -1936,7 +1936,7 @@ class PositionManager: # 价格兜底:如果能明显命中止损/止盈价,则覆盖 exit_reason # 这对于保护单触发的 MARKET 订单特别重要(币安的保护单触发后会生成 MARKET 订单) try: - def _close_to(a: float, b: float, max_pct: float = 0.02) -> bool: # 放宽到2%,因为滑点可能导致价格不完全一致 + def _close_to(a: float, b: float, max_pct: float = 0.05) -> bool: # 从2%放宽到5%,以应对极端滑点下的同步识别 if a <= 0 or b <= 0: return False return abs((a - b) / b) <= max_pct @@ -1948,14 +1948,14 @@ class PositionManager: tp1 = trade.get("take_profit_1") tp2 = trade.get("take_profit_2") # 优先检查止损(因为止损更关键) - if sl is not None and _close_to(ep, float(sl), max_pct=0.02): + if sl is not None and _close_to(ep, float(sl), max_pct=0.05): exit_reason = "stop_loss" # 然后检查止盈 - elif tp is not None and _close_to(ep, float(tp), max_pct=0.02): + elif tp is not None and _close_to(ep, float(tp), max_pct=0.05): exit_reason = "take_profit" - elif tp1 is not None and _close_to(ep, float(tp1), max_pct=0.02): + elif tp1 is not None and _close_to(ep, float(tp1), max_pct=0.05): exit_reason = "take_profit" - elif tp2 is not None and _close_to(ep, float(tp2), max_pct=0.02): + elif tp2 is not None and _close_to(ep, float(tp2), max_pct=0.05): exit_reason = "take_profit" # 如果之前标记为 sync 且是 reduceOnly 订单,但价格不匹配止损/止盈,可能是其他自动平仓(如移动止损) elif exit_reason == "sync" and is_reduce_only: