Add hub TP profit field, 2-decimal options PnL, and exchange mark price display.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -455,7 +455,7 @@
|
||||
'<div class="pos-cell"><span class="pos-label">指数价</span><span class="pos-value">' + fmt(p.idx_px, 0) + "</span></div>" +
|
||||
'<div class="pos-cell"><span class="pos-label">到期平衡</span><span class="pos-value">' + fmt(p.expiry_be_px, 0) + "</span></div>" +
|
||||
'<div class="pos-cell"><span class="pos-label">平掉回本</span><span class="pos-value">' + fmt(p.close_be_px, 0) + "</span></div>" +
|
||||
'<div class="pos-cell"><span class="pos-label">浮盈亏</span><span class="pos-value ' + uplCls + '">' + fmt(p.upl, 4) + "</span></div>" +
|
||||
'<div class="pos-cell"><span class="pos-label">浮盈亏</span><span class="pos-value ' + uplCls + '">' + fmt(p.upl, 2) + "</span></div>" +
|
||||
'<div class="pos-cell"><span class="pos-label">收益率</span><span class="pos-value ' + uplCls + '">' +
|
||||
(p.upl_ratio_pct != null ? p.upl_ratio_pct + "%" : "—") + "</span></div>" +
|
||||
"</div></div>"
|
||||
|
||||
@@ -920,6 +920,7 @@ function formatOrderMarkDisplay(o){
|
||||
const hasMark = markRaw !== null && markRaw !== undefined && markRaw !== "" && Number.isFinite(markNum) && markNum > 0;
|
||||
if(hasMark){
|
||||
if(row.exchange_mark_price_display && row.exchange_mark_price_display !== "-") return row.exchange_mark_price_display;
|
||||
if(row.price_display && row.price_display !== "-") return row.price_display;
|
||||
return markNum.toFixed(6);
|
||||
}
|
||||
if(row.price_display && row.price_display !== "-") return row.price_display;
|
||||
|
||||
@@ -137,4 +137,4 @@
|
||||
</div>
|
||||
</div>
|
||||
<script src="/static/options_expiry_countdown.js?v=1"></script>
|
||||
<script src="/static/options_panel.js?v=13"></script>
|
||||
<script src="/static/options_panel.js?v=14"></script>
|
||||
|
||||
@@ -355,6 +355,12 @@ def apply_order_price_display_fields(
|
||||
payload["take_profit_display"] = (
|
||||
format_price_fn(symbol, disp_tp) if disp_tp is not None else "—"
|
||||
)
|
||||
mark_raw = mark_price if mark_price is not None else None
|
||||
if mark_raw is not None and format_price_fn is not None and symbol is not None:
|
||||
try:
|
||||
payload["exchange_mark_price_display"] = format_price_fn(symbol, float(mark_raw))
|
||||
except (TypeError, ValueError):
|
||||
payload["exchange_mark_price_display"] = None
|
||||
return payload
|
||||
|
||||
|
||||
|
||||
@@ -1989,6 +1989,7 @@ _ORDER_PRICE_MERGE_KEYS = (
|
||||
"display_rr_ratio",
|
||||
"latest_risk_amount",
|
||||
"contracts",
|
||||
"reward_at_tp_usdt",
|
||||
"exchange_initial_margin",
|
||||
"plan_margin",
|
||||
"time_close_enabled",
|
||||
@@ -2120,6 +2121,17 @@ def _merge_flask_position_breakeven(agent_row: dict, snap: dict | None, hub_mon:
|
||||
break
|
||||
if isinstance(matched, dict):
|
||||
_apply_order_price_op_fields(p, matched)
|
||||
disp = matched.get("exchange_mark_price_display")
|
||||
if disp is not None and str(disp).strip() not in ("", "-"):
|
||||
p["mark_price_fmt"] = str(disp)
|
||||
mp = matched.get("exchange_mark_price")
|
||||
if mp is not None:
|
||||
try:
|
||||
mpf = float(mp)
|
||||
if mpf > 0:
|
||||
p["mark_price"] = mpf
|
||||
except (TypeError, ValueError):
|
||||
pass
|
||||
|
||||
|
||||
def _agent_position_has_mark(p: dict) -> bool:
|
||||
|
||||
@@ -1968,6 +1968,15 @@ body.market-chart-fs-open {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.hub-pos-card .pos-tp-profit {
|
||||
color: #4cd97f;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
html[data-theme="light"] .hub-pos-card .pos-tp-profit {
|
||||
color: #1a8f4a;
|
||||
}
|
||||
|
||||
.hub-pos-card .pos-footer {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
@@ -116,7 +116,7 @@
|
||||
function positionTableHeadHtml(compact) {
|
||||
const pnlTh = showAccountPnlPref() ? "<th>浮盈</th>" : "";
|
||||
const cls = compact ? " data-table data-table-positions" : "";
|
||||
return `<table class="data-table${cls}"><thead><tr><th>合约</th><th>方向</th><th>开仓价</th><th>标记价</th><th>张数</th>${pnlTh}<th>操作</th></tr></thead><tbody>`;
|
||||
return `<table class="data-table${cls}"><thead><tr><th>合约</th><th>方向</th><th>开仓价</th><th>标记价</th><th>张数</th><th>盈利金额</th>${pnlTh}<th>操作</th></tr></thead><tbody>`;
|
||||
}
|
||||
let tpslPending = null;
|
||||
let lastMonitorRows = [];
|
||||
@@ -864,6 +864,26 @@
|
||||
return null;
|
||||
}
|
||||
|
||||
function resolveTpProfitUsdt(mo, pos) {
|
||||
const m = mo || {};
|
||||
const p = pos || {};
|
||||
const raw =
|
||||
m.reward_at_tp_usdt != null && m.reward_at_tp_usdt !== ""
|
||||
? m.reward_at_tp_usdt
|
||||
: p.reward_at_tp_usdt != null && p.reward_at_tp_usdt !== ""
|
||||
? p.reward_at_tp_usdt
|
||||
: null;
|
||||
if (raw == null || raw === "") return null;
|
||||
const n = Number(raw);
|
||||
return Number.isFinite(n) ? n : null;
|
||||
}
|
||||
|
||||
function formatTpProfitCell(mo, pos) {
|
||||
const n = resolveTpProfitUsdt(mo, pos);
|
||||
if (n == null) return "—";
|
||||
return `<span class="pos-tp-profit">${fmt(n, 2)}U</span>`;
|
||||
}
|
||||
|
||||
function formatMonitorRiskMeta(mo, trendPlan) {
|
||||
const m = mo || {};
|
||||
const t = trendPlan || {};
|
||||
@@ -3155,7 +3175,8 @@
|
||||
<div class="pos-cell"><span class="pos-label">止损</span><span class="pos-value">${sl != null && sl !== "" ? fmtSymbolPrice(sl, symbol, tickMap) : "—"}</span></div>
|
||||
<div class="pos-cell"><span class="pos-label">止盈</span><span class="pos-value${tpMonitored ? " pos-tp-program" : ""}">${formatTpCellValue(tp, tpMonitored, symbol, tickMap)}</span></div>
|
||||
<div class="pos-cell"><span class="pos-label">盈亏比</span><span class="pos-value">${rr != null ? fmt(rr, 2) + ":1" : "—"}</span></div>
|
||||
<div class="pos-cell"><span class="pos-label">张数</span><span class="pos-value">${fmt(pos.contracts, 4)}</span></div>
|
||||
<div class="pos-cell"><span class="pos-label">张数</span><span class="pos-value">${fmt(pos.contracts, 2)}</span></div>
|
||||
<div class="pos-cell"><span class="pos-label">盈利金额</span><span class="pos-value">${formatTpProfitCell(mo, pos)}</span></div>
|
||||
${
|
||||
showAccountPnlPref()
|
||||
? `<div class="pos-cell"><span class="pos-label">浮盈亏</span><span class="pos-value ${pnlFmt.cls}">${pnlText}</span></div>`
|
||||
@@ -3308,12 +3329,14 @@
|
||||
const pnlTd = showAccountPnlPref()
|
||||
? `<td class="${pnlCls(x.unrealized_pnl)}">${fmt(x.unrealized_pnl, 2)}</td>`
|
||||
: "";
|
||||
const tpProfitTd = `<td>${formatTpProfitCell(monitorOrder, x)}</td>`;
|
||||
return `<tr>
|
||||
<td class="td-symbol"><button type="button" class="btn-open-market sym-link" ${mktAttrs} title="打开行情区(含入场/止盈止损)">${esc(x.symbol)}</button>${tcBadge}${fcBadge}${symBeBadge}</td>
|
||||
<td class="${sideDirCls(x.side)}">${renderDirectionHtml(x.side)}</td>
|
||||
<td class="td-entry">${fmtEntryPrice(x, tickMap)}</td>
|
||||
<td>${fmtMarkPrice(x, tickMap)}</td>
|
||||
<td>${fmt(x.contracts, 4)}</td>
|
||||
<td>${fmt(x.contracts, 2)}</td>
|
||||
${tpProfitTd}
|
||||
${pnlTd}
|
||||
<td class="td-actions">${actionCell}</td>
|
||||
</tr>`;
|
||||
@@ -3499,7 +3522,7 @@
|
||||
<td>${p.idx_px != null ? fmt(p.idx_px, 0) : "—"}</td>
|
||||
<td>${p.expiry_be_px != null ? fmt(p.expiry_be_px, 0) : "—"}</td>
|
||||
<td>${p.close_be_px != null ? fmt(p.close_be_px, 0) : "—"}</td>
|
||||
<td class="${pnlCls(p.upl)}">${fmt(p.upl, 4)}</td>
|
||||
<td class="${pnlCls(p.upl)}">${fmt(p.upl, 2)}</td>
|
||||
<td class="${pnlCls(p.upl)}">${p.upl_ratio_pct != null ? esc(p.upl_ratio_pct) + "%" : "—"}</td>
|
||||
</tr>`;
|
||||
});
|
||||
|
||||
@@ -1152,6 +1152,6 @@
|
||||
<script src="/assets/time_close_ui.js?v=3"></script>
|
||||
<script src="/assets/options_expiry_countdown.js?v=1"></script>
|
||||
<script src="/assets/backup.js?v=1"></script>
|
||||
<script src="/assets/app.js?v=20260708-options-expiry-cd"></script>
|
||||
<script src="/assets/app.js?v=20260708-hub-tp-profit"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user