diff --git a/frontend/strategy.html b/frontend/strategy.html
index 8e36b21..13742a3 100644
--- a/frontend/strategy.html
+++ b/frontend/strategy.html
@@ -87,66 +87,6 @@
-
-
-
@@ -298,12 +301,14 @@
},
// ── derived ───────────────────────────────────────────
- get netCost() { return this.legs.reduce((s,l)=> s + legCost(l), 0); },
- get strategyName() { return detectStrategy(this.legs); },
- get maxDTE() { return Math.max(1, Math.ceil(Math.max(0, ...this.legs.map(legDTE)))); },
+ // only legs with the "Show" checkbox ticked drive the chart / stats / Greeks
+ get activeLegs() { return this.legs.filter(l => l.enabled !== false); },
+ get netCost() { return this.activeLegs.reduce((s,l)=> s + legCost(l), 0); },
+ get strategyName() { return detectStrategy(this.activeLegs); },
+ get maxDTE() { const a = this.activeLegs; return a.length ? Math.max(1, Math.ceil(Math.max(0, ...a.map(legDTE)))) : 1; },
// exact (not floored) days to the earliest expiry — so the "expiration"
// curve uses true intrinsic value (sharp hockey stick), not a near-expiry BS approx
- get minDTE() { return Math.max(0, Math.min(...this.legs.map(legDTE))); },
+ get minDTE() { const a = this.activeLegs; return a.length ? Math.max(0, Math.min(...a.map(legDTE))) : 0; },
get dteLabel() {
const d = new Date(Date.now() + this.dteOffset * DAY_MS);
const ds = d.toISOString().slice(0,10);
@@ -331,7 +336,8 @@
},
get stats() {
- const legs = this.legs, net = this.netCost, spot = this.spot;
+ const legs = this.activeLegs, net = this.netCost, spot = this.spot;
+ if (legs.length === 0) return { maxProfit:'—', maxLoss:'—', breakevens:'—', delta:0, gamma:0, theta:0, vega:0 };
// dense expiration-curve sample for breakevens / extremes / unbounded
const lo0 = 0.01;
const hi0 = Math.max(spot * 2, ...legs.map(l=>l.strike)) * 1.5 + 10;
@@ -386,6 +392,16 @@
StrategyStore.updateLeg(id, patch);
this.reload();
},
+ toggleLeg(id) {
+ const leg = this.legs.find(l => l.id === id);
+ const cur = leg ? leg.enabled !== false : true;
+ StrategyStore.updateLeg(id, { enabled: !cur });
+ // refresh legs without resetting the date slider
+ const st = StrategyStore.load();
+ this.legs = st.legs || [];
+ if (this.dteOffset > this.maxDTE) this.dteOffset = this.maxDTE;
+ this.$nextTick(() => this.renderChart());
+ },
removeLeg(id) {
StrategyStore.removeLeg(id);
this.reload();
@@ -442,8 +458,11 @@
},
renderChart() {
- if (this.legs.length === 0) return;
- const legs = this.legs, net = this.netCost;
+ const legs = this.activeLegs, net = this.netCost;
+ if (legs.length === 0) {
+ if (this.chart) this.chart.updateSeries([{ name: 'P/L', data: [] }, { name: 'P/L', data: [] }]);
+ return;
+ }
const spot = this.spot > 0 ? this.spot : (legs.reduce((s,l)=>s+l.strike,0)/legs.length);
const strikes = legs.map(l=>l.strike);
const minK = Math.min(...strikes), maxK = Math.max(...strikes);