ATM panel: show ask/bid by position state and live option leverage.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+70
-14
@@ -22,6 +22,24 @@ function fmtBidLiq(px: number | null | undefined, sz: number | null | undefined)
|
|||||||
return `${fmt(px)}/${s}`;
|
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) {
|
function pnlClass(n: number | null | undefined) {
|
||||||
if (n == null || Number.isNaN(n) || n === 0) return "";
|
if (n == null || Number.isNaN(n) || n === 0) return "";
|
||||||
return n > 0 ? "pos-pnl-profit" : "pos-pnl-loss";
|
return n > 0 ? "pos-pnl-profit" : "pos-pnl-loss";
|
||||||
@@ -731,20 +749,58 @@ export default function PlanPage() {
|
|||||||
{open ? "持仓期权" : "期权 ATM"}
|
{open ? "持仓期权" : "期权 ATM"}
|
||||||
{snap?.pair ? ` @ ${snap.pair.strike}` : ""}
|
{snap?.pair ? ` @ ${snap.pair.strike}` : ""}
|
||||||
</h3>
|
</h3>
|
||||||
<div className="kv">
|
{(() => {
|
||||||
<span>Call 卖一/买一</span>
|
const under =
|
||||||
<span className="mono">
|
snap?.index_px ??
|
||||||
{fmtTop(snap?.call?.ask, snap?.call?.ask_sz)} /{" "}
|
(snap?.perp?.bid != null && snap?.perp?.ask != null
|
||||||
{fmtTop(snap?.call?.bid, snap?.call?.bid_sz)}
|
? (snap.perp.bid + snap.perp.ask) / 2
|
||||||
</span>
|
: snap?.perp?.mark_px ?? null);
|
||||||
</div>
|
const callPx = open ? snap?.call?.bid : snap?.call?.ask;
|
||||||
<div className="kv">
|
const callSz = open ? snap?.call?.bid_sz : snap?.call?.ask_sz;
|
||||||
<span>Put 卖一/买一</span>
|
const putPx = open ? snap?.put?.bid : snap?.put?.ask;
|
||||||
<span className="mono">
|
const putSz = open ? snap?.put?.bid_sz : snap?.put?.ask_sz;
|
||||||
{fmtTop(snap?.put?.ask, snap?.put?.ask_sz)} /{" "}
|
const sideLabel = open ? "买一/流动性" : "卖一/流动性";
|
||||||
{fmtTop(snap?.put?.bid, snap?.put?.bid_sz)}
|
const callLev = optionLevLabel(under, callPx);
|
||||||
</span>
|
const putLev = optionLevLabel(under, putPx);
|
||||||
</div>
|
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 (
|
||||||
|
<>
|
||||||
|
<div className="kv">
|
||||||
|
<span>Call {sideLabel}</span>
|
||||||
|
<span className="mono">
|
||||||
|
{fmtTop(callPx, callSz)}
|
||||||
|
{!open ? ` · 杠杆 ${callLev}` : ""}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className="kv">
|
||||||
|
<span>Put {sideLabel}</span>
|
||||||
|
<span className="mono">
|
||||||
|
{fmtTop(putPx, putSz)}
|
||||||
|
{!open ? ` · 杠杆 ${putLev}` : ""}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className="kv">
|
||||||
|
<span>实际杠杆</span>
|
||||||
|
<span className="mono">
|
||||||
|
{open
|
||||||
|
? heldLev ||
|
||||||
|
(heldSide
|
||||||
|
? "—"
|
||||||
|
: `Call ${callLev} · Put ${putLev}`)
|
||||||
|
: `Call ${callLev} · Put ${putLev}`}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
})()}
|
||||||
<div className="kv">
|
<div className="kv">
|
||||||
<span>距现价</span>
|
<span>距现价</span>
|
||||||
<span className="mono">
|
<span className="mono">
|
||||||
|
|||||||
Reference in New Issue
Block a user