Show DTE per leg + per-expiry remaining DTE for multi-expiry strategies
- Legs table: small DTE chip next to each leg's expiry (e.g. "14d", "<1d", "exp" — absolute days from today) - Chart header: when active legs span multiple expiries (calendar/diagonal), a "Remaining: 2026-05-15 (0d) · 2026-06-20 (36d)" line shows how many days each unique expiry has left at the current slider position Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -109,11 +109,12 @@
|
||||
<button class="btn btn-outline-secondary" @click="zoomFit()" title="Reset pan & zoom">Fit</button>
|
||||
</div>
|
||||
<!-- time slider -->
|
||||
<div class="d-flex align-items-center gap-2" style="min-width:300px;">
|
||||
<div class="d-flex align-items-center flex-wrap gap-2" style="min-width:300px;">
|
||||
<span class="text-secondary small text-nowrap">Now</span>
|
||||
<input type="range" class="form-range" min="0" :max="maxDTE" step="1" x-model.number="dteOffset" @input="scheduleRender()" style="min-width:150px;">
|
||||
<span class="text-secondary small text-nowrap">Exp</span>
|
||||
<span class="badge bg-blue-lt text-nowrap" x-text="dteLabel"></span>
|
||||
<small class="text-secondary w-100" x-show="hasMultiExpiry" x-text="'Remaining: ' + expiryBreakdown"></small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -173,11 +174,14 @@
|
||||
</select>
|
||||
<span x-show="!hasStrikeOpts(lv)" x-text="lv.strike"></span>
|
||||
</td>
|
||||
<td class="mono small" style="width:8.5rem">
|
||||
<td class="mono small" style="width:11rem">
|
||||
<div class="d-flex align-items-center gap-1 flex-nowrap">
|
||||
<select x-show="hasExpiryOpts(lv)" class="form-select form-select-sm" :value="lv.expiry" @change="changeExpiry(lv.id, $event.target.value)" title="Change expiry — strike, entry, IV & mark update from the new chain">
|
||||
<template x-for="e in expiryOpts(lv)" :key="e"><option :value="e" x-text="e"></option></template>
|
||||
</select>
|
||||
<span x-show="!hasExpiryOpts(lv)" x-text="lv.expiry"></span>
|
||||
<span class="badge bg-secondary-lt text-secondary" :title="'Days to expiry from today'" x-text="legDTEStr(lv)"></span>
|
||||
</div>
|
||||
</td>
|
||||
<td style="width:8.5rem">
|
||||
<div class="input-group input-group-sm flex-nowrap">
|
||||
@@ -493,6 +497,22 @@
|
||||
if (this.dteOffset === 0) return 'Today (' + ds + ')';
|
||||
return 'T+' + this.dteOffset + 'd · ' + ds;
|
||||
},
|
||||
get hasMultiExpiry() {
|
||||
return new Set(this.activeLegs.map(l => l.expiry)).size > 1;
|
||||
},
|
||||
get expiryBreakdown() {
|
||||
const uniq = [...new Set(this.activeLegs.map(l => l.expiry))].sort();
|
||||
return uniq.map(e => {
|
||||
const rem = Math.max(0, Math.round(legDTE({expiry:e}) - this.dteOffset));
|
||||
return e + ' (' + rem + 'd)';
|
||||
}).join(' · ');
|
||||
},
|
||||
legDTEStr(lv) {
|
||||
const d = legDTE(lv);
|
||||
if (d < 0) return 'exp';
|
||||
if (d < 1) return '<1d';
|
||||
return Math.round(d) + 'd';
|
||||
},
|
||||
|
||||
get legsView() {
|
||||
return this.legs.map(l => {
|
||||
|
||||
Reference in New Issue
Block a user