Align options realtime PnL with bid-net and show totals in stats.
Header float PnL now uses bid recycle minus premium like position cards. Stats adds realized/open/total net PnL. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -3929,6 +3929,24 @@ html[data-theme="light"] .options-estimate-row {
|
||||
.options-pos-stats-card {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.options-stats-pnl-summary {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
gap: 10px;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
.options-stats-pnl-summary .options-stat-item {
|
||||
padding: 10px 12px;
|
||||
border-radius: 8px;
|
||||
background: rgba(127, 127, 127, 0.12);
|
||||
}
|
||||
.options-stats-pnl-summary .opt-stats-net-item .v {
|
||||
font-size: 1.15em;
|
||||
font-weight: 650;
|
||||
}
|
||||
html[data-theme="light"] .options-stats-pnl-summary .options-stat-item {
|
||||
background: rgba(0, 0, 0, 0.04);
|
||||
}
|
||||
.options-stats-panel {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
@@ -1476,6 +1476,19 @@
|
||||
}
|
||||
}
|
||||
|
||||
function paintPnlStat(el, value) {
|
||||
if (!el) return;
|
||||
if (value == null || value === "" || Number.isNaN(Number(value))) {
|
||||
el.textContent = "—";
|
||||
el.classList.remove("pos-pnl-profit", "pos-pnl-loss");
|
||||
return;
|
||||
}
|
||||
const n = Number(value);
|
||||
el.textContent = (n > 0 ? "+" : "") + fmt(n, 2) + " USDC";
|
||||
el.classList.toggle("pos-pnl-profit", n > 0);
|
||||
el.classList.toggle("pos-pnl-loss", n < 0);
|
||||
}
|
||||
|
||||
async function refreshStats() {
|
||||
const d = await apiJson("/api/options/stats");
|
||||
const winEl = document.getElementById("opt-stats-winrate");
|
||||
@@ -1487,14 +1500,23 @@
|
||||
const winHoldEl = document.getElementById("opt-stats-win-hold");
|
||||
const lossHoldEl = document.getElementById("opt-stats-loss-hold");
|
||||
const openHoldEl = document.getElementById("opt-stats-open-hold");
|
||||
const totalPnlEl = document.getElementById("opt-stats-total-pnl");
|
||||
const netRealizedEl = document.getElementById("opt-stats-net-realized");
|
||||
const openFloatEl = document.getElementById("opt-stats-open-float");
|
||||
const statEls = [winEl, plrEl, closedEl, profitEl, lossEl, avgHoldEl, winHoldEl, lossHoldEl, openHoldEl];
|
||||
if (!d.ok) {
|
||||
statEls.forEach(function (el) {
|
||||
if (el) el.textContent = "—";
|
||||
});
|
||||
paintPnlStat(totalPnlEl, null);
|
||||
paintPnlStat(netRealizedEl, null);
|
||||
paintPnlStat(openFloatEl, null);
|
||||
paintStatsCharts(null);
|
||||
return;
|
||||
}
|
||||
paintPnlStat(totalPnlEl, d.total_pnl);
|
||||
paintPnlStat(netRealizedEl, d.net_realized_pnl);
|
||||
paintPnlStat(openFloatEl, d.open_float_pnl);
|
||||
if (winEl) winEl.textContent = d.total_closed ? d.win_rate + "%" : "0%";
|
||||
if (plrEl) {
|
||||
plrEl.textContent = d.profit_loss_ratio != null ? String(d.profit_loss_ratio) : "—";
|
||||
|
||||
Reference in New Issue
Block a user