Align hedge UI/fees: drop 未启动, premium coin/U, equity incl perp margin, OKX option fees.

Option net uses Min(0.03%×coin, 7%×premium) with bid/ask fills (no slip); live PnL colors fixed.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-10-14 17:12:10 +08:00
parent be00991568
commit 746655acba
12 changed files with 190 additions and 45 deletions
@@ -38,12 +38,29 @@ def is_option_primary(body_or_plan: dict[str, Any] | None) -> bool:
def fee_rate() -> float:
"""永续 taker 费率(默认 0.05%)."""
try:
return max(0.0, float(os.getenv("HEDGE_PLAN_FEE_RATE") or os.getenv("OKX_TAKER_FEE") or "0.0005"))
except (TypeError, ValueError):
return 0.0005
def option_fee_rate() -> float:
"""币本位期权 taker 费率(OKX 普通档默认 0.03%)."""
try:
return max(
0.0,
float(
os.getenv("HEDGE_PLAN_OPTION_FEE_RATE")
or os.getenv("OKX_OPTIONS_TAKER_FEE")
or os.getenv("SIM_OPTION_FEE_RATE")
or "0.0003"
),
)
except (TypeError, ValueError):
return 0.0003
def floor2(v: float) -> float:
"""ETH 数量向下取两位小数."""
if v <= 0:
@@ -201,17 +218,30 @@ def estimate_combo_net_pnl(
contracts: float,
contract_size: float,
fee: Optional[float] = None,
option_fee: Optional[float] = None,
) -> dict[str, Any]:
"""组合净利(扣费);平仓/卖出手续费按买入费率估算."""
fr = fee if fee is not None else fee_rate()
"""组合净利(扣开平双边手续费).
期权:吃卖一开/买一平(无滑点);费=Min(费率×标的币, 权利金×7%).
永续:名义×费率(开+平).
"""
from lib.sim.pricing_lib import option_fee_coin
fr_perp = fee if fee is not None else fee_rate()
fr_opt = option_fee if option_fee is not None else option_fee_rate()
ct = float(ct_mult or 0.01)
sh = float(sheets or 0)
a = float(ask_open or 0)
b = float(bid or 0)
premium = a * sh * ct
opt_proceeds = b * sh * ct
opt_open_fee = premium * fr
opt_close_fee = opt_proceeds * fr # 卖出费用按买入费率
underlying = sh * ct
premium = a * underlying
opt_proceeds = b * underlying
opt_open_fee = option_fee_coin(
underlying_coin=underlying, premium_coin=premium, fee_rate=fr_opt
)
opt_close_fee = option_fee_coin(
underlying_coin=underlying, premium_coin=opt_proceeds, fee_rate=fr_opt
)
opt_net = opt_proceeds - premium - opt_open_fee - opt_close_fee
coins = float(contracts or 0) * float(contract_size or 0.01)
@@ -224,15 +254,20 @@ def estimate_combo_net_pnl(
perp_gross = (mark - entry) * coins
perp_notional_open = abs(entry * coins)
perp_notional_close = abs(mark * coins)
perp_open_fee = perp_notional_open * fr
perp_close_fee = perp_notional_close * fr
perp_open_fee = perp_notional_open * fr_perp
perp_close_fee = perp_notional_close * fr_perp
perp_net = perp_gross - perp_open_fee - perp_close_fee
total = opt_net + perp_net
return {
"opt_net": round(opt_net, 4),
"perp_net": round(perp_net, 4),
"net": round(total, 4),
"fee_rate": fr,
"fee_rate": fr_perp,
"option_fee_rate": fr_opt,
"opt_open_fee": round(opt_open_fee, 8),
"opt_close_fee": round(opt_close_fee, 8),
"perp_open_fee": round(perp_open_fee, 4),
"perp_close_fee": round(perp_close_fee, 4),
"premium": round(premium, 4),
"opt_proceeds": round(opt_proceeds, 4),
}