diff --git a/lib/common/static/instance_theme.css b/lib/common/static/instance_theme.css
index a9b30d6..6504eb4 100644
--- a/lib/common/static/instance_theme.css
+++ b/lib/common/static/instance_theme.css
@@ -3372,6 +3372,15 @@ html[data-theme="light"] .settings-side-export-label {
html[data-theme="light"] .opt-chain-lev {
color: #1a4a8a;
}
+.opt-chain-delta {
+ font-variant-numeric: tabular-nums;
+ white-space: nowrap;
+ font-weight: 600;
+ color: #9ad5ff;
+}
+html[data-theme="light"] .opt-chain-delta {
+ color: #0b5cad;
+}
.opt-be-dist-up {
color: #5ee89a;
}
diff --git a/lib/common/static/options_panel.js b/lib/common/static/options_panel.js
index b696e9f..a9b6d63 100644
--- a/lib/common/static/options_panel.js
+++ b/lib/common/static/options_panel.js
@@ -477,7 +477,15 @@
}
function strikeTableColspan() {
- return 9;
+ return state.chainView === "t" ? 9 : 10;
+ }
+
+ function fmtDelta(v) {
+ if (v === null || v === undefined || v === "") return "—";
+ const n = Number(v);
+ if (!Number.isFinite(n)) return "—";
+ const sign = n > 0 ? "+" : "";
+ return sign + n.toFixed(3);
}
function syncChainViewUI() {
@@ -1308,6 +1316,7 @@
"
" + c.inst_id + " | " +
"" + fmtPxSz(c.ask, c.ask_sz, c.ask_estimated) + " | " +
'' + fmtChainLeverage(chainLev) + " | " +
+ '' + fmtDelta(c.delta) + " | " +
"" + fmtPxSz(c.bid, c.bid_sz) + " | " +
"" + (c.expiry_be_px != null ? fmt(c.expiry_be_px, 0) : "—") + " | " +
'' + fmtDist(c.dist_expiry_be) + " | " +
@@ -1734,6 +1743,9 @@
'行权价: ' + fmt(p.strike, 0) + "" +
'张数: ' + fmt(p.pos, 0) + " · 币量 " + fmt(p.eth_amount, 4) + "" +
'杠杆倍数: ' + fmtPosLeverage(p) + "" +
+ 'Delta: ' +
+ fmtDelta(p.delta != null ? p.delta : p.delta_bs) +
+ "" +
(expAttr
? '到期倒计时: —'
: "") +
@@ -1742,6 +1754,9 @@
'权利金' + premTxt + " " + premCcy + "
" +
'开仓均价' + avgTxt + "
" +
'标记价' + markTxt + "
" +
+ 'Delta' +
+ fmtDelta(p.delta != null ? p.delta : p.delta_bs) +
+ "
" +
'指数价' + fmt(p.idx_px, 0) + "
" +
'到期平衡' + fmt(p.expiry_be_px, 0) + "
" +
'平掉回本' + fmt(p.close_be_px, 0) + "
" +
diff --git a/lib/exchange/okx_options_lib.py b/lib/exchange/okx_options_lib.py
index a4389bc..2c18450 100644
--- a/lib/exchange/okx_options_lib.py
+++ b/lib/exchange/okx_options_lib.py
@@ -884,6 +884,10 @@ def build_option_chain(
mark = q["mark_px"]
ask_sz = q["ask_sz"]
bid_sz = q["bid_sz"]
+ # 行情 ticker:delta;兼容个别字段名
+ delta = _safe_float(t.get("delta"))
+ if delta is None:
+ delta = _safe_float(t.get("deltaBS"))
expiry_be = expiry_breakeven_from_ask(
opt_type=opt_type,
strike=strike,
@@ -904,6 +908,7 @@ def build_option_chain(
"ask_sz": ask_sz,
"bid_sz": bid_sz,
"mark_px": mark,
+ "delta": delta,
"ask_estimated": q["ask_estimated"],
"expiry_be_px": expiry_be,
"dist_expiry_be": strike_distance_to_be(strike, expiry_be),
@@ -1843,6 +1848,9 @@ def format_position_row(
round(total_premium(avg, eth_amount), 8) if avg is not None and eth_amount > 0 else None
)
delta_pa = _safe_float(pos.get("deltaPA"))
+ delta_bs = _safe_float(pos.get("deltaBS"))
+ if delta_bs is None:
+ delta_bs = _safe_float(pos.get("delta"))
try:
from lib.options.options_margin_mode_lib import margin_mode_from_inst_id
@@ -1909,6 +1917,10 @@ def format_position_row(
total_premium=premium_paid,
margin_mode=row_mode,
),
+ # 展示用单位 Delta(BS);delta_pa 为仓位美元敏感度
+ "delta": delta_bs,
+ "delta_bs": delta_bs,
+ "delta_pa": delta_pa,
"raw": pos,
}
diff --git a/lib/hub/hub_bridge_register.py b/lib/hub/hub_bridge_register.py
index b113cc2..66b8134 100644
--- a/lib/hub/hub_bridge_register.py
+++ b/lib/hub/hub_bridge_register.py
@@ -135,6 +135,7 @@ def _enrich_hub_protocol(snap: dict[str, Any], *, app_module: Any) -> dict[str,
"premium_paid_usdt": round(float(premium_usdt), 4) if premium_usdt is not None else None,
"premium_ccy": p.get("premium_ccy"),
"contract_leverage": contract_leverage,
+ "delta": p.get("delta") if p.get("delta") is not None else p.get("delta_bs"),
"mark": p.get("mark") or p.get("mark_px"),
"underlying": p.get("underlying"),
"source_label": p.get("source_label"),
diff --git a/lib/instance/templates/embed_shell.html b/lib/instance/templates/embed_shell.html
index a539e18..bfdadd1 100644
--- a/lib/instance/templates/embed_shell.html
+++ b/lib/instance/templates/embed_shell.html
@@ -9,7 +9,7 @@
-
+
diff --git a/lib/instance/templates/index.html b/lib/instance/templates/index.html
index a6c7af6..fd1b8d0 100644
--- a/lib/instance/templates/index.html
+++ b/lib/instance/templates/index.html
@@ -19,7 +19,7 @@
{{ pwa_app_name }}
-
+
合约
卖一/张 |
杠杆 |
+ Delta |
买一/张 |
到期平衡 |
平衡价差 |
@@ -110,7 +111,7 @@
- | 请选择到期日 |
+ | 请选择到期日 |
@@ -368,4 +369,4 @@
-
+
diff --git a/tests/test_options_delta_fields.py b/tests/test_options_delta_fields.py
new file mode 100644
index 0000000..67e59ff
--- /dev/null
+++ b/tests/test_options_delta_fields.py
@@ -0,0 +1,45 @@
+# -*- coding: utf-8 -*-
+import unittest
+
+from lib.exchange.okx_options_lib import format_position_row
+
+
+class OptionsDeltaFieldsTests(unittest.TestCase):
+ def test_format_position_exposes_delta_bs(self):
+ row = format_position_row(
+ {
+ "instId": "ETH-USD-261015-2500-C",
+ "pos": "10",
+ "avgPx": "0.02",
+ "markPx": "0.025",
+ "idxPx": "2600",
+ "optType": "C",
+ "stk": "2500",
+ "deltaBS": "0.6123",
+ "deltaPA": "1.23",
+ },
+ ct_mult=0.1,
+ )
+ self.assertAlmostEqual(row["delta"], 0.6123, places=4)
+ self.assertAlmostEqual(row["delta_bs"], 0.6123, places=4)
+ self.assertAlmostEqual(row["delta_pa"], 1.23, places=4)
+
+ def test_format_position_falls_back_delta_field(self):
+ row = format_position_row(
+ {
+ "instId": "BTC-USD-261015-80000-P",
+ "pos": "1",
+ "avgPx": "0.01",
+ "markPx": "0.012",
+ "idxPx": "82000",
+ "optType": "P",
+ "stk": "80000",
+ "delta": "-0.45",
+ },
+ ct_mult=0.01,
+ )
+ self.assertAlmostEqual(row["delta"], -0.45, places=4)
+
+
+if __name__ == "__main__":
+ unittest.main()