diff --git a/lib/common/static/options_panel.js b/lib/common/static/options_panel.js index 089a09f..0ae34d1 100644 --- a/lib/common/static/options_panel.js +++ b/lib/common/static/options_panel.js @@ -352,7 +352,7 @@ const typeGroup = document.getElementById("opt-type-btn-group"); if (typeGroup) typeGroup.hidden = isT; const expandWrap = document.getElementById("opt-strike-expand-wrap"); - if (expandWrap) expandWrap.hidden = !isT; + if (expandWrap) expandWrap.hidden = false; const headList = document.getElementById("opt-strike-head-list"); const headT = document.getElementById("opt-strike-head-t"); const headTCols = document.getElementById("opt-strike-head-t-cols"); @@ -472,16 +472,59 @@ }); } + // 默认窗口:平值 + 实值 3 档 + 虚值 3 档(T 型按行权价 ATM±3) + const DEFAULT_ATM_SIDE = 3; + function sliceAtmWindow(rows, indexPx) { if (state.strikeExpandAll || !rows.length) return rows; const atmStrike = findAtmStrike(rows, indexPx); const idx = rows.findIndex(function (r) { return Number(r.strike) === Number(atmStrike); }); - if (idx < 0) return rows.slice(0, Math.min(rows.length, 11)); - const start = Math.max(0, idx - 5); - const end = Math.min(rows.length, idx + 6); + const side = DEFAULT_ATM_SIDE; + if (idx < 0) return rows.slice(0, Math.min(rows.length, side * 2 + 1)); + const start = Math.max(0, idx - side); + const end = Math.min(rows.length, idx + side + 1); return rows.slice(start, end); } + function sliceListByMoneyness(list) { + if (state.strikeExpandAll || !list.length) return list; + const sorted = list.slice().sort(function (a, b) { + return Number(a.strike) - Number(b.strike); + }); + const itm = []; + const atm = []; + const otm = []; + sorted.forEach(function (c) { + const m = String(c.moneyness || "").toLowerCase(); + if (m === "atm") atm.push(c); + else if (m === "itm") itm.push(c); + else if (m === "otm") otm.push(c); + }); + if (!atm.length && !itm.length && !otm.length) { + const indexPx = state.chain && state.chain.index_px; + return sliceAtmWindow( + sorted.map(function (c) { return { strike: c.strike, _c: c }; }), + indexPx + ).map(function (r) { return r._c; }); + } + const n = DEFAULT_ATM_SIDE; + const isPut = String(state.optType || "").toUpperCase() === "P"; + // Call: ITM 在下方取靠近 ATM 的末 N;OTM 取前 N。Put 相反。 + const pickedItm = isPut ? itm.slice(0, n) : itm.slice(-n); + const pickedOtm = isPut ? otm.slice(-n) : otm.slice(0, n); + return pickedItm.concat(atm, pickedOtm).sort(function (a, b) { + return Number(a.strike) - Number(b.strike); + }); + } + + function strikeWindowHintHtml(cols) { + return ( + '