update
This commit is contained in:
parent
ae762c94cb
commit
9fceadcb27
@ -130,7 +130,8 @@ class Settings(BaseSettings):
|
|||||||
# 模拟交易配置
|
# 模拟交易配置
|
||||||
paper_trading_enabled: bool = True # 是否启用模拟交易
|
paper_trading_enabled: bool = True # 是否启用模拟交易
|
||||||
paper_trading_initial_balance: float = 10000 # 初始本金 (USDT)
|
paper_trading_initial_balance: float = 10000 # 初始本金 (USDT)
|
||||||
paper_trading_leverage: int = 20 # 杠杆倍数(全仓模式下的最大杠杆)
|
paper_trading_leverage: int = 20 # 单笔订单杠杆倍数
|
||||||
|
paper_trading_max_total_leverage: float = 10 # 总杠杆上限(持仓+挂单,倍数)
|
||||||
paper_trading_margin_per_order: float = 1000 # 每单保证金 (USDT)
|
paper_trading_margin_per_order: float = 1000 # 每单保证金 (USDT)
|
||||||
paper_trading_max_orders: int = 10 # 最大持仓+挂单总数
|
paper_trading_max_orders: int = 10 # 最大持仓+挂单总数
|
||||||
paper_trading_auto_close_opposite: bool = False # 是否自动平掉反向持仓(智能策略)
|
paper_trading_auto_close_opposite: bool = False # 是否自动平掉反向持仓(智能策略)
|
||||||
|
|||||||
@ -27,6 +27,7 @@ class PaperTradingService:
|
|||||||
self.max_orders = self.settings.paper_trading_max_orders # 最大订单数
|
self.max_orders = self.settings.paper_trading_max_orders # 最大订单数
|
||||||
self.auto_close_opposite = self.settings.paper_trading_auto_close_opposite # 是否自动平掉反向持仓
|
self.auto_close_opposite = self.settings.paper_trading_auto_close_opposite # 是否自动平掉反向持仓
|
||||||
self.breakeven_threshold = self.settings.paper_trading_breakeven_threshold # 保本止损触发阈值
|
self.breakeven_threshold = self.settings.paper_trading_breakeven_threshold # 保本止损触发阈值
|
||||||
|
self.max_total_leverage = self.settings.paper_trading_max_total_leverage # 总杠杆上限
|
||||||
|
|
||||||
# 移动止损配置
|
# 移动止损配置
|
||||||
self.trailing_stop_enabled = self.settings.paper_trading_trailing_stop_enabled
|
self.trailing_stop_enabled = self.settings.paper_trading_trailing_stop_enabled
|
||||||
@ -48,7 +49,8 @@ class PaperTradingService:
|
|||||||
# 加载活跃订单到内存
|
# 加载活跃订单到内存
|
||||||
self._load_active_orders()
|
self._load_active_orders()
|
||||||
|
|
||||||
logger.info(f"交易服务初始化完成(自动平反向持仓: {'启用' if self.auto_close_opposite else '禁用'},"
|
logger.info(f"交易服务初始化完成(单笔杠杆: {self.leverage}x,总杠杆上限: {self.max_total_leverage}x,"
|
||||||
|
f"自动平反向持仓: {'启用' if self.auto_close_opposite else '禁用'},"
|
||||||
f"保本止损阈值: {self.breakeven_threshold}%,"
|
f"保本止损阈值: {self.breakeven_threshold}%,"
|
||||||
f"移动止损: {'启用' if self.trailing_stop_enabled else '禁用'},"
|
f"移动止损: {'启用' if self.trailing_stop_enabled else '禁用'},"
|
||||||
f"触发倍数: {self.trailing_stop_threshold_multiplier}x,"
|
f"触发倍数: {self.trailing_stop_threshold_multiplier}x,"
|
||||||
@ -265,6 +267,46 @@ class PaperTradingService:
|
|||||||
result['message'] = msg
|
result['message'] = msg
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
# === 检查总杠杆是否超限 ===
|
||||||
|
# 计算当前已用保证金(持仓+挂单)
|
||||||
|
current_used_margin = len(self.active_orders) * self.margin_per_order
|
||||||
|
# 新订单增加的保证金
|
||||||
|
new_margin = margin
|
||||||
|
# 新订单的总持仓价值 = 保证金 × 杠杆
|
||||||
|
new_position_value = new_margin * self.leverage
|
||||||
|
# 新增后的总持仓价值
|
||||||
|
new_total_position_value = (current_used_margin * self.leverage) + new_position_value
|
||||||
|
|
||||||
|
# 获取当前账户余额
|
||||||
|
db = db_service.get_session()
|
||||||
|
try:
|
||||||
|
closed_orders = db.query(PaperOrder).filter(
|
||||||
|
PaperOrder.status.in_([
|
||||||
|
OrderStatus.CLOSED_TP,
|
||||||
|
OrderStatus.CLOSED_SL,
|
||||||
|
OrderStatus.CLOSED_BE,
|
||||||
|
OrderStatus.CLOSED_TS,
|
||||||
|
OrderStatus.CLOSED_MANUAL
|
||||||
|
])
|
||||||
|
).all()
|
||||||
|
realized_pnl = sum(o.pnl_amount for o in closed_orders)
|
||||||
|
finally:
|
||||||
|
db.close()
|
||||||
|
|
||||||
|
current_balance = self.initial_balance + realized_pnl
|
||||||
|
|
||||||
|
# 计算新订单后的总杠杆
|
||||||
|
new_total_leverage = new_total_position_value / current_balance if current_balance > 0 else 0
|
||||||
|
|
||||||
|
if new_total_leverage > self.max_total_leverage:
|
||||||
|
msg = f"总杠杆超限!当前 {new_total_leverage:.1f}x,上限 {self.max_total_leverage}x"
|
||||||
|
logger.info(f"{msg}: {symbol} | 当前持仓价值: ${current_used_margin * self.leverage:,.0f} | "
|
||||||
|
f"新订单持仓价值: ${new_position_value:,.0f} | 总持仓价值: ${new_total_position_value:,.0f} | "
|
||||||
|
f"账户余额: ${current_balance:,.0f}")
|
||||||
|
result['message'] = msg
|
||||||
|
return result
|
||||||
|
|
||||||
|
logger.debug(f"总杠杆检查通过: {new_total_leverage:.1f}x / {self.max_total_leverage}x")
|
||||||
quantity = round(position_value, 2) # 确保持仓价值保留2位小数
|
quantity = round(position_value, 2) # 确保持仓价值保留2位小数
|
||||||
|
|
||||||
# 确定入场类型
|
# 确定入场类型
|
||||||
@ -1769,6 +1811,10 @@ class PaperTradingService:
|
|||||||
# 计算当前余额
|
# 计算当前余额
|
||||||
current_balance = self.initial_balance + realized_pnl
|
current_balance = self.initial_balance + realized_pnl
|
||||||
|
|
||||||
|
# 计算当前总杠杆(持仓价值 / 账户余额)
|
||||||
|
total_position_value = used_margin * self.leverage
|
||||||
|
current_total_leverage = total_position_value / current_balance if current_balance > 0 else 0
|
||||||
|
|
||||||
# 计算可用保证金
|
# 计算可用保证金
|
||||||
available_margin = current_balance - used_margin
|
available_margin = current_balance - used_margin
|
||||||
|
|
||||||
@ -1782,12 +1828,14 @@ class PaperTradingService:
|
|||||||
'used_margin': round(used_margin, 2),
|
'used_margin': round(used_margin, 2),
|
||||||
'available': round(available_margin, 2), # 添加 available 字段,兼容性
|
'available': round(available_margin, 2), # 添加 available 字段,兼容性
|
||||||
'available_margin': round(available_margin, 2),
|
'available_margin': round(available_margin, 2),
|
||||||
'leverage': self.leverage,
|
'leverage': self.leverage, # 单笔订单杠杆
|
||||||
|
'max_total_leverage': self.max_total_leverage, # 总杠杆上限
|
||||||
|
'current_total_leverage': round(current_total_leverage, 2), # 当前总杠杆
|
||||||
'margin_per_order': self.margin_per_order,
|
'margin_per_order': self.margin_per_order,
|
||||||
'active_orders': active_count,
|
'active_orders': active_count,
|
||||||
'max_orders': self.max_orders,
|
'max_orders': self.max_orders,
|
||||||
'available_orders': available_orders,
|
'available_orders': available_orders,
|
||||||
'total_position_value': round(used_margin * self.leverage, 2),
|
'total_position_value': round(total_position_value, 2),
|
||||||
'margin_ratio': round((used_margin / current_balance * 100), 2) if current_balance > 0 else 0,
|
'margin_ratio': round((used_margin / current_balance * 100), 2) if current_balance > 0 else 0,
|
||||||
'max_drawdown': round(account_max_drawdown, 2), # 账户最大回撤百分比
|
'max_drawdown': round(account_max_drawdown, 2), # 账户最大回撤百分比
|
||||||
'max_drawdown_amount': round(account_max_drawdown * self.initial_balance / 100, 2) if account_max_drawdown != 0 else 0, # 账户最大回撤金额
|
'max_drawdown_amount': round(account_max_drawdown * self.initial_balance / 100, 2) if account_max_drawdown != 0 else 0, # 账户最大回撤金额
|
||||||
|
|||||||
@ -135,6 +135,10 @@
|
|||||||
color: #ef4444;
|
color: #ef4444;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.stat-value.warning {
|
||||||
|
color: #f59e0b; /* 橙色警告 */
|
||||||
|
}
|
||||||
|
|
||||||
/* 统计卡片内的正值/负值样式 */
|
/* 统计卡片内的正值/负值样式 */
|
||||||
.grade-card-stats .positive {
|
.grade-card-stats .positive {
|
||||||
color: var(--accent);
|
color: var(--accent);
|
||||||
@ -1200,6 +1204,18 @@
|
|||||||
${{ account.current_balance?.toFixed(2) || '0.00' }}
|
${{ account.current_balance?.toFixed(2) || '0.00' }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="stat-card">
|
||||||
|
<div class="stat-label">总仓位价值</div>
|
||||||
|
<div class="stat-value">
|
||||||
|
${{ account.total_position_value?.toFixed(2) || '0.00' }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="stat-card">
|
||||||
|
<div class="stat-label">总杠杆率</div>
|
||||||
|
<div class="stat-value" :class="account.current_total_leverage > account.max_total_leverage * 0.8 ? 'warning' : ''">
|
||||||
|
{{ account.current_total_leverage?.toFixed(1) || '0.0' }}x / {{ account.max_total_leverage }}x
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="stat-card">
|
<div class="stat-card">
|
||||||
<div class="stat-label">收益率</div>
|
<div class="stat-label">收益率</div>
|
||||||
<div class="stat-value" :class="account.current_balance >= account.initial_balance ? 'positive' : 'negative'">
|
<div class="stat-value" :class="account.current_balance >= account.initial_balance ? 'positive' : 'negative'">
|
||||||
@ -1701,7 +1717,9 @@
|
|||||||
available_orders: 10,
|
available_orders: 10,
|
||||||
total_position_value: 0,
|
total_position_value: 0,
|
||||||
margin_ratio: 0,
|
margin_ratio: 0,
|
||||||
realized_pnl: 0
|
realized_pnl: 0,
|
||||||
|
current_total_leverage: 0, // 当前总杠杆率
|
||||||
|
max_total_leverage: 10 // 总杠杆上限
|
||||||
},
|
},
|
||||||
monitorRunning: false,
|
monitorRunning: false,
|
||||||
latestPrices: {},
|
latestPrices: {},
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user