From 9f3395de2fd6e3bbd7e856ddd710d2bbbf1a3785 Mon Sep 17 00:00:00 2001 From: dekun Date: Wed, 29 Jul 2026 22:38:20 +0800 Subject: [PATCH] Add sideways max-loss to perpetual-options calculator. Show premium wipeout plus flat round-trip perp fees as case C for both size and points modes. Co-authored-by: Cursor --- docs/永期对冲计算器.md | 14 ++++++++ lib/hub/hub_perp_options_calc_lib.py | 21 ++++++++++++ manual_trading_hub/static/calculator.js | 44 ++++++++++++++++++++++++- manual_trading_hub/static/index.html | 4 +-- tests/test_hub_perp_options_calc_lib.py | 11 +++++++ 5 files changed, 91 insertions(+), 3 deletions(-) diff --git a/docs/永期对冲计算器.md b/docs/永期对冲计算器.md index 1de6630..af2f403 100644 --- a/docs/永期对冲计算器.md +++ b/docs/永期对冲计算器.md @@ -65,6 +65,19 @@ API:`POST /api/calculator/perp-options` 组合净利 = 期权净利 + 永续亏损 ``` +**C · 横盘(最大亏损)** + +波动≈0、期权到期无内在价值: + +```text +永续盈亏 ≈ 0 +永续开平手续费 = 2 × 现价 × 1 × 0.05% (同价开平) +最大亏损 = 权利金总额 + 永续开平手续费 +组合净利 = −最大亏损 +``` + +忽略资金费 / Theta 过程中的中间态;口径与「权利金按全亏」一致。 + ### 手测示例 现价 1800、波动 50 点、目标盈利 15、期权杠杆 100、永续杠杆 10: @@ -126,6 +139,7 @@ move = (目标 + 权利金) / (期权币数 − 1) |------|----------------| | A 永续方向对(净利=15) | ≈52.83 | | B 组合净利=15 | 51.00 | +| C 横盘最大亏损 | 37.80(权利金 36 + 同价开平费 1.8) | --- diff --git a/lib/hub/hub_perp_options_calc_lib.py b/lib/hub/hub_perp_options_calc_lib.py index 87ae060..91b946a 100644 --- a/lib/hub/hub_perp_options_calc_lib.py +++ b/lib/hub/hub_perp_options_calc_lib.py @@ -75,6 +75,25 @@ def _move_for_perp_correct(*, spot: float, target: float, premium: float, fee_ra return (float(target) + float(premium) + 2.0 * float(spot) * float(fee_rate)) / denom +def _case_sideways(*, spot: float, premium_total: float) -> dict[str, Any]: + """横盘/到期无方向:永续≈0,期权权利金全亏,另计永续开平同价手续费. + + 最大亏损(正数) = 权利金总额 + 开平手续费(exit=entry) + 组合净利 = −最大亏损 + """ + fee_flat = estimate_roundtrip_fee_usdt(spot, spot, qty=PERP_COINS, contract_size=1.0) + prem = float(premium_total) + max_loss = prem + float(fee_flat) + return { + "label": "横盘", + "perp_pnl_u": 0.0, + "premium_u": round(prem, 8), + "fee_u": round(float(fee_flat), 8), + "max_loss_u": round(max_loss, 8), + "net_u": round(-max_loss, 8), + } + + def calc_perp_options_hedge( *, base: str = "ETH", @@ -186,6 +205,7 @@ def calc_perp_options_hedge( "perp_pnl_u": round(perp_loss, 8), "portfolio_net_u": round(portfolio_net, 8), }, + "case_sideways": _case_sideways(spot=s, premium_total=premium_total), }, None @@ -316,6 +336,7 @@ def calc_perp_options_points( "portfolio_error": port_err, "premium_u": round(premium_total, 8), }, + "case_sideways": _case_sideways(spot=s, premium_total=premium_total), }, None diff --git a/manual_trading_hub/static/calculator.js b/manual_trading_hub/static/calculator.js index 02c7017..6c826a4 100644 --- a/manual_trading_hub/static/calculator.js +++ b/manual_trading_hub/static/calculator.js @@ -572,6 +572,35 @@ } } + function renderSidewaysCase(sw) { + sw = sw || {}; + return ( + '
' + + "

情景 C · 横盘(最大亏损)

" + + '
' + + "
永续盈亏" + + fmtU(sw.perp_pnl_u != null ? sw.perp_pnl_u : 0) + + "
" + + "
权利金(全亏)" + + fmt(sw.premium_u, 2) + + "U
" + + "
永续开平手续费" + + fmt(sw.fee_u, 2) + + "U
" + + "
最大亏损' + + fmt(sw.max_loss_u, 2) + + "U
" + + "
组合净利' + + fmtU(sw.net_u) + + "
" + + "
" + ); + } + function renderPerpOptionsResult(data) { const box = $("calc-po-result"); if (!box) return; @@ -614,6 +643,11 @@ "
永续保证金" + fmt(data.perp_margin_u, 2) + "U
" + + "
横盘最大亏损' + + fmt((data.case_sideways || {}).max_loss_u, 2) + + "U
" + "
开仓参考" + esc(capitalHint) + "
" + @@ -663,7 +697,9 @@ '">' + fmtU(b.portfolio_net_u) + "" + - ""; + "" + + renderSidewaysCase(data.case_sideways) + + ""; } function renderPerpOptionsPointsResult(data) { @@ -743,6 +779,11 @@ "
永续保证金" + fmt(data.perp_margin_u, 2) + "U
" + + "
横盘最大亏损' + + fmt((data.case_sideways || {}).max_loss_u, 2) + + "U
" + "
开仓参考" + esc(capitalHint) + "
" + @@ -774,6 +815,7 @@ "" + "" + caseB + + renderSidewaysCase(data.case_sideways) + ""; } diff --git a/manual_trading_hub/static/index.html b/manual_trading_hub/static/index.html index c307142..97ae43b 100644 --- a/manual_trading_hub/static/index.html +++ b/manual_trading_hub/static/index.html @@ -966,7 +966,7 @@

永期对冲计算器

-

永续固定 1 币;单币权利金 = 现价 / 期权杠杆;权利金按全亏;只扣永续开平手续费(各 0.05%).「推仓位」由波动反推期权数量;「推点数」按永续:期权比例反推达目标盈利所需波动.

+

永续固定 1 币;单币权利金 = 现价 / 期权杠杆;权利金按全亏;只扣永续开平手续费(各 0.05%).「推仓位」由波动反推期权数量;「推点数」按永续:期权比例反推达目标盈利所需波动.横盘最大亏损 = 权利金全亏 + 永续开平同价手续费.