feat: reorder cards (payoff below positions), booked=totalRealised, payoff respects expiry tab
This commit is contained in:
parent
a1945d06e2
commit
ef459facfc
1 changed files with 32 additions and 32 deletions
|
|
@ -156,7 +156,7 @@
|
|||
</nav>
|
||||
<div class="g3">
|
||||
<div class="card pcard pu"><div class="plbl">Unrealised P&L</div><div class="pval fl" id="v-u">—</div><div class="psub">Open positions MTM</div></div>
|
||||
<div class="card pcard pr"><div class="plbl">Realised P&L</div><div class="pval fl" id="v-r">—</div><div class="psub">Booked today (netqty=0)</div></div>
|
||||
<div class="card pcard pr"><div class="plbl">Realised P&L</div><div class="pval fl" id="v-r">—</div><div class="psub">Partial + full exits today</div></div>
|
||||
<div class="card pcard pt"><div class="plbl">Total P&L</div><div class="pval fl" id="v-t">—</div><div class="psub">Unrealised + Realised</div></div>
|
||||
</div>
|
||||
<div class="g6" id="market-grid">
|
||||
|
|
@ -196,8 +196,33 @@
|
|||
<tfoot id="pos-foot" style="display:none"><tr><td colspan="4">Portfolio Total</td><td id="f-u" class="mono">—</td><td id="f-r" class="mono">—</td><td id="f-t" class="mono">—</td></tr></tfoot>
|
||||
</table></div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="card collapsible" id="sec-payoff" style="margin-bottom:16px">
|
||||
<div class="card-head" onclick="toggleCard('sec-payoff')">
|
||||
<span class="card-title">Strategy Payoff at Expiry</span>
|
||||
<div style="display:flex;align-items:center;gap:8px">
|
||||
<span id="pf-ul" style="font-size:.7rem;font-weight:600;color:var(--text2);font-family:Geist Mono,monospace"></span>
|
||||
<span id="pf-strat" style="font-size:.68rem;padding:2px 8px;border-radius:9999px;background:var(--bg3);border:1px solid var(--border2);color:var(--text2)"></span>
|
||||
</div>
|
||||
<span class="collapse-arrow">▼</span>
|
||||
</div>
|
||||
<div class="collapse-body">
|
||||
<div style="display:grid;grid-template-columns:repeat(6,1fr);border-bottom:1px solid var(--border)">
|
||||
<div class="pf-stat"><div class="pfs-l">NET PREMIUM</div><div class="pfs-v" id="pf-prem">—</div></div>
|
||||
<div class="pf-stat"><div class="pfs-l">MAX PROFIT</div><div class="pfs-v up" id="pf-maxp">—</div></div>
|
||||
<div class="pf-stat"><div class="pfs-l">MAX LOSS</div><div class="pfs-v dn" id="pf-maxl">—</div></div>
|
||||
<div class="pf-stat"><div class="pfs-l">REWARD/RISK</div><div class="pfs-v" id="pf-rr">—</div></div>
|
||||
<div class="pf-stat"><div class="pfs-l">BREAKEVEN(S)</div><div class="pfs-v" id="pf-be" style="font-size:.8rem">—</div></div>
|
||||
<div class="pf-stat"><div class="pfs-l">DTE</div><div class="pfs-v" id="pf-dte">—</div></div>
|
||||
</div>
|
||||
<div style="padding:14px 16px 10px;height:250px;position:relative">
|
||||
<canvas id="payoff-chart"></canvas>
|
||||
<div id="pf-empty" style="display:none;position:absolute;inset:0;align-items:center;justify-content:center;color:var(--text3);font-size:.8rem;flex-direction:column;gap:6px">
|
||||
<span style="font-size:1.4rem">📈</span><span>No option positions to analyse</span>
|
||||
</div>
|
||||
</div>
|
||||
<div style="padding:0 16px 10px;font-size:.63rem;color:var(--text3)">Theoretical payoff at expiry based on avg cost. Does not account for time value or IV. Current spot shown as vertical line.</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card collapsible" id="sec-closed" style="margin-bottom:16px">
|
||||
<div class="card-head" onclick="toggleCard('sec-closed')">
|
||||
<span class="card-title">Closed / Booked Positions</span>
|
||||
|
|
@ -234,33 +259,6 @@
|
|||
<div id="closed-stale" style="display:none;padding:10px 18px;font-size:.7rem;color:var(--amber);border-top:1px solid var(--border)"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card collapsible" id="sec-payoff" style="margin-bottom:16px">
|
||||
<div class="card-head" onclick="toggleCard('sec-payoff')">
|
||||
<span class="card-title">Strategy Payoff at Expiry</span>
|
||||
<div style="display:flex;align-items:center;gap:8px">
|
||||
<span id="pf-ul" style="font-size:.7rem;font-weight:600;color:var(--text2);font-family:Geist Mono,monospace"></span>
|
||||
<span id="pf-strat" style="font-size:.68rem;padding:2px 8px;border-radius:9999px;background:var(--bg3);border:1px solid var(--border2);color:var(--text2)"></span>
|
||||
</div>
|
||||
<span class="collapse-arrow">▼</span>
|
||||
</div>
|
||||
<div class="collapse-body">
|
||||
<div style="display:grid;grid-template-columns:repeat(6,1fr);border-bottom:1px solid var(--border)">
|
||||
<div class="pf-stat"><div class="pfs-l">NET PREMIUM</div><div class="pfs-v" id="pf-prem">—</div></div>
|
||||
<div class="pf-stat"><div class="pfs-l">MAX PROFIT</div><div class="pfs-v up" id="pf-maxp">—</div></div>
|
||||
<div class="pf-stat"><div class="pfs-l">MAX LOSS</div><div class="pfs-v dn" id="pf-maxl">—</div></div>
|
||||
<div class="pf-stat"><div class="pfs-l">REWARD/RISK</div><div class="pfs-v" id="pf-rr">—</div></div>
|
||||
<div class="pf-stat"><div class="pfs-l">BREAKEVEN(S)</div><div class="pfs-v" id="pf-be" style="font-size:.8rem">—</div></div>
|
||||
<div class="pf-stat"><div class="pfs-l">DTE</div><div class="pfs-v" id="pf-dte">—</div></div>
|
||||
</div>
|
||||
<div style="padding:14px 16px 10px;height:250px;position:relative">
|
||||
<canvas id="payoff-chart"></canvas>
|
||||
<div id="pf-empty" style="display:none;position:absolute;inset:0;align-items:center;justify-content:center;color:var(--text3);font-size:.8rem;flex-direction:column;gap:6px">
|
||||
<span style="font-size:1.4rem">📈</span><span>No option positions to analyse</span>
|
||||
</div>
|
||||
</div>
|
||||
<div style="padding:0 16px 10px;font-size:.63rem;color:var(--text3)">Theoretical payoff at expiry based on avg cost. Does not account for time value or IV. Current spot shown as vertical line.</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card collapsible" id="sec-alrt" style="margin-bottom:16px">
|
||||
<div class="card-head" onclick="toggleCard('sec-alrt')"><span class="card-title">Alert History</span><div style="display:flex;align-items:center;gap:8px"><span id="alrt-hcount" style="font-size:.7rem;font-weight:600;padding:2px 9px;border-radius:9999px;background:rgba(245,166,35,.15);color:var(--amber);display:none"></span><span id="alrt-hmuted" style="font-size:.7rem;font-weight:600;padding:2px 9px;border-radius:9999px;background:rgba(231,76,60,.12);color:var(--red);display:none">MUTED</span></div><span class="collapse-arrow">▼</span></div>
|
||||
<div class="collapse-body"><table>
|
||||
|
|
@ -307,7 +305,7 @@ async function loadChart(h=8){
|
|||
curH=h;['b2','b8','b24','b72'].forEach(id=>document.getElementById(id)?.classList.remove('on'));
|
||||
document.getElementById({2:'b2',8:'b8',24:'b24',72:'b72'}[h])?.classList.add('on');
|
||||
const {summary,history}=await fetch('/api/pnl-history?hours='+h).then(r=>r.json());
|
||||
if(summary){const set=(id,v)=>{const e=document.getElementById(id);e.textContent=fmt(v);e.className='pval '+cls(v)};set('v-u',summary.totalUnrealised);set('v-r',summary.bookedPnl||0);set('v-t',summary.totalPnl);document.getElementById('s-pos').textContent=summary.openPositions;var bEl=document.getElementById('s-booked');if(bEl){bEl.textContent=fmt(summary.bookedPnl||0);bEl.className='sval '+cls(summary.bookedPnl||0);}var bEl=document.getElementById('s-booked');if(bEl){bEl.textContent=fmt(summary.bookedPnl||0);bEl.className='sval '+cls(summary.bookedPnl||0);}}
|
||||
if(summary){const set=(id,v)=>{const e=document.getElementById(id);e.textContent=fmt(v);e.className='pval '+cls(v)};set('v-u',summary.totalUnrealised);set('v-r',summary.totalRealised||0);set('v-t',summary.totalPnl);document.getElementById('s-pos').textContent=summary.openPositions;var bEl=document.getElementById('s-booked');if(bEl){bEl.textContent=fmt(summary.totalRealised||0);bEl.className='sval '+cls(summary.totalRealised||0);}var bEl=document.getElementById('s-booked');if(bEl){bEl.textContent=fmt(summary.bookedPnl||0);bEl.className='sval '+cls(summary.bookedPnl||0);}}
|
||||
const canvas=document.getElementById('pnl-chart'),empty=document.getElementById('chart-empty');
|
||||
if(!history||history.length<2){canvas.style.display='none';empty.classList.add('show');return;}
|
||||
canvas.style.display='block';empty.classList.remove('show');
|
||||
|
|
@ -566,7 +564,8 @@ async function loadPayoff() {
|
|||
var mktRes = await fetch('/api/market').then(function(r){return r.json();}).catch(function(){return {data:[]};});
|
||||
|
||||
var open = (posRes.data || []).filter(function(p){return p.is_closed===0;});
|
||||
var opts = open.filter(function(p){return /CE|PE/.test(p.tradingsymbol);}).map(function(p){
|
||||
var expFiltered=(_activeExpiry&&_activeExpiry!=='ALL')?open.filter(function(p){return expiryLabel(p.tradingsymbol)===_activeExpiry;}):open;
|
||||
var opts = expFiltered.filter(function(p){return /CE|PE/.test(p.tradingsymbol);}).map(function(p){
|
||||
p._parsed = parseOptionSym(p.tradingsymbol);
|
||||
return p;
|
||||
}).filter(function(p){return p._parsed !== null;});
|
||||
|
|
@ -760,6 +759,7 @@ function setExpiry(btn,exp){
|
|||
if(row) row.querySelectorAll('.exp-tab').forEach(function(b){b.classList.remove('active');});
|
||||
if(btn) btn.classList.add('active');
|
||||
loadPositions();
|
||||
loadPayoff();
|
||||
}
|
||||
loadConfig();refresh();
|
||||
setInterval(refresh,60000);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue