This commit is contained in:
薇薇安 2026-02-15 00:47:55 +08:00
parent 9379a9815e
commit 7cf6613540
4 changed files with 481 additions and 15 deletions

View File

@ -47,3 +47,5 @@
**已实现**:在 `risk_manager.get_take_profit_price` 中增加了 **USE_MARGIN_CAP_FOR_TP**(默认 **True**):当使用盈亏比算出 TP2 时若该价格比「TAKE_PROFIT_PERCENT 对应的保证金止盈价」更远,则**改用保证金止盈价**作为 TP2这样止盈不会远到难以触及。
- **⚠️ 不要关闭**:普遍出现的「止盈特别远(如 +238% 保证金)、亏损扛单」是因为**没有封顶**时用了「止损距离×3」的止盈。**关掉 USE_MARGIN_CAP_FOR_TP 会恢复那种过远止盈,加重扛单**。应保持 **True**,并确保交易进程已重启/配置已生效,新开仓才会用封顶后的止盈。
**止损封顶USE_MARGIN_CAP_FOR_SL**:若仅封顶止盈、不封顶止损,会出现「止盈 55%、止损 -58%-78%」——止损仍过宽、易扛单。因此增加了 **USE_MARGIN_CAP_FOR_SL**(默认 True当 ATR或技术止损对应的**保证金亏损**超过配置的 STOP_LOSS_PERCENT如 10%)时,**改用保证金止损**,使止损不再超过 10% 保证金。与 USE_MARGIN_CAP_FOR_TP 一起使用,新开仓的 SL/TP 都会在「保证金比例」范围内,避免极端远距。

View File

@ -207,6 +207,7 @@ DEFAULT_TRADING_CONFIG = {
'ATR_TAKE_PROFIT_MULTIPLIER': 6.0, # ATR止盈倍数6.0(追求更高盈亏比)
'RISK_REWARD_RATIO': 3.0, # 盈亏比3:1
'USE_MARGIN_CAP_FOR_TP': True, # 止盈按保证金上限封顶,避免 TP 过远难以触及、亏损扛单。勿关。
'USE_MARGIN_CAP_FOR_SL': True, # 止损按保证金上限封顶,避免 ATR 过宽导致 -60%-80% 保证金扛单。勿关。
'ATR_PERIOD': 14, # ATR计算周期14
'USE_DYNAMIC_ATR_MULTIPLIER': False, # 不使用动态ATR
'ATR_MULTIPLIER_MIN': 0.5, # 动态ATR倍数最小值

View File

@ -1135,21 +1135,32 @@ class RiskManager:
f"已采用保证金止损以与策略一致"
)
# 如果最终止损价对应的保证金百分比超过配置值且不是ATR/技术止损,则强制使用保证金止损
if final_stop_loss_pct_margin > (stop_loss_percent * 100) and not is_atr_or_tech:
logger.warning(
f"⚠️ 最终止损价({final_stop_loss:.4f}, 使用{selected_method})对应的保证金百分比({final_stop_loss_pct_margin:.2f}%) "
f"超过配置值({stop_loss_percent*100:.1f}%),强制使用保证金止损({stop_loss_price_margin:.4f})"
)
final_stop_loss = stop_loss_price_margin
selected_method = '保证金(强制)'
final_stop_loss_pct_margin = stop_loss_percent * 100
elif final_stop_loss_pct_margin > (stop_loss_percent * 100) and is_atr_or_tech:
logger.info(
f" {selected_method}止损 ({final_stop_loss:.4f}) 超过保证金配置值 "
f"({final_stop_loss_pct_margin:.2f}% > {stop_loss_percent*100:.1f}%)"
f"但予以保留(风险已通过仓位控制)"
)
# 如果最终止损价对应的保证金百分比超过配置值,强制使用保证金止损(含 ATR/技术止损)
# 避免 ATR 过宽导致止损 -58%-78% 保证金、长期扛单;与 USE_MARGIN_CAP_FOR_TP 一致
use_margin_cap_sl = bool(config.TRADING_CONFIG.get('USE_MARGIN_CAP_FOR_SL', True))
if final_stop_loss_pct_margin > (stop_loss_percent * 100):
if not is_atr_or_tech:
logger.warning(
f"⚠️ 最终止损价({final_stop_loss:.4f}, 使用{selected_method})对应的保证金百分比({final_stop_loss_pct_margin:.2f}%) "
f"超过配置值({stop_loss_percent*100:.1f}%),强制使用保证金止损({stop_loss_price_margin:.4f})"
)
final_stop_loss = stop_loss_price_margin
selected_method = '保证金(强制)'
final_stop_loss_pct_margin = stop_loss_percent * 100
elif use_margin_cap_sl:
logger.info(
f"止损已按保证金上限封顶: {selected_method}止损({final_stop_loss_pct_margin:.1f}% 保证金) "
f"超过 STOP_LOSS_PERCENT({stop_loss_percent*100:.1f}%),采用保证金止损({stop_loss_price_margin:.4f})"
)
final_stop_loss = stop_loss_price_margin
selected_method = '保证金(止损上限)'
final_stop_loss_pct_margin = stop_loss_percent * 100
else:
logger.info(
f" {selected_method}止损 ({final_stop_loss:.4f}) 超过保证金配置值 "
f"({final_stop_loss_pct_margin:.2f}% > {stop_loss_percent*100:.1f}%)"
f"但予以保留USE_MARGIN_CAP_FOR_SL=False"
)
# ⚠️ 最终强制检查:最小止损距离(防止 -2021 Order would immediately trigger
# 此检查必须在最后执行,覆盖之前的逻辑,因为这是交易所/系统的硬性约束

