feat: 盈亏计算改为保证金%(开仓成本%)

- risk_leverage=100: 0.01手按7保证金算,不改变实际杠杆
- _calculate_pnl_pct: dollar_pnl / position_margin
- 硬止损: 保证金% × 开仓保证金 × 倍率
- RISK_CONFIG: SL-50%/TP+100%/拖尾+70%/回撤35%(均为保证金%)
This commit is contained in:
silencesdg
2026-05-14 18:15:18 +08:00
parent 9b0eeb521e
commit 0fcd676a0a
3 changed files with 29 additions and 12 deletions
+1 -1
View File
@@ -1 +1 @@
162796
185384
+8 -6
View File
@@ -142,12 +142,14 @@ SIGNAL_THRESHOLDS = {
# 风险管理参数(优化器结果 2026-05-10,5万根M1数据)
RISK_CONFIG = {
# ★ 以下百分比均为账户余额%,非金价涨跌%
# 例:余额$1682-1.5% = -$25 ≈ 25点金价(0.01手)
"stop_loss_pct": -0.015, # -1.5% 账户
"profit_retracement_pct": 0.01, # 1.0% 账户(拖尾回撤容忍
"min_profit_for_trailing": 0.02, # +2.0% 后激活拖尾
"take_profit_pct": 0.03, # +3.0% 账户
# ★ 以下百分比均为保证金%(开仓成本%,非金价涨跌%、非账户%
# risk_leverage 控制计算杠杆:设100则0.01手按$47保证金算%
# 例:亏损$25 / 保证金$47 = -53%,而不是 $25/账户$1682=-1.5%
"risk_leverage": 100, # 计算杠杆(实际杠杆不变,仅影响%基准
"stop_loss_pct": -0.50, # -50% 保证金(亏一半保证金就平)
"profit_retracement_pct": 0.35, # 35% 保证金(拖尾回撤容忍)
"min_profit_for_trailing": 0.70, # +70% 保证金后激活拖尾
"take_profit_pct": 1.00, # +100% 保证金(赚一倍保证金就平)
"max_daily_loss": -0.3,
"max_holding_minutes": 133,
"min_profit_for_time_exit": 0.010,
+20 -5
View File
@@ -42,6 +42,16 @@ class PositionManager:
self.hard_sl_mult = risk.get("hard_sl_multiplier", 1.5)
self.hard_tp_mult = risk.get("hard_tp_multiplier", 1.3)
# ★ 计算杠杆(仅影响%基准,不改实际杠杆)
self.risk_leverage = risk.get("risk_leverage", 0)
if self.risk_leverage <= 0:
# 未设置则从MT5读取实际杠杆
try:
acct = self.data_provider.get_account_info()
self.risk_leverage = acct.leverage if hasattr(acct, 'leverage') else acct.get('leverage', 2000)
except Exception:
self.risk_leverage = 2000
# 资金管理
self.initial_capital = INITIAL_CAPITAL
self.long_capital_pct = CAPITAL_ALLOCATION.get("long_pct", 0.5)
@@ -189,14 +199,16 @@ class PositionManager:
return False
# ★ 计算 MT5 硬止损/硬止盈(兜底安全网)
# 公式:账户% × 余额 × 倍率 → 美元 → 金价点数 → 价格
# 公式:保证金% × 开仓保证金 × 倍率 → 美元 → 金价点数 → 价格
hard_sl_price = None
hard_tp_price = None
contract_size = self._get_contract_size()
points_per_dollar = 1.0 / (position_volume * contract_size) if position_volume > 0 else 0
sl_dollars = abs(self.stop_loss_pct) * self.total_equity * self.hard_sl_mult # 正数
tp_dollars = abs(self.take_profit_pct) * self.total_equity * self.hard_tp_mult
# 开仓保证金
position_margin = (execution_price * position_volume * contract_size) / self.risk_leverage
sl_dollars = abs(self.stop_loss_pct) * position_margin * self.hard_sl_mult # 正数
tp_dollars = abs(self.take_profit_pct) * position_margin * self.hard_tp_mult
sl_points = sl_dollars * points_per_dollar
tp_points = tp_dollars * points_per_dollar
@@ -330,17 +342,20 @@ class PositionManager:
return self._cached_contract_size
def _calculate_pnl_pct(self, position, current_price_value):
"""账户余额百分比盈亏(非金价涨跌%"""
"""保证金百分比盈亏 = 美元盈亏 / 开仓保证金"""
entry_price = position['entry_price']
quantity = position.get('quantity', 0.01)
contract_size = self._get_contract_size()
# 美元盈亏
if position['position_type'] == 'long':
dollar_pnl = (current_price_value - entry_price) * quantity * contract_size
else:
dollar_pnl = (entry_price - current_price_value) * quantity * contract_size
return dollar_pnl / self.total_equity if self.total_equity > 0 else 0.0
# 开仓保证金 = 合约价值 / 计算杠杆
margin = (entry_price * quantity * contract_size) / self.risk_leverage
return dollar_pnl / margin if margin > 0 else 0.0
def _calculate_unrealized_pnl(self) -> float:
"""计算所有持仓的浮动盈亏"""