币本位盈亏双显ETH/U(按指数换算);平仓卖币改为卖光交易户可用余额

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-08-20 17:45:32 +08:00
parent d4d2110412
commit f5c553844f
9 changed files with 235 additions and 48 deletions
+29 -7
View File
@@ -1075,7 +1075,7 @@ function refreshOrderDefaults(){
}).catch(()=>{});
}
function paintRealtimePnl(v, unit){
function paintRealtimePnl(v, unit, spotPx){
const nodes = document.querySelectorAll('[data-funds-field="realtime-pnl"]');
if(!nodes.length) return;
if(v === null || v === undefined || Number.isNaN(Number(v))){
@@ -1088,11 +1088,23 @@ function paintRealtimePnl(v, unit){
const n = Number(v);
const u = String(unit || lastRealtimePnlUnit || "U").toUpperCase() || "U";
lastRealtimePnlUnit = u;
if (spotPx != null && Number.isFinite(Number(spotPx)) && Number(spotPx) > 0) {
lastRealtimePnlSpotPx = Number(spotPx);
}
const sign = n > 0 ? "+" : "";
let text;
if (u === "ETH" || u === "BTC") {
const abs = Math.abs(n).toFixed(8).replace(/\.?0+$/, "") || "0";
text = `${n < 0 ? "-" : sign}${abs}${u}`;
const coinTxt = `${n < 0 ? "-" : sign}${abs} ${u}`;
const px = Number(spotPx != null ? spotPx : lastRealtimePnlSpotPx);
if (Number.isFinite(px) && px > 0) {
const uu = n * px;
const uAbs = Math.abs(uu).toFixed(2);
const uSign = uu < 0 ? "-" : uu > 0 ? "+" : "";
text = `${coinTxt} / ${uSign}${uAbs}U`;
} else {
text = coinTxt;
}
} else {
text = `${sign}${n.toFixed(2)}U`;
}
@@ -1104,15 +1116,16 @@ function paintRealtimePnl(v, unit){
}
let lastRealtimePnl = null;
let lastRealtimePnlUnit = "U";
function updateRealtimePnl(v, unit){
let lastRealtimePnlSpotPx = null;
function updateRealtimePnl(v, unit, spotPx){
if(v != null && !Number.isNaN(Number(v))){
lastRealtimePnl = Number(v);
if (unit) lastRealtimePnlUnit = String(unit).toUpperCase();
paintRealtimePnl(v, lastRealtimePnlUnit);
paintRealtimePnl(v, lastRealtimePnlUnit, spotPx);
return;
}
if(lastRealtimePnl != null) return;
paintRealtimePnl(v, lastRealtimePnlUnit);
paintRealtimePnl(v, lastRealtimePnlUnit, spotPx);
}
function sumOrdersFloatPnl(orders){
if(!orders || !orders.length) return null;
@@ -1143,14 +1156,23 @@ function paintRealtimePnlFromSnapshot(data){
const opt = data.options_unrealized_pnl;
const coinMode = String(data.options_margin_mode || "").toLowerCase() === "coin";
const underly = String(data.options_underly || "ETH").toUpperCase() || "ETH";
const spotPx = data.options_index_px != null ? Number(data.options_index_px) : null;
if (coinMode && opt != null && !Number.isNaN(Number(opt))) {
if (perp != null && Math.abs(Number(perp)) >= 0.005) {
const optAbs = Math.abs(Number(opt)).toFixed(8).replace(/\.?0+$/, "") || "0";
const optSign = Number(opt) > 0 ? "+" : (Number(opt) < 0 ? "-" : "");
const perpSign = Number(perp) > 0 ? "+" : "";
const text = `${perpSign}${Number(perp).toFixed(2)}U / ${optSign}${optAbs}${underly}`;
let optPart = `${optSign}${optAbs} ${underly}`;
if (Number.isFinite(spotPx) && spotPx > 0) {
const uu = Number(opt) * spotPx;
const uAbs = Math.abs(uu).toFixed(2);
const uSign = uu < 0 ? "-" : uu > 0 ? "+" : "";
optPart += ` / ${uSign}${uAbs}U`;
}
const text = `${perpSign}${Number(perp).toFixed(2)}U / ${optPart}`;
lastRealtimePnl = Number(opt);
lastRealtimePnlUnit = underly;
lastRealtimePnlSpotPx = spotPx;
document.querySelectorAll('[data-funds-field="realtime-pnl"]').forEach((pnlEl) => {
pnlEl.innerText = text;
const n = Number(opt) + Number(perp);
@@ -1159,7 +1181,7 @@ function paintRealtimePnlFromSnapshot(data){
});
return;
}
paintRealtimePnl(opt, underly);
paintRealtimePnl(opt, underly, spotPx);
return;
}
const combined = combineRealtimeFloatPnl(perp, opt);
+29 -7
View File
@@ -1556,7 +1556,7 @@ function refreshOrderDefaults(){
}).catch(()=>{});
}
function paintRealtimePnl(v, unit){
function paintRealtimePnl(v, unit, spotPx){
const nodes = document.querySelectorAll('[data-funds-field="realtime-pnl"]');
if(!nodes.length) return;
if(v === null || v === undefined || Number.isNaN(Number(v))){
@@ -1569,11 +1569,23 @@ function paintRealtimePnl(v, unit){
const n = Number(v);
const u = String(unit || lastRealtimePnlUnit || "U").toUpperCase() || "U";
lastRealtimePnlUnit = u;
if (spotPx != null && Number.isFinite(Number(spotPx)) && Number(spotPx) > 0) {
lastRealtimePnlSpotPx = Number(spotPx);
}
const sign = n > 0 ? "+" : "";
let text;
if (u === "ETH" || u === "BTC") {
const abs = Math.abs(n).toFixed(8).replace(/\.?0+$/, "") || "0";
text = `${n < 0 ? "-" : sign}${abs}${u}`;
const coinTxt = `${n < 0 ? "-" : sign}${abs} ${u}`;
const px = Number(spotPx != null ? spotPx : lastRealtimePnlSpotPx);
if (Number.isFinite(px) && px > 0) {
const uu = n * px;
const uAbs = Math.abs(uu).toFixed(2);
const uSign = uu < 0 ? "-" : uu > 0 ? "+" : "";
text = `${coinTxt} / ${uSign}${uAbs}U`;
} else {
text = coinTxt;
}
} else {
text = `${sign}${n.toFixed(2)}U`;
}
@@ -1585,15 +1597,16 @@ function paintRealtimePnl(v, unit){
}
let lastRealtimePnl = null;
let lastRealtimePnlUnit = "U";
function updateRealtimePnl(v, unit){
let lastRealtimePnlSpotPx = null;
function updateRealtimePnl(v, unit, spotPx){
if(v != null && !Number.isNaN(Number(v))){
lastRealtimePnl = Number(v);
if (unit) lastRealtimePnlUnit = String(unit).toUpperCase();
paintRealtimePnl(v, lastRealtimePnlUnit);
paintRealtimePnl(v, lastRealtimePnlUnit, spotPx);
return;
}
if(lastRealtimePnl != null) return;
paintRealtimePnl(v, lastRealtimePnlUnit);
paintRealtimePnl(v, lastRealtimePnlUnit, spotPx);
}
function sumOrdersFloatPnl(orders){
if(!orders || !orders.length) return null;
@@ -1624,15 +1637,24 @@ function paintRealtimePnlFromSnapshot(data){
const opt = data.options_unrealized_pnl;
const coinMode = String(data.options_margin_mode || "").toLowerCase() === "coin";
const underly = String(data.options_underly || "ETH").toUpperCase() || "ETH";
const spotPx = data.options_index_px != null ? Number(data.options_index_px) : null;
if (coinMode && opt != null && !Number.isNaN(Number(opt))) {
// 币本位期权盈亏单位为币,勿与永续 U 混加成「xxU」
if (perp != null && Math.abs(Number(perp)) >= 0.005) {
const optAbs = Math.abs(Number(opt)).toFixed(8).replace(/\.?0+$/, "") || "0";
const optSign = Number(opt) > 0 ? "+" : (Number(opt) < 0 ? "-" : "");
const perpSign = Number(perp) > 0 ? "+" : "";
const text = `${perpSign}${Number(perp).toFixed(2)}U / ${optSign}${optAbs}${underly}`;
let optPart = `${optSign}${optAbs} ${underly}`;
if (Number.isFinite(spotPx) && spotPx > 0) {
const uu = Number(opt) * spotPx;
const uAbs = Math.abs(uu).toFixed(2);
const uSign = uu < 0 ? "-" : uu > 0 ? "+" : "";
optPart += ` / ${uSign}${uAbs}U`;
}
const text = `${perpSign}${Number(perp).toFixed(2)}U / ${optPart}`;
lastRealtimePnl = Number(opt);
lastRealtimePnlUnit = underly;
lastRealtimePnlSpotPx = spotPx;
document.querySelectorAll('[data-funds-field="realtime-pnl"]').forEach((pnlEl) => {
pnlEl.innerText = text;
const n = Number(opt) + Number(perp);
@@ -1641,7 +1663,7 @@ function paintRealtimePnlFromSnapshot(data){
});
return;
}
paintRealtimePnl(opt, underly);
paintRealtimePnl(opt, underly, spotPx);
return;
}
const combined = combineRealtimeFloatPnl(perp, opt);