优化推荐模块
This commit is contained in:
parent
f8eca1ed59
commit
9be1c5777d
|
|
@ -228,6 +228,69 @@ class RiskManager:
|
|||
logger.error(f"检查总仓位失败: {e}", exc_info=True)
|
||||
return False
|
||||
|
||||
async def calculate_dynamic_leverage(self, symbol: str, entry_price: float, stop_loss_price: Optional[float] = None, atr: Optional[float] = None, side: Optional[str] = None) -> int:
|
||||
"""
|
||||
计算动态杠杆
|
||||
|
||||
Args:
|
||||
symbol: 交易对
|
||||
entry_price: 入场价格
|
||||
stop_loss_price: 止损价格
|
||||
atr: ATR值
|
||||
side: 交易方向
|
||||
|
||||
Returns:
|
||||
建议杠杆倍数
|
||||
"""
|
||||
# 默认使用配置杠杆
|
||||
default_leverage = config.TRADING_CONFIG.get('LEVERAGE', 10)
|
||||
|
||||
if not config.TRADING_CONFIG.get('USE_DYNAMIC_LEVERAGE', False):
|
||||
return default_leverage
|
||||
|
||||
# 尝试获取止损价格(如果没有传入,尝试估算)
|
||||
target_stop_loss = stop_loss_price
|
||||
|
||||
# 如果没有传入止损价,尝试使用ATR估算(仅用于计算杠杆建议)
|
||||
if target_stop_loss is None and atr and atr > 0 and entry_price:
|
||||
atr_multiplier = config.TRADING_CONFIG.get('ATR_STOP_LOSS_MULTIPLIER', 2.5)
|
||||
if side == 'BUY':
|
||||
target_stop_loss = entry_price - (atr * atr_multiplier)
|
||||
elif side == 'SELL':
|
||||
target_stop_loss = entry_price + (atr * atr_multiplier)
|
||||
|
||||
if target_stop_loss and entry_price:
|
||||
# 计算止损宽度比例
|
||||
stop_loss_width = abs(entry_price - target_stop_loss) / entry_price
|
||||
|
||||
if stop_loss_width > 0:
|
||||
# 获取最大单笔亏损率限制 (默认20%)
|
||||
max_loss_pct = config.TRADING_CONFIG.get('MAX_SINGLE_TRADE_LOSS_PERCENT', 20.0) / 100.0
|
||||
|
||||
# 计算建议杠杆
|
||||
# 理论杠杆 = 最大允许亏损比例 / 止损宽度比例
|
||||
theoretical_leverage = max_loss_pct / stop_loss_width
|
||||
|
||||
# 向下取整
|
||||
suggested_leverage = int(theoretical_leverage)
|
||||
|
||||
# 限制在最大杠杆范围内
|
||||
max_config_leverage = config.TRADING_CONFIG.get('MAX_LEVERAGE', 10)
|
||||
final_dynamic_leverage = min(suggested_leverage, max_config_leverage)
|
||||
|
||||
# 至少为1倍
|
||||
final_dynamic_leverage = max(1, final_dynamic_leverage)
|
||||
|
||||
logger.info(f" ⚖️ 动态杠杆计算 ({symbol}):")
|
||||
logger.info(f" 止损价格: {target_stop_loss:.4f} (宽度: {stop_loss_width*100:.2f}%)")
|
||||
logger.info(f" 最大单笔亏损限制: {max_loss_pct*100:.1f}%")
|
||||
logger.info(f" 理论最大杠杆: {theoretical_leverage:.2f}x")
|
||||
logger.info(f" -> 最终建议杠杆: {final_dynamic_leverage}x")
|
||||
|
||||
return final_dynamic_leverage
|
||||
|
||||
return default_leverage
|
||||
|
||||
async def calculate_position_size(
|
||||
self,
|
||||
symbol: str,
|
||||
|
|
@ -283,53 +346,15 @@ class RiskManager:
|
|||
# -------------------------------------------------------------------------
|
||||
# 动态杠杆计算逻辑 (针对 ZROUSDT 亏损案例优化)
|
||||
# -------------------------------------------------------------------------
|
||||
# 如果启用了动态杠杆,根据止损宽度自动调整杠杆
|
||||
# 公式: 建议杠杆 = 目标最大单单亏损率 / 止损宽度
|
||||
# 例如: 目标亏损20%,止损宽度10%,则建议杠杆 = 20% / 10% = 2倍
|
||||
# -------------------------------------------------------------------------
|
||||
calculated_leverage = None
|
||||
if config.TRADING_CONFIG.get('USE_DYNAMIC_LEVERAGE', False):
|
||||
# 尝试获取止损价格(如果没有传入,尝试估算)
|
||||
target_stop_loss = stop_loss_price
|
||||
|
||||
# 如果没有传入止损价,尝试使用ATR估算(仅用于计算杠杆建议)
|
||||
if target_stop_loss is None and atr and atr > 0 and entry_price:
|
||||
atr_multiplier = config.TRADING_CONFIG.get('ATR_STOP_LOSS_MULTIPLIER', 2.5)
|
||||
if side == 'BUY':
|
||||
target_stop_loss = entry_price - (atr * atr_multiplier)
|
||||
else:
|
||||
target_stop_loss = entry_price + (atr * atr_multiplier)
|
||||
|
||||
if target_stop_loss and entry_price:
|
||||
# 计算止损宽度比例
|
||||
stop_loss_width = abs(entry_price - target_stop_loss) / entry_price
|
||||
|
||||
if stop_loss_width > 0:
|
||||
# 获取最大单笔亏损率限制 (默认20%)
|
||||
max_loss_pct = config.TRADING_CONFIG.get('MAX_SINGLE_TRADE_LOSS_PERCENT', 20.0) / 100.0
|
||||
|
||||
# 计算建议杠杆
|
||||
# 理论杠杆 = 最大允许亏损比例 / 止损宽度比例
|
||||
theoretical_leverage = max_loss_pct / stop_loss_width
|
||||
|
||||
# 向下取整
|
||||
suggested_leverage = int(theoretical_leverage)
|
||||
|
||||
# 限制在最大杠杆范围内
|
||||
max_config_leverage = config.TRADING_CONFIG.get('MAX_LEVERAGE', 10)
|
||||
final_dynamic_leverage = min(suggested_leverage, max_config_leverage)
|
||||
|
||||
# 至少为1倍
|
||||
final_dynamic_leverage = max(1, final_dynamic_leverage)
|
||||
|
||||
logger.info(f" ⚖️ 动态杠杆计算:")
|
||||
logger.info(f" 止损价格: {target_stop_loss:.4f} (宽度: {stop_loss_width*100:.2f}%)")
|
||||
logger.info(f" 最大单笔亏损限制: {max_loss_pct*100:.1f}%")
|
||||
logger.info(f" 理论最大杠杆: {theoretical_leverage:.2f}x")
|
||||
logger.info(f" 配置最大杠杆: {max_config_leverage}x")
|
||||
logger.info(f" -> 最终建议杠杆: {final_dynamic_leverage}x")
|
||||
|
||||
calculated_leverage = final_dynamic_leverage
|
||||
calculated_leverage = await self.calculate_dynamic_leverage(
|
||||
symbol=symbol,
|
||||
entry_price=entry_price if entry_price else current_price,
|
||||
stop_loss_price=stop_loss_price,
|
||||
atr=atr,
|
||||
side=side
|
||||
)
|
||||
|
||||
# 确定最终使用的杠杆
|
||||
# 优先级: 动态计算杠杆 > 传入的leverage参数 > 配置的默认LEVERAGE
|
||||
|
|
|
|||
|
|
@ -489,14 +489,23 @@ class TradeRecommender:
|
|||
entry_price = suggested_limit_price
|
||||
|
||||
# 估算仓位数量和杠杆(用于计算止损止盈)
|
||||
# 1. 优先计算动态杠杆(基于波动率和风险)
|
||||
atr = symbol_info.get('atr')
|
||||
leverage = await self.risk_manager.calculate_dynamic_leverage(
|
||||
symbol,
|
||||
entry_price,
|
||||
stop_loss_price=None, # 让内部使用ATR自动估算止损来计算杠杆
|
||||
atr=atr,
|
||||
side=direction
|
||||
)
|
||||
|
||||
# 重要语义:suggested_position_pct 表示“保证金占用比例”
|
||||
account_balance = symbol_info.get('account_balance', 1000)
|
||||
# 使用传入的 account_balance (默认为1000用于展示)
|
||||
suggested_position_pct = symbol_info.get('suggested_position_pct', 0.05)
|
||||
leverage = config.TRADING_CONFIG.get('LEVERAGE', 10)
|
||||
|
||||
# 估算保证金与名义价值
|
||||
estimated_margin = account_balance * suggested_position_pct
|
||||
estimated_notional = estimated_margin * leverage if leverage and leverage > 0 else estimated_margin
|
||||
estimated_notional = estimated_margin * leverage
|
||||
estimated_quantity = estimated_notional / entry_price if entry_price > 0 else 0
|
||||
|
||||
# 计算基于保证金的止损止盈
|
||||
|
|
@ -593,7 +602,8 @@ class TradeRecommender:
|
|||
# 生成用户指南(人话版计划)
|
||||
user_guide = self._generate_user_guide(
|
||||
symbol, direction, suggested_limit_price, stop_loss_price, take_profit_1, take_profit_2,
|
||||
simple_reason, expected_hold_time, risk_warning, recommendation_category, current_price
|
||||
simple_reason, expected_hold_time, risk_warning, recommendation_category, current_price,
|
||||
leverage, suggested_position_pct
|
||||
)
|
||||
|
||||
# 基础推荐数据
|
||||
|
|
@ -626,7 +636,7 @@ class TradeRecommender:
|
|||
# 计划入场价(限价挂单价)作为止损/止盈计算基准
|
||||
'planned_entry_price': entry_price,
|
||||
'suggested_position_percent': suggested_position_pct,
|
||||
'suggested_leverage': config.TRADING_CONFIG.get('LEVERAGE', 10),
|
||||
'suggested_leverage': leverage,
|
||||
'volume_24h': symbol_info.get('volume24h'),
|
||||
'volatility': symbol_info.get('volatility'),
|
||||
'estimated_win_rate': round(estimated_win_rate, 1),
|
||||
|
|
@ -869,7 +879,9 @@ class TradeRecommender:
|
|||
expected_hold_time: str,
|
||||
risk_warning: str,
|
||||
category: str,
|
||||
current_price: float
|
||||
current_price: float,
|
||||
leverage: int,
|
||||
position_pct: float
|
||||
) -> str:
|
||||
"""
|
||||
生成用户指南(人话版计划)
|
||||
|
|
@ -886,6 +898,8 @@ class TradeRecommender:
|
|||
risk_warning: 风险警告
|
||||
category: 推荐分类
|
||||
current_price: 当前价格(用于计算反向波动)
|
||||
leverage: 建议杠杆
|
||||
position_pct: 建议仓位(保证金比例)
|
||||
|
||||
Returns:
|
||||
用户指南文本
|
||||
|
|
@ -910,6 +924,10 @@ class TradeRecommender:
|
|||
【明确的入场价】
|
||||
建议在 {limit_price:.4f} USDT 附近{direction_action}
|
||||
|
||||
【资金管理】
|
||||
• 建议杠杆: {leverage}x
|
||||
• 建议仓位: 保证金占用总资金的 {position_pct*100:.1f}%
|
||||
|
||||
【具体点位】
|
||||
• 建议挂单价: {limit_price:.4f} USDT
|
||||
• 止损价: {stop_loss:.4f} USDT
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user