View File

@ -0,0 +1,452 @@
[
{
"id": 4640,
"symbol": "PIPPINUSDT",
"side": "SELL",
"quantity": 13,
"entry_price": 0.70165,
"entry_value_usdt": 9.12145,
"notional_usdt": 9.060078690000001,
"margin_usdt": 4.5300393450000005,
"original_notional_usdt": 9.12145,
"original_margin_usdt": 4.560725,
"mark_price": 0.69692913,
"pnl": 0.06137131,
"pnl_percent": 1.3547632884853011,
"leverage": 2,
"entry_time": 1771087159,
"stop_loss_price": 0.90642143,
"take_profit_price": 0.50869625,
"take_profit_1": 0.39449286,
"take_profit_2": 0.50869625,
"atr": 0.06825714,
"entry_order_id": 4503065801,
"entry_order_type": "LIMIT",
"open_orders": [
{
"orderId": 2000000449763200,
"type": "TAKE_PROFIT_MARKET",
"side": "BUY",
"stopPrice": 0.5087,
"price": 0,
"origType": "CONDITIONAL",
"reduceOnly": true,
"status": "NEW"
},
{
"orderId": 2000000449763193,
"type": "STOP_MARKET",
"side": "BUY",
"stopPrice": 0.90642,
"price": 0,
"origType": "CONDITIONAL",
"reduceOnly": true,
"status": "NEW"
}
],
"active_sl_orders": "STOP_MARKET @ 0.90642 (NEW)",
"active_tp_orders": "TAKE_PROFIT_MARKET @ 0.5087 (NEW)",
"binance_open_orders_raw": [
{
"orderId": 2000000449763200,
"type": "TAKE_PROFIT_MARKET",
"side": "BUY",
"stopPrice": 0.5087,
"price": 0,
"origType": "CONDITIONAL",
"reduceOnly": true,
"status": "NEW"
},
{
"orderId": 2000000449763193,
"type": "STOP_MARKET",
"side": "BUY",
"stopPrice": 0.90642,
"price": 0,
"origType": "CONDITIONAL",
"reduceOnly": true,
"status": "NEW"
}
]
},
{
"id": 4643,
"symbol": "ZECUSDT",
"side": "SELL",
"quantity": 0.084,
"entry_price": 283.79,
"entry_value_usdt": 23.83836,
"notional_usdt": 23.828280000000003,
"margin_usdt": 4.765656000000001,
"original_notional_usdt": 23.83836,
"original_margin_usdt": 4.767672,
"mark_price": 283.67,
"pnl": 0.01008,
"pnl_percent": 0.21151337822117247,
"leverage": 5,
"entry_time": 1771087205,
"stop_loss_price": 327.98,
"take_profit_price": 252.5731,
"take_profit_1": 217.505,
"take_profit_2": 252.5731,
"atr": 14.73,
"entry_order_id": 797657761399,
"entry_order_type": "LIMIT",
"open_orders": [
{
"orderId": 2000000449766575,
"type": "TAKE_PROFIT_MARKET",
"side": "BUY",
"stopPrice": 252.58,
"price": 0,
"origType": "CONDITIONAL",
"reduceOnly": true,
"status": "NEW"
},
{
"orderId": 2000000449766566,
"type": "STOP_MARKET",
"side": "BUY",
"stopPrice": 327.98,
"price": 0,
"origType": "CONDITIONAL",
"reduceOnly": true,
"status": "NEW"
}
],
"active_sl_orders": "STOP_MARKET @ 327.98 (NEW)",
"active_tp_orders": "TAKE_PROFIT_MARKET @ 252.58 (NEW)",
"binance_open_orders_raw": [
{
"orderId": 2000000449766575,
"type": "TAKE_PROFIT_MARKET",
"side": "BUY",
"stopPrice": 252.58,
"price": 0,
"origType": "CONDITIONAL",
"reduceOnly": true,
"status": "NEW"
},
{
"orderId": 2000000449766566,
"type": "STOP_MARKET",
"side": "BUY",
"stopPrice": 327.98,
"price": 0,
"origType": "CONDITIONAL",
"reduceOnly": true,
"status": "NEW"
}
]
},
{
"id": 4641,
"symbol": "TAOUSDT",
"side": "SELL",
"quantity": 0.104,
"entry_price": 191.45,
"entry_value_usdt": 19.9108,
"notional_usdt": 19.9984220904,
"margin_usdt": 4.9996055226,
"original_notional_usdt": 19.9108,
"original_margin_usdt": 4.9777,
"mark_price": 192.2925201,
"pnl": -0.08762209,
"pnl_percent": -1.7525800706459123,
"leverage": 4,
"entry_time": 1771087174,
"stop_loss_price": 223.29714286,
"take_profit_price": 165.125625,
"take_profit_1": 143.67928571,
"take_profit_2": 165.125625,
"atr": 10.61571429,
"entry_order_id": 9523399174,
"entry_order_type": "LIMIT",
"open_orders": [
{
"orderId": 2000000449764167,
"type": "TAKE_PROFIT_MARKET",
"side": "BUY",
"stopPrice": 165.13,
"price": 0,
"origType": "CONDITIONAL",
"reduceOnly": true,
"status": "NEW"
},
{
"orderId": 2000000449764159,
"type": "STOP_MARKET",
"side": "BUY",
"stopPrice": 223.29,
"price": 0,
"origType": "CONDITIONAL",
"reduceOnly": true,
"status": "NEW"
}
],
"active_sl_orders": "STOP_MARKET @ 223.29 (NEW)",
"active_tp_orders": "TAKE_PROFIT_MARKET @ 165.13 (NEW)",
"binance_open_orders_raw": [
{
"orderId": 2000000449764167,
"type": "TAKE_PROFIT_MARKET",
"side": "BUY",
"stopPrice": 165.13,
"price": 0,
"origType": "CONDITIONAL",
"reduceOnly": true,
"status": "NEW"
},
{
"orderId": 2000000449764159,
"type": "STOP_MARKET",
"side": "BUY",
"stopPrice": 223.29,
"price": 0,
"origType": "CONDITIONAL",
"reduceOnly": true,
"status": "NEW"
}
]
},
{
"id": 4642,
"symbol": "COAIUSDT",
"side": "SELL",
"quantity": 22,
"entry_price": 0.4395,
"entry_value_usdt": 9.669,
"notional_usdt": 9.4624585,
"margin_usdt": 4.73122925,
"original_notional_usdt": 9.669,
"original_margin_usdt": 4.8345,
"mark_price": 0.43011175,
"pnl": 0.2065415,
"pnl_percent": 4.365493386311813,
"leverage": 2,
"entry_time": 1771087179,
"stop_loss_price": 0.57938571,
"take_profit_price": 0.3186375,
"take_profit_1": 0.22967143,
"take_profit_2": 0.3186375,
"atr": 0.04662857,
"entry_order_id": 2086471512,
"entry_order_type": "LIMIT",
"open_orders": [
{
"orderId": 2000000449764560,
"type": "TAKE_PROFIT_MARKET",
"side": "BUY",
"stopPrice": 0.3187,
"price": 0,
"origType": "CONDITIONAL",
"reduceOnly": true,
"status": "NEW"
},
{
"orderId": 2000000449764551,
"type": "STOP_MARKET",
"side": "BUY",
"stopPrice": 0.5793,
"price": 0,
"origType": "CONDITIONAL",
"reduceOnly": true,
"status": "NEW"
}
],
"active_sl_orders": "STOP_MARKET @ 0.5793 (NEW)",
"active_tp_orders": "TAKE_PROFIT_MARKET @ 0.3187 (NEW)",
"binance_open_orders_raw": [
{
"orderId": 2000000449764560,
"type": "TAKE_PROFIT_MARKET",
"side": "BUY",
"stopPrice": 0.3187,
"price": 0,
"origType": "CONDITIONAL",
"reduceOnly": true,
"status": "NEW"
},
{
"orderId": 2000000449764551,
"type": "STOP_MARKET",
"side": "BUY",
"stopPrice": 0.5793,
"price": 0,
"origType": "CONDITIONAL",
"reduceOnly": true,
"status": "NEW"
}
]
},
{
"id": 4647,
"symbol": "PYTHUSDT",
"side": "SELL",
"quantity": 377,
"entry_price": 0.0610065251989,
"entry_value_usdt": 22.9994599999853,
"notional_usdt": 23.053546230000002,
"margin_usdt": 4.610709246000001,
"original_notional_usdt": 22.9994505,
"original_margin_usdt": 4.5998901,
"mark_price": 0.06114999,
"pnl": -0.05408819,
"pnl_percent": -1.173099128879661,
"leverage": 5,
"entry_time": 1771087459,
"stop_loss_price": 0.06959507,
"take_profit_price": 0.05429579,
"take_profit_1": 0.04812364,
"take_profit_2": 0.05429579,
"atr": 0.00286286,
"entry_order_id": 5286793226,
"entry_order_type": "LIMIT",
"open_orders": [
{
"orderId": 2000000449784169,
"type": "TAKE_PROFIT_MARKET",
"side": "BUY",
"stopPrice": 0.0543,
"price": 0,
"origType": "CONDITIONAL",
"reduceOnly": true,
"status": "NEW"
},
{
"orderId": 2000000449784150,
"type": "STOP_MARKET",
"side": "BUY",
"stopPrice": 0.06959,
"price": 0,
"origType": "CONDITIONAL",
"reduceOnly": true,
"status": "NEW"
}
],
"active_sl_orders": "STOP_MARKET @ 0.06959 (NEW)",
"active_tp_orders": "TAKE_PROFIT_MARKET @ 0.0543 (NEW)",
"binance_open_orders_raw": [
{
"orderId": 2000000449784169,
"type": "TAKE_PROFIT_MARKET",
"side": "BUY",
"stopPrice": 0.0543,
"price": 0,
"origType": "CONDITIONAL",
"reduceOnly": true,
"status": "NEW"
},
{
"orderId": 2000000449784150,
"type": "STOP_MARKET",
"side": "BUY",
"stopPrice": 0.06959,
"price": 0,
"origType": "CONDITIONAL",
"reduceOnly": true,
"status": "NEW"
}
]
},
{
"id": 4639,
"symbol": "VVVUSDT",
"side": "SELL",
"quantity": 3.64,
"entry_price": 2.792,
"entry_value_usdt": 10.16288,
"notional_usdt": 10.46136,
"margin_usdt": 5.23068,
"original_notional_usdt": 10.16288,
"original_margin_usdt": 5.08144,
"mark_price": 2.874,
"pnl": -0.29848,
"pnl_percent": -5.706332637439109,
"leverage": 2,
"entry_time": 1771081222,
"stop_loss_price": 3.776,
"take_profit_price": -0.16,
"take_profit_1": 1.316,
"take_profit_2": -0.16,
"atr": 0.328,
"entry_order_id": 824862620,
"entry_order_type": "LIMIT",
"open_orders": [
{
"orderId": 2000000449333341,
"type": "STOP_MARKET",
"side": "BUY",
"stopPrice": 3.776,
"price": 0,
"origType": "CONDITIONAL",
"reduceOnly": true,
"status": "NEW"
}
],
"active_sl_orders": "STOP_MARKET @ 3.776 (NEW)",
"active_tp_orders": "",
"binance_open_orders_raw": [
{
"orderId": 2000000449333341,
"type": "STOP_MARKET",
"side": "BUY",
"stopPrice": 3.776,
"price": 0,
"origType": "CONDITIONAL",
"reduceOnly": true,
"status": "NEW"
}
]
},
{
"id": 4637,
"symbol": "RIVERUSDT",
"side": "SELL",
"quantity": 0.7,
"entry_price": 13.874,
"entry_value_usdt": 9.7118,
"notional_usdt": 9.251199999999999,
"margin_usdt": 4.6255999999999995,
"original_notional_usdt": 9.7118,
"original_margin_usdt": 4.8559,
"mark_price": 13.216,
"pnl": 0.4606,
"pnl_percent": 9.95762711864407,
"leverage": 2,
"entry_time": 1771079231,
"stop_loss_price": 19.02242857,
"take_profit_price": -1.57128571,
"take_profit_1": 6.15135714,
"take_profit_2": -1.57128571,
"atr": 1.71614286,
"entry_order_id": 3923246641,
"entry_order_type": "LIMIT",
"open_orders": [
{
"orderId": 2000000449191175,
"type": "STOP_MARKET",
"side": "BUY",
"stopPrice": 19.022,
"price": 0,
"origType": "CONDITIONAL",
"reduceOnly": true,
"status": "NEW"
}
],
"active_sl_orders": "STOP_MARKET @ 19.022 (NEW)",
"active_tp_orders": "",
"binance_open_orders_raw": [
{
"orderId": 2000000449191175,
"type": "STOP_MARKET",
"side": "BUY",
"stopPrice": 19.022,
"price": 0,
"origType": "CONDITIONAL",
"reduceOnly": true,
"status": "NEW"
}
]
}
]