This commit is contained in:
薇薇安 2026-01-23 13:24:01 +08:00
parent cdbb660c1d
commit 7a72cfb30c
4 changed files with 50 additions and 11 deletions

View File

@ -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("")
@router.get("/") @router.get("/")
async def get_all_configs( async def get_all_configs(
@ -231,6 +266,10 @@ async def get_all_configs(
if k not in result: if k not in result:
result[k] = meta 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" is_admin = (user.get("role") or "user") == "admin"

View File

@ -543,9 +543,9 @@ class ConfigManager:
'MIN_STOP_LOSS_PRICE_PCT': eff_get('MIN_STOP_LOSS_PRICE_PCT', 0.02), # 默认2% '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过小时计算出不切实际的微小止盈距离 '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动态止损 '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_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止盈倍数从4.5降至1.5将盈亏比从3:1降至更现实、可达成的1.5:1提升止盈触发率 '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), # 盈亏比(止损距离的倍数,从3.0降至1.5,更容易达成 'RISK_REWARD_RATIO': eff_get('RISK_REWARD_RATIO', 1.5), # 盈亏比(止损距离的倍数,1.5倍
'ATR_PERIOD': eff_get('ATR_PERIOD', 14), # ATR计算周期 'ATR_PERIOD': eff_get('ATR_PERIOD', 14), # ATR计算周期
'USE_DYNAMIC_ATR_MULTIPLIER': eff_get('USE_DYNAMIC_ATR_MULTIPLIER', False), # 是否根据波动率动态调整ATR倍数 'USE_DYNAMIC_ATR_MULTIPLIER': eff_get('USE_DYNAMIC_ATR_MULTIPLIER', False), # 是否根据波动率动态调整ATR倍数
'ATR_MULTIPLIER_MIN': eff_get('ATR_MULTIPLIER_MIN', 1.5), # 动态ATR倍数最小值 'ATR_MULTIPLIER_MIN': eff_get('ATR_MULTIPLIER_MIN', 1.5), # 动态ATR倍数最小值

View File

@ -192,9 +192,9 @@ def _get_trading_config():
'MIN_STOP_LOSS_PRICE_PCT': 0.02, # 最小止损价格变动百分比如0.02表示2%防止止损过紧默认2% 'MIN_STOP_LOSS_PRICE_PCT': 0.02, # 最小止损价格变动百分比如0.02表示2%防止止损过紧默认2%
'MIN_TAKE_PROFIT_PRICE_PCT': 0.02, # 最小止盈价格变动百分比如0.02表示2%防止ATR过小时计算出不切实际的微小止盈距离默认2% 'MIN_TAKE_PROFIT_PRICE_PCT': 0.02, # 最小止盈价格变动百分比如0.02表示2%防止ATR过小时计算出不切实际的微小止盈距离默认2%
'USE_ATR_STOP_LOSS': True, # 是否使用ATR动态止损优先于固定百分比 'USE_ATR_STOP_LOSS': True, # 是否使用ATR动态止损优先于固定百分比
'ATR_STOP_LOSS_MULTIPLIER': 1.8, # ATR止损倍数1.5-2倍ATR默认1.8 'ATR_STOP_LOSS_MULTIPLIER': 2.5, # ATR止损倍数放宽至2.5配合固定风险2%,提升胜率
'ATR_TAKE_PROFIT_MULTIPLIER': 1.5, # ATR止盈倍数从4.5降至1.5将盈亏比从3:1降至更现实、可达成的1.5:1提升止盈触发率 'ATR_TAKE_PROFIT_MULTIPLIER': 1.5, # ATR止盈倍数1.5:1盈亏比更容易达成
'RISK_REWARD_RATIO': 1.5, # 盈亏比(止损距离的倍数用于计算止盈从3.0降至1.5,更容易达成 'RISK_REWARD_RATIO': 1.5, # 盈亏比(配合止盈倍数
'ATR_PERIOD': 14, # ATR计算周期默认14 'ATR_PERIOD': 14, # ATR计算周期默认14
'USE_DYNAMIC_ATR_MULTIPLIER': False, # 是否根据波动率动态调整ATR倍数 'USE_DYNAMIC_ATR_MULTIPLIER': False, # 是否根据波动率动态调整ATR倍数
'ATR_MULTIPLIER_MIN': 1.5, # 动态ATR倍数最小值 'ATR_MULTIPLIER_MIN': 1.5, # 动态ATR倍数最小值

View File

@ -1936,7 +1936,7 @@ class PositionManager:
# 价格兜底:如果能明显命中止损/止盈价,则覆盖 exit_reason # 价格兜底:如果能明显命中止损/止盈价,则覆盖 exit_reason
# 这对于保护单触发的 MARKET 订单特别重要(币安的保护单触发后会生成 MARKET 订单) # 这对于保护单触发的 MARKET 订单特别重要(币安的保护单触发后会生成 MARKET 订单)
try: 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: if a <= 0 or b <= 0:
return False return False
return abs((a - b) / b) <= max_pct return abs((a - b) / b) <= max_pct
@ -1948,14 +1948,14 @@ class PositionManager:
tp1 = trade.get("take_profit_1") tp1 = trade.get("take_profit_1")
tp2 = trade.get("take_profit_2") 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" 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" 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" 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" exit_reason = "take_profit"
# 如果之前标记为 sync 且是 reduceOnly 订单,但价格不匹配止损/止盈,可能是其他自动平仓(如移动止损) # 如果之前标记为 sync 且是 reduceOnly 订单,但价格不匹配止损/止盈,可能是其他自动平仓(如移动止损)
elif exit_reason == "sync" and is_reduce_only: elif exit_reason == "sync" and is_reduce_only: