From 50628d1987ce4ed2bb34756b011235edb2117fcb Mon Sep 17 00:00:00 2001 From: heyitsStylez Date: Sun, 20 Sep 2026 17:53:06 +0800 Subject: [PATCH] Wheeler DITM calc: expiry dropdown, fix table overflow, full Position Costs --- src/css/styles.css | 20 +++++++++++--------- src/html/modals.html | 2 +- src/js/tradfi/20-ditm-calc.js | 30 ++++++++++++++++++++++++++++-- 3 files changed, 40 insertions(+), 12 deletions(-) diff --git a/src/css/styles.css b/src/css/styles.css index 024953c..6b85aea 100644 --- a/src/css/styles.css +++ b/src/css/styles.css @@ -356,18 +356,20 @@ tr.lot-child.la-sol:hover > td{background:rgba(153,69,255,.08)} .merge-preview .mp-lbl{color:var(--mu2)}.merge-preview .mp-val{color:var(--text);font-weight:600} /* DITM call calculator */ .dc-inputs{display:grid;grid-template-columns:repeat(4,1fr);gap:12px} -.dc-tiles{display:grid;grid-template-columns:repeat(4,1fr);gap:10px;margin:16px 0} +.dc-tiles{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin:16px 0} +.dc-tiles:empty{display:none} +.dc-costs-hd{grid-column:1/-1;font-size:.62rem;font-weight:700;text-transform:uppercase;letter-spacing:1.2px;color:var(--mu);font-family:var(--mono)} .dc-tile{background:var(--s2);border:1px solid var(--bd2);border-radius:8px;padding:10px 12px} -.dc-tile .k{font-size:.6rem;font-weight:600;text-transform:uppercase;letter-spacing:1px;color:var(--mu);font-family:var(--mono)} +.dc-tile .k{font-size:.58rem;font-weight:600;text-transform:uppercase;letter-spacing:1px;color:var(--mu);font-family:var(--mono)} .dc-tile .v{font-size:1rem;font-weight:700;margin-top:4px;font-family:var(--mono)} -.dc-matrix{width:100%;border-collapse:collapse;font-family:var(--mono);font-size:.74rem} -.dc-matrix th{text-align:right;padding:6px 8px;color:var(--mu);font-weight:600;font-size:.62rem;text-transform:uppercase;letter-spacing:.5px;border-bottom:1px solid var(--bd2)} -.dc-matrix th:first-child{text-align:left} -.dc-matrix td{text-align:right;padding:5px 8px;border-bottom:1px solid var(--bd)} -.dc-matrix td:first-child{text-align:left;font-weight:600} +.dc-matrix{width:100%;table-layout:fixed;border-collapse:collapse;font-family:var(--mono);font-size:.72rem} +.dc-matrix th{text-align:right;padding:5px 6px;color:var(--mu);font-weight:600;font-size:.6rem;text-transform:uppercase;letter-spacing:.4px;border-bottom:1px solid var(--bd2)} +.dc-matrix td{text-align:right;padding:4px 6px;border-bottom:1px solid var(--bd);white-space:nowrap;overflow:hidden;text-overflow:ellipsis} +.dc-matrix th:first-child,.dc-matrix td:first-child{text-align:left;font-weight:600;width:12%} +.dc-matrix th:last-child,.dc-matrix td:last-child{text-align:left;width:24%;white-space:normal} .dc-matrix tr.dc-special td{background:var(--s2)} -.dc-matrix .dc-lbl{color:var(--mu2);font-size:.66rem;text-align:left} -@media(max-width:600px){.dc-inputs,.dc-tiles{grid-template-columns:1fr 1fr}} +.dc-matrix .dc-lbl{color:var(--mu2);font-size:.64rem} +@media(max-width:600px){.dc-inputs{grid-template-columns:1fr 1fr}.dc-tiles{grid-template-columns:1fr 1fr}} .merge-preview .mp-val.green{color:var(--green)}.merge-preview .mp-val.orange{color:var(--orange)} diff --git a/src/html/modals.html b/src/html/modals.html index 3433cb7..809046b 100644 --- a/src/html/modals.html +++ b/src/html/modals.html @@ -39,7 +39,7 @@

DITM Call vs 100 Shares

-
+
diff --git a/src/js/tradfi/20-ditm-calc.js b/src/js/tradfi/20-ditm-calc.js index 1b9cc2c..05e1abf 100644 --- a/src/js/tradfi/20-ditm-calc.js +++ b/src/js/tradfi/20-ditm-calc.js @@ -4,6 +4,8 @@ // ditm_call_tracker.xlsx. Pure scratchpad — nothing is saved to trades. function openDitmCalc() { + const sel = document.getElementById('dc-expiry'); + if (sel && !sel.options.length) sel.innerHTML = ditmExpiryOptions(); document.getElementById('ditm-overlay').classList.add('open'); ditmRecalc(); } @@ -12,6 +14,26 @@ function closeDitmCalc() { document.getElementById('ditm-overlay').classList.remove('open'); } +// Build the expiry dropdown: the standard monthly option expiry (3rd Friday) +// for the next 36 months, so LEAPS-style horizons are one click away. +function ditmExpiryOptions() { + const mon = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; + const now = new Date(); + const out = ['']; + for (let i = 0; i < 36; i++) { + const m = now.getMonth() + i; + const y = now.getFullYear() + Math.floor(m / 12); + const mm = ((m % 12) + 12) % 12; + const firstDow = new Date(y, mm, 1).getDay(); // 0=Sun … 6=Sat + const thirdFri = 1 + ((5 - firstDow + 7) % 7) + 14; // 3rd Friday of month + const d = new Date(y, mm, thirdFri); + if (d <= now) continue; // skip this month if already past + const iso = y + '-' + String(mm + 1).padStart(2, '0') + '-' + String(thirdFri).padStart(2, '0'); + out.push(''); + } + return out.join(''); +} + // Auto-generate a sorted, deduped set of price levels: total loss (0), // current price (stock breakeven), strike, option breakeven, plus a spread // of ± moves around the current price. @@ -55,9 +77,13 @@ function ditmRecalc() { + (color ? ' style="color:' + color + '"' : '') + '>' + v + ''; tiles.innerHTML = - tile('Option Breakeven', '$' + fmt(optBe), 'var(--green)') - + tile('Debit / Max Loss', '−$' + fmt(debit), 'var(--red)') + '
Position Costs
' + tile('Cost of 100 Shares', '$' + fmt(shares100)) + + tile('Cost of 1 Call (Debit)', '$' + fmt(debit)) + + tile('Stock Breakeven', '$' + fmt(price)) + + tile('Option Breakeven', '$' + fmt(optBe), 'var(--green)') + + tile('Max Loss — Stock', '−$' + fmt(shares100), 'var(--red)') + + tile('Max Loss — Call', '−$' + fmt(debit), 'var(--red)') + tile('Days to Expiry', dte == null ? '—' : dte); // Special-level labels keyed by rounded price.