Positions: "Open" button loads the position into the Strategy page

Each row has a new Open button that copies the order's legs (locked, since
they're real fills) into the StrategyStore basket for that symbol — wiping
only that symbol's basket (with a confirm if it already has legs) — and
navigates to strategy.html so you can analyze, roll or adjust the position.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
ojy
2026-05-13 07:08:52 +00:00
parent 9de7f14573
commit c4507ec075

View File

@@ -114,7 +114,7 @@
<th class="text-end">P/L %</th>
<th>Opened</th>
<th>Status</th>
<th></th><th></th>
<th></th><th></th><th></th>
</tr>
</thead>
<tbody>
@@ -131,6 +131,7 @@
<td class="text-end mono small" :class="row.netPL >= 0 ? 'text-success' : 'text-danger'" x-text="row.plPct.toFixed(1) + '%'"></td>
<td class="small text-secondary mono" x-text="(row.o.created_at||'').slice(0,10)"></td>
<td><span class="badge" :class="row.o.status === 'open' ? 'bg-success-lt text-success' : 'bg-secondary-lt text-secondary'" x-text="row.o.status"></span></td>
<td><button class="btn btn-sm btn-outline-primary" @click="openInStrategy(row.o)" title="Load this position into the Strategy page for analysis">Open</button></td>
<td><button class="btn btn-sm" :class="row.o.status === 'open' ? 'btn-outline-warning' : 'btn-outline-success'" @click="toggleClose(row.o)" x-text="row.o.status === 'open' ? 'Close' : 'Reopen'"></button></td>
<td><button class="btn btn-sm btn-ghost-danger" @click="remove(row.o.id)" aria-label="Remove position"></button></td>
</tr>
@@ -152,6 +153,7 @@
<script src="/assets/tabler.min.js" defer></script>
<script src="/assets/settings-store.js"></script>
<script src="/assets/strategy-store.js"></script>
<script src="/assets/alpine.min.js" defer></script>
<script>
@@ -284,6 +286,35 @@
} catch {}
},
// Load this order's legs into the Strategy basket (replacing any existing
// legs for the same symbol), then open the Strategy page.
openInStrategy(o) {
const sym = o.symbol;
let existingLegs = 0;
try {
const doc = JSON.parse(localStorage.getItem('optionsPricer:strategy') || '{}');
existingLegs = doc?.baskets?.[sym]?.legs?.length || 0;
} catch {}
if (existingLegs > 0 && !confirm(`Replace your current ${sym} strategy (${existingLegs} leg${existingLegs===1?'':'s'}) with order #${o.id}?`)) return;
const legs = (o.legs || []).map(l => ({
id: 'id-' + Date.now() + '-' + Math.random().toString(36).slice(2),
symbol: l.symbol,
expiry: l.expiry,
type: l.type,
strike: Number(l.strike),
side: l.side === 'short' ? 'short' : 'long',
qty: Math.max(1, Math.round(Number(l.qty) || 1)),
entryPrice: Number(l.entryPrice) || 0,
iv: Number(l.iv) || 0,
locked: true, // it's an entered position — lock the entry prices
currentMark: null,
}));
StrategyStore.save({ symbol: sym, spotSnapshot: 0, legs });
StrategyStore.setActive(sym);
this.flash('Loaded into Strategy — opening…');
setTimeout(() => { window.location.href = '/strategy.html'; }, 400);
},
flash(msg) { this.toast = msg; setTimeout(() => { this.toast = ''; }, 2500); },
fmtMoney(v) {