This commit is contained in:
aaron 2026-03-04 12:01:59 +08:00
parent 0b3b59fad3
commit 7e58b5203b

View File

@ -354,12 +354,13 @@ class PaperTradingService:
def _calculate_dynamic_position(self, position_size: str, symbol: str) -> tuple:
"""
根据 LLM 建议的仓位大小计算实际保证金和持仓价值复利策略
根据 LLM 建议的仓位大小计算实际保证金和持仓价值
计算逻辑
- 可用保证金 = 余额 - (持仓 + 挂单占用保证金)
- 根据 position_size 按可用保证金的百分比分配
- 持仓价值 = 保证金 × 杠杆
- 根据可用保证金的倍数确定持仓价值
- micro: 0.8x, light: 1.2x, medium: 2.0x, heavy: 3.0x
- 累计持仓价值不超过可用保证金的 15
- 保证金 = 持仓价值 / 杠杆
Args:
position_size: 'heavy' / 'medium' / 'light' / 'micro'
@ -372,44 +373,57 @@ class PaperTradingService:
account = self.get_account_status()
balance = account['current_balance']
used_margin = account['used_margin'] # 已用保证金(持仓+挂单)
total_position_value = account['total_position_value'] # 累计持仓价值
# 计算可用保证金(复利核心)
available_margin = balance - used_margin
# 计算可用保证金
available_margin = max(0, balance - used_margin)
if available_margin <= 0:
logger.warning(f"可用保证金不足,无法开仓(余额: ${balance:.2f}, 已用: ${used_margin:.2f}")
# 根据 position_size 确定倍数(相对于可用保证金)
position_multiplier = {
'micro': 0.8,
'light': 1.2,
'medium': 2.0,
'heavy': 3.0
}.get(position_size, 1.2)
# 最大累计持仓价值倍数
max_total_multiplier = 15.0
# 计算目标持仓价值 = 可用保证金 × 倍数
target_position_value = available_margin * position_multiplier
# 计算最大允许的累计持仓价值 = 可用保证金 × 15
max_total_position_value = available_margin * max_total_multiplier
# 可用的剩余持仓价值额度
available_position_value = max(0, max_total_position_value - total_position_value)
# 检查是否超过可用额度
if target_position_value > available_position_value:
logger.warning(f"目标持仓价值 ${target_position_value:.2f} 超过可用额度 ${available_position_value:.2f},调整为可用额度")
target_position_value = available_position_value
if target_position_value < 50:
logger.warning(f"可用持仓价值不足(${available_position_value:.2f}),无法开仓")
return 0, 0
# 根据 position_size 确定保证金比例(按可用保证金百分比)
# micro: 5%, light: 10%, medium: 15%, heavy: 20%
size_ratio = {
'micro': 0.05,
'light': 0.10,
'medium': 0.15,
'heavy': 0.20
}.get(position_size, 0.10)
# 计算保证金 = 持仓价值 / 杠杆
margin = target_position_value / self.leverage
# 计算目标保证金(直接使用可用保证金的百分比)
target_margin = available_margin * size_ratio
# 设置最小和最大保证金限制
min_margin = 50 # 最小保证金 50 USDT对应 1000 USDT 持仓价值)
max_single_margin = balance * 0.25 # 单笔最大不超过余额的 25%
margin = max(min_margin, min(target_margin, max_single_margin))
# 确保不超过可用保证金
margin = min(margin, available_margin)
# 确保不超过可用保证金(理论上不会超过,因为 position_value = available_margin × multiplier
if margin > available_margin:
logger.warning(f"计算保证金 ${margin:.2f} 超过可用保证金 ${available_margin:.2f},调整为可用保证金")
margin = available_margin
# 重新计算持仓价值
target_position_value = margin * self.leverage
# 修正浮点数精度问题,保留 2 位小数
margin = round(margin, 2)
position_value = round(target_position_value, 2)
# 计算持仓价值(保证金 × 杠杆)
position_value = round(margin * self.leverage, 2)
logger.info(f"动态仓位计算: {position_size} | 余额: ${balance:.2f} | 已用保证金: ${used_margin:.2f} | "
f"可用保证金: ${available_margin:.2f} | 目标保证金: ${margin:.2f} ({size_ratio*100:.0f}%) | "
f"持仓价值: ${position_value:.2f}")
logger.info(f"动态仓位计算: {position_size} | 可用保证金: ${available_margin:.2f} | "
f"累计持仓: ${total_position_value:.2f}/${max_total_position_value:.2f} | "
f"目标保证金: ${margin:.2f} | 持仓价值: ${position_value:.2f} ({position_multiplier}x, {self.leverage}x杠杆)")
return margin, position_value