From bc3041dcf23ef50bcfd8b1f657d75f7cee2b61dc Mon Sep 17 00:00:00 2001 From: dekun Date: Sun, 2 Aug 2026 11:51:38 +0800 Subject: [PATCH] ATM panel: show ask/bid by position state and live option leverage. Co-authored-by: Cursor --- frontend/src/pages/Plan.tsx | 84 ++++++++++++++++++++++++++++++------- 1 file changed, 70 insertions(+), 14 deletions(-) diff --git a/frontend/src/pages/Plan.tsx b/frontend/src/pages/Plan.tsx index 6068ccb..d03720b 100644 --- a/frontend/src/pages/Plan.tsx +++ b/frontend/src/pages/Plan.tsx @@ -22,6 +22,24 @@ function fmtBidLiq(px: number | null | undefined, sz: number | null | undefined) return `${fmt(px)}/${s}`; } +/** 期权杠杆 = 标的 ÷ 权利金 */ +function optionLevLabel( + underlying: number | null | undefined, + premium: number | null | undefined, +) { + if ( + underlying == null || + premium == null || + !Number.isFinite(underlying) || + !Number.isFinite(premium) || + underlying <= 0 || + premium <= 0 + ) { + return "—"; + } + return `${(underlying / premium).toFixed(0)}x`; +} + function pnlClass(n: number | null | undefined) { if (n == null || Number.isNaN(n) || n === 0) return ""; return n > 0 ? "pos-pnl-profit" : "pos-pnl-loss"; @@ -731,20 +749,58 @@ export default function PlanPage() { {open ? "持仓期权" : "期权 ATM"} {snap?.pair ? ` @ ${snap.pair.strike}` : ""} -
- Call 卖一/买一 - - {fmtTop(snap?.call?.ask, snap?.call?.ask_sz)} /{" "} - {fmtTop(snap?.call?.bid, snap?.call?.bid_sz)} - -
-
- Put 卖一/买一 - - {fmtTop(snap?.put?.ask, snap?.put?.ask_sz)} /{" "} - {fmtTop(snap?.put?.bid, snap?.put?.bid_sz)} - -
+ {(() => { + const under = + snap?.index_px ?? + (snap?.perp?.bid != null && snap?.perp?.ask != null + ? (snap.perp.bid + snap.perp.ask) / 2 + : snap?.perp?.mark_px ?? null); + const callPx = open ? snap?.call?.bid : snap?.call?.ask; + const callSz = open ? snap?.call?.bid_sz : snap?.call?.ask_sz; + const putPx = open ? snap?.put?.bid : snap?.put?.ask; + const putSz = open ? snap?.put?.bid_sz : snap?.put?.ask_sz; + const sideLabel = open ? "买一/流动性" : "卖一/流动性"; + const callLev = optionLevLabel(under, callPx); + const putLev = optionLevLabel(under, putPx); + const heldSide = String(pos?.option_side || "").toLowerCase(); + const heldLev = + open && pos?.option_leverage != null + ? `${fmt(pos.option_leverage, 0)}x` + : open && heldSide === "call" + ? callLev + : open && heldSide === "put" + ? putLev + : null; + return ( + <> +
+ Call {sideLabel} + + {fmtTop(callPx, callSz)} + {!open ? ` · 杠杆 ${callLev}` : ""} + +
+
+ Put {sideLabel} + + {fmtTop(putPx, putSz)} + {!open ? ` · 杠杆 ${putLev}` : ""} + +
+
+ 实际杠杆 + + {open + ? heldLev || + (heldSide + ? "—" + : `Call ${callLev} · Put ${putLev}`) + : `Call ${callLev} · Put ${putLev}`} + +
+ + ); + })()}
距现价