CoolFace
Apppublic

Nagaraj81/OptionsTradingRecoEngine

sourceHugging Facemitupdated 7mo agoView on Hugging Face
0likes
index.html782 linesDownload Raw Back to root
1<!DOCTYPE html>2<html lang="en">3<head>4<meta charset="UTF-8"/>5<meta name="viewport" content="width=device-width, initial-scale=1.0"/>6<title>Options Intelligence — MSFT · BMNR · IREN · CRCL</title>7<link href="https://fonts.googleapis.com/css2?family=Inter:ital,wght@0,300;0,400;0,500;0,600;0,700;1,400&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet"/>8<style>9:root{10  --bg:#F7F8FA;--surface:#fff;--surface2:#F0F2F7;11  --border:#E2E5EE;--border2:#C8CCDB;12  --t1:#0D0F1A;--t2:#3D4460;--t3:#8B92AA;13  --blue:#1A56DB;--blue-l:#EBF1FF;--blue-d:#1341B0;14  --green:#0A7A45;--green-l:#E8F8F0;--green-m:#D1F0E0;15  --red:#CC2828;--red-l:#FFF0F0;--red-m:#FFD8D8;16  --amber:#B45309;--amber-l:#FFF8ED;--amber-m:#FDECC8;17  --purple:#6326C7;--purple-l:#F3EEFF;18  --sh:0 1px 3px rgba(0,0,0,.06),0 1px 2px rgba(0,0,0,.04);19  --sh2:0 4px 16px rgba(0,0,0,.09),0 2px 6px rgba(0,0,0,.05);20  --r:10px;21}22*{box-sizing:border-box;margin:0;padding:0}23body{font-family:'Inter',sans-serif;background:var(--bg);color:var(--t1);-webkit-font-smoothing:antialiased;min-height:100vh}24a{color:var(--blue);text-decoration:none}a:hover{text-decoration:underline}25button,input{font-family:inherit;cursor:pointer}26textarea:focus,input:focus{outline:none}27::-webkit-scrollbar{width:5px}::-webkit-scrollbar-track{background:var(--bg)}28::-webkit-scrollbar-thumb{background:var(--border2);border-radius:3px}29 30/* ── HEADER ── */31.hdr{background:var(--surface);border-bottom:1px solid var(--border);padding:0 28px;position:sticky;top:0;z-index:100;box-shadow:var(--sh)}32.hdr-in{max-width:1280px;margin:0 auto;display:flex;align-items:center;justify-content:space-between;height:58px}33.logo{display:flex;align-items:center;gap:10px}34.logo-mark{width:34px;height:34px;background:linear-gradient(135deg,#1A56DB,#6326C7);border-radius:9px;display:flex;align-items:center;justify-content:center;font-size:17px;box-shadow:0 2px 8px rgba(26,86,219,.3)}35.logo-title{font-size:16px;font-weight:700;letter-spacing:-.4px}36.logo-sub{font-size:11px;color:var(--t3);margin-top:1px}37.hdr-right{display:flex;align-items:center;gap:12px}38.hdr-time{font-size:11px;color:var(--t3)}39.hdr-vix{font-size:12px;font-weight:600;padding:4px 10px;border-radius:6px;background:var(--surface2);border:1px solid var(--border);display:none}40.btn-refresh{display:flex;align-items:center;gap:6px;padding:8px 18px;background:var(--blue);color:#fff;border:none;border-radius:8px;font-size:13px;font-weight:600;letter-spacing:-.1px;transition:all .15s}41.btn-refresh:hover:not(:disabled){background:var(--blue-d);transform:translateY(-1px);box-shadow:0 3px 10px rgba(26,86,219,.35)}42.btn-refresh:disabled{background:var(--border2);color:var(--t3);cursor:not-allowed;transform:none;box-shadow:none}43@keyframes spin{to{transform:rotate(360deg)}}44.spin{animation:spin .8s linear infinite}45@keyframes fadeUp{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}46 47/* ── GATE ── */48#gate{min-height:calc(100vh - 58px);display:flex;align-items:center;justify-content:center;padding:32px 16px}49.gate-card{background:var(--surface);border:1px solid var(--border);border-radius:16px;padding:40px;max-width:460px;width:100%;box-shadow:var(--sh2)}50.gate-logo{width:52px;height:52px;background:linear-gradient(135deg,#1A56DB,#6326C7);border-radius:14px;display:flex;align-items:center;justify-content:center;font-size:26px;margin:0 auto 20px;box-shadow:0 4px 12px rgba(26,86,219,.3)}51.gate-h{font-size:21px;font-weight:700;text-align:center;margin-bottom:8px;letter-spacing:-.4px}52.gate-p{font-size:13px;color:var(--t2);text-align:center;line-height:1.65;margin-bottom:28px}53.gate-lbl{font-size:12px;font-weight:600;color:var(--t2);margin-bottom:6px}54.gate-inp{width:100%;padding:11px 14px;border:1.5px solid var(--border);border-radius:8px;font-size:13px;font-family:'JetBrains Mono',monospace;color:var(--t1);background:var(--bg);transition:border-color .15s;margin-bottom:6px}55.gate-inp:focus{border-color:var(--blue);background:#fff}56.gate-hint{font-size:11px;color:var(--t3);line-height:1.6;margin-bottom:20px}57.gate-err{font-size:12px;color:var(--red);margin-bottom:10px;display:none}58.btn-start{width:100%;padding:12px;background:var(--blue);color:#fff;border:none;border-radius:8px;font-size:14px;font-weight:700;transition:all .15s}59.btn-start:hover{background:var(--blue-d)}60.feat-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:8px;margin-top:24px}61.feat{padding:11px 14px;background:var(--bg);border-radius:8px;border:1px solid var(--border);font-size:11px;color:var(--t2);display:flex;align-items:flex-start;gap:8px;line-height:1.4}62.feat-ic{font-size:15px;flex-shrink:0}63 64/* ── PAGE ── */65.page{max-width:1280px;margin:0 auto;padding:24px 28px 48px}66 67/* ── SUMMARY STRIP ── */68.summary-strip{background:var(--surface);border:1px solid var(--border);border-radius:var(--r);padding:0;margin-bottom:24px;overflow:hidden;box-shadow:var(--sh)}69.summary-hdr{padding:12px 20px;background:var(--surface2);border-bottom:1px solid var(--border);display:flex;align-items:center;justify-content:space-between}70.summary-hdr-title{font-size:12px;font-weight:700;letter-spacing:.8px;text-transform:uppercase;color:var(--t3)}71.summary-table{width:100%;border-collapse:collapse}72.summary-table th{padding:10px 16px;font-size:10px;font-weight:700;letter-spacing:.7px;text-transform:uppercase;color:var(--t3);text-align:left;border-bottom:1px solid var(--border);background:var(--surface)}73.summary-table td{padding:13px 16px;font-size:13px;border-bottom:1px solid var(--border);vertical-align:middle}74.summary-table tr:last-child td{border-bottom:none}75.summary-table tr:hover td{background:#FAFBFF}76.sticker{font-size:14px;font-weight:800;letter-spacing:-.3px}77.sprice{font-family:'JetBrains Mono',monospace;font-size:13px;font-weight:500}78.schg{font-size:11px;font-weight:600;padding:2px 7px;border-radius:4px;font-family:'JetBrains Mono',monospace;margin-left:6px}79.up{background:var(--green-m);color:var(--green)}.dn{background:var(--red-m);color:var(--red)}.fl{background:var(--surface2);color:var(--t3)}80.strategy-pill{display:inline-flex;align-items:center;padding:4px 10px;border-radius:6px;font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.3px;white-space:nowrap}81.conf-badge{font-size:10px;font-weight:700;padding:2px 7px;border-radius:4px;text-transform:uppercase;letter-spacing:.3px}82.conf-high{background:var(--green-m);color:var(--green)}83.conf-med{background:var(--amber-m);color:var(--amber)}84.conf-low{background:var(--surface2);color:var(--t3)}85.mono{font-family:'JetBrains Mono',monospace;font-size:12px}86.summary-loading td{color:var(--t3);font-style:italic;font-size:12px}87 88/* ── TICKER CARDS ── */89.cards-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:20px}90@media(max-width:900px){.cards-grid{grid-template-columns:1fr}}91 92.tcard{background:var(--surface);border:1px solid var(--border);border-radius:var(--r);overflow:hidden;box-shadow:var(--sh);animation:fadeUp .35s ease both}93.tcard:hover{box-shadow:var(--sh2)}94 95.tcard-hdr{padding:16px 20px;border-bottom:1px solid var(--border);display:flex;align-items:flex-start;justify-content:space-between;gap:12px}96.tcard-ticker{font-size:20px;font-weight:800;letter-spacing:-.5px}97.tcard-name{font-size:11px;color:var(--t3);margin-top:2px}98.tcard-price{text-align:right;flex-shrink:0}99.price-big{font-size:20px;font-weight:700;font-family:'JetBrains Mono',monospace}100.price-chg{font-size:11px;font-weight:600;padding:2px 8px;border-radius:5px;margin-top:4px;display:inline-block;font-family:'JetBrains Mono',monospace}101 102/* stats row */103.stats-band{display:grid;grid-template-columns:repeat(4,1fr);border-bottom:1px solid var(--border)}104.sc{padding:11px 14px;border-right:1px solid var(--border)}105.sc:last-child{border-right:none}106.sc-l{font-size:10px;font-weight:600;letter-spacing:.7px;text-transform:uppercase;color:var(--t3);margin-bottom:4px}107.sc-v{font-size:14px;font-weight:700;font-family:'JetBrains Mono',monospace}108.sc-s{font-size:10px;color:var(--t3);margin-top:2px}109 110/* IV bar */111.iv-bar-wrap{padding:13px 20px;border-bottom:1px solid var(--border)}112.iv-bar-row{display:flex;align-items:center;justify-content:space-between;margin-bottom:7px}113.iv-bar-lbl{font-size:11px;font-weight:600;color:var(--t2)}114.iv-regime-tag{font-size:10px;font-weight:700;padding:2px 9px;border-radius:10px;text-transform:uppercase;letter-spacing:.4px}115.rt-sell{background:var(--red-l);color:var(--red)}116.rt-buy{background:var(--green-l);color:var(--green)}117.rt-neutral{background:var(--amber-l);color:var(--amber)}118.iv-track{height:6px;background:var(--surface2);border-radius:3px;overflow:hidden;border:1px solid var(--border)}119.iv-fill{height:100%;border-radius:3px;transition:width .8s ease}120 121/* news pill */122.news-row{padding:9px 20px;border-bottom:1px solid var(--border);display:flex;align-items:flex-start;gap:8px;background:#FAFBFE}123.news-tag{font-size:10px;font-weight:700;padding:2px 7px;border-radius:4px;background:var(--blue-l);color:var(--blue);flex-shrink:0;margin-top:1px;text-transform:uppercase;letter-spacing:.3px}124.news-text{font-size:11px;color:var(--t2);line-height:1.55;flex:1}125.news-src{font-size:10px;color:var(--t3);margin-top:2px}126 127/* recommendation block */128.rec-block{padding:18px 20px;border-bottom:1px solid var(--border)}129.rec-block-title{font-size:10px;font-weight:700;letter-spacing:1px;text-transform:uppercase;color:var(--t3);margin-bottom:12px}130 131.rec-banner{border-radius:9px;padding:14px;margin-bottom:14px;border:1.5px solid}132.rec-top-row{display:flex;align-items:flex-start;justify-content:space-between;gap:10px;margin-bottom:10px}133.rec-strat-name{font-size:15px;font-weight:800;letter-spacing:-.3px}134.rec-dir{font-size:11px;color:var(--t2);margin-top:2px}135.rec-conf{text-align:right;flex-shrink:0}136.rec-strike-row{display:flex;flex-wrap:wrap;gap:10px}137.rec-chip{display:flex;flex-direction:column;padding:7px 12px;border-radius:6px;background:rgba(255,255,255,.7);border:1px solid rgba(0,0,0,.06)}138.rec-chip-l{font-size:9px;font-weight:700;letter-spacing:.6px;text-transform:uppercase;color:var(--t3);margin-bottom:3px}139.rec-chip-v{font-size:13px;font-weight:700;font-family:'JetBrains Mono',monospace}140 141/* P&L row */142.pnl-row{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin-bottom:12px}143.pnl-box{padding:9px 11px;border-radius:7px;border:1px solid var(--border);background:var(--bg)}144.pnl-l{font-size:9px;font-weight:700;letter-spacing:.5px;text-transform:uppercase;color:var(--t3);margin-bottom:3px}145.pnl-v{font-size:12px;font-weight:700;font-family:'JetBrains Mono',monospace}146 147/* greeks row */148.greeks-row{display:grid;grid-template-columns:repeat(4,1fr);gap:6px;margin-bottom:14px}149.greek-box{padding:8px 10px;background:var(--surface2);border-radius:6px;text-align:center}150.greek-sym{font-size:14px;font-weight:700;color:var(--t2);margin-bottom:2px}151.greek-val{font-size:11px;font-family:'JetBrains Mono',monospace;color:var(--t1);font-weight:500}152.greek-lbl{font-size:9px;color:var(--t3);margin-top:1px}153 154/* plain english */155.plain-block{padding:16px 20px;border-bottom:1px solid var(--border);background:#FAFCFF}156.plain-title{font-size:10px;font-weight:700;letter-spacing:1px;text-transform:uppercase;color:var(--blue);margin-bottom:8px;display:flex;align-items:center;gap:5px}157.plain-text{font-size:13px;line-height:1.75;color:var(--t2)}158.plain-text strong{color:var(--t1);font-weight:600}159 160/* risk + pass */161.risk-block{padding:12px 20px;border-bottom:1px solid var(--border);background:#FFFBF5}162.risk-tag{font-size:10px;font-weight:700;letter-spacing:.5px;text-transform:uppercase;color:var(--amber);margin-bottom:5px}163.risk-text{font-size:12px;line-height:1.65;color:#78350F}164 165.pass-block{padding:12px 20px;border-bottom:1px solid var(--border)}166.pass-tag{font-size:10px;font-weight:700;letter-spacing:.5px;text-transform:uppercase;color:var(--t3);margin-bottom:5px}167.pass-text{font-size:12px;line-height:1.65;color:var(--t2)}168 169/* alt trade */170.alt-block{padding:12px 20px;border-bottom:1px solid var(--border)}171.alt-tag{font-size:10px;font-weight:700;letter-spacing:.5px;text-transform:uppercase;color:var(--t3);margin-bottom:6px}172.alt-inner{display:flex;align-items:flex-start;gap:10px;padding:10px 12px;background:var(--bg);border-radius:7px;border:1px solid var(--border)}173.alt-text{font-size:12px;line-height:1.6;color:var(--t2)}174 175/* scores */176.scores-block{padding:14px 20px}177.scores-title{font-size:10px;font-weight:700;letter-spacing:.8px;text-transform:uppercase;color:var(--t3);margin-bottom:10px}178.score-row{display:flex;align-items:center;gap:8px;margin-bottom:5px}179.score-nm{font-size:11px;color:var(--t2);min-width:130px}180.score-tr{flex:1;height:5px;background:var(--surface2);border-radius:3px;overflow:hidden}181.score-fi{height:100%;border-radius:3px;transition:width 1s ease}182.score-n{font-size:11px;font-weight:700;min-width:26px;text-align:right;font-family:'JetBrains Mono',monospace}183 184/* loading state */185.card-loading{padding:32px 20px;display:flex;flex-direction:column;align-items:center;gap:10px}186.ld-spinner{width:28px;height:28px;border:2.5px solid var(--border);border-top-color:var(--blue);border-radius:50%;animation:spin .7s linear infinite}187.ld-text{font-size:13px;color:var(--t3)}188.ld-steps{font-size:11px;color:var(--border2);text-align:center;line-height:1.8}189 190/* error state */191.card-err{padding:28px 20px;text-align:center}192.card-err-ico{font-size:30px;margin-bottom:8px}193.card-err-msg{font-size:13px;color:var(--t2);line-height:1.6;margin-bottom:14px}194.btn-retry{padding:7px 16px;border:1px solid var(--border);border-radius:6px;background:var(--bg);color:var(--blue);font-size:12px;font-weight:600;cursor:pointer;font-family:inherit;transition:background .15s}195.btn-retry:hover{background:var(--blue-l)}196 197/* strategy color classes */198.s-sp{background:var(--purple-l);border-color:#C4B5FD}.b-sp{background:var(--purple-l);color:var(--purple)}199.s-sc{background:var(--amber-l);border-color:#FCD34D}.b-sc{background:var(--amber-l);color:var(--amber)}200.s-bc{background:var(--green-l);border-color:#6EE7B7}.b-bc{background:var(--green-l);color:var(--green)}201.s-bp{background:var(--red-l);border-color:#FCA5A5}.b-bp{background:var(--red-l);color:var(--red)}202.s-st{background:var(--blue-l);border-color:#93C5FD}.b-st{background:var(--blue-l);color:var(--blue)}203.s-sg{background:var(--blue-l);border-color:#BFDBFE}.b-sg{background:var(--blue-l);color:var(--blue)}204.s-ic{background:#F0FDF4;border-color:#86EFAC}.b-ic{background:#F0FDF4;color:#16A34A}205.s-bs{background:var(--green-l);border-color:#6EE7B7}.b-bs{background:var(--green-l);color:var(--green)}206.s-ps{background:var(--red-l);border-color:#FCA5A5}.b-ps{background:var(--red-l);color:var(--red)}207.s-df{background:var(--bg);border-color:var(--border)}.b-df{background:var(--bg);color:var(--t2)}208 209footer{padding:20px 28px;text-align:center;font-size:11px;color:var(--t3);border-top:1px solid var(--border);line-height:1.8;background:var(--surface)}210@media(max-width:700px){.page{padding:14px}.stats-band{grid-template-columns:repeat(2,1fr)}.pnl-row{grid-template-columns:repeat(2,1fr)}.greeks-row{grid-template-columns:repeat(2,1fr)}.hdr{padding:0 14px}}211</style>212</head>213<body>214 215<!-- HEADER -->216<header class="hdr">217  <div class="hdr-in">218    <div class="logo">219      <div class="logo-mark">📈</div>220      <div>221        <div class="logo-title">Options Intelligence</div>222        <div class="logo-sub">MSFT · BMNR · IREN · CRCL — Live AI Recommendations</div>223      </div>224    </div>225    <div class="hdr-right">226      <span class="hdr-vix" id="hdr-vix"></span>227      <span class="hdr-time" id="hdr-time"></span>228      <button class="btn-refresh" id="btn-refresh" onclick="refreshAll()" disabled>229        <svg id="ref-icon" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M3 12a9 9 0 019-9 9.75 9.75 0 016.74 2.74L21 8"/><path d="M21 3v5h-5"/><path d="M21 12a9 9 0 01-9 9 9.75 9.75 0 01-6.74-2.74L3 16"/><path d="M3 21v-5h5"/></svg>230        Refresh231      </button>232    </div>233  </div>234</header>235 236<!-- GATE -->237<div id="gate">238  <div class="gate-card">239    <div class="gate-logo">📊</div>240    <div class="gate-h">Options Intelligence Dashboard</div>241    <div class="gate-p">Live AI-powered options recommendations for <strong>MSFT, BMNR, IREN, CRCL</strong>. Each refresh searches live market data and generates a fresh trade recommendation with plain English explanations.</div>242    <div class="gate-lbl">Anthropic API Key</div>243    <input type="password" id="gate-key" class="gate-inp" placeholder="sk-ant-api03-…"/>244    <div class="gate-hint">Your key stays in your browser only — never stored anywhere. Get one free at <a href="https://console.anthropic.com" target="_blank">console.anthropic.com</a>. Cost per refresh: ~$0.08–0.12.</div>245    <div class="gate-err" id="gate-err"></div>246    <button class="btn-start" onclick="startApp()">Launch Dashboard →</button>247    <div class="feat-grid">248      <div class="feat"><div class="feat-ic">🔍</div><div>Live web search for current prices, IV and news on every refresh</div></div>249      <div class="feat"><div class="feat-ic">📰</div><div>News sources shown — know where the information came from</div></div>250      <div class="feat"><div class="feat-ic">💬</div><div>Plain English explanation of every recommendation</div></div>251      <div class="feat"><div class="feat-ic">🎯</div><div>Exact strike, expiry, entry price and breakevens</div></div>252      <div class="feat"><div class="feat-ic">⚡</div><div>Greeks: Delta, Gamma, Theta, Vega for every trade</div></div>253      <div class="feat"><div class="feat-ic">⚠️</div><div>Risk scenario and "skip if" conditions per ticker</div></div>254    </div>255  </div>256</div>257 258<!-- APP -->259<div id="app" style="display:none">260<div class="page">261 262  <!-- Summary strip -->263  <div class="summary-strip">264    <div class="summary-hdr">265      <span class="summary-hdr-title">📋 At-a-Glance Summary — What to trade today</span>266      <span style="font-size:11px;color:var(--t3)" id="summary-ts"></span>267    </div>268    <table class="summary-table" id="summary-tbl">269      <thead>270        <tr>271          <th>Ticker</th>272          <th>Price</th>273          <th>Strategy</th>274          <th>Strike</th>275          <th>Expiry / DTE</th>276          <th>Entry (Mid)</th>277          <th>Max Profit</th>278          <th>Max Loss</th>279          <th>Confidence</th>280        </tr>281      </thead>282      <tbody id="summary-body">283        <tr class="summary-loading">284          <td colspan="9" style="padding:18px 16px;color:var(--t3);font-style:italic;font-size:12px">⏳ Loading live data…</td>285        </tr>286      </tbody>287    </table>288  </div>289 290  <!-- Ticker cards -->291  <div class="cards-grid" id="cards-grid"></div>292 293</div>294<footer>295  Options Intelligence · Powered by Claude AI + Live Web Search<br/>296  <strong>⚠ Not financial advice.</strong> Options trading involves substantial risk of loss. Always verify recommendations independently before placing any trade.297</footer>298</div>299 300<script>301'use strict';302 303// ── CONFIG ──────────────────────────────────────────────────304const TICKERS = [305  {sym:'MSFT', name:'Microsoft Corporation'},306  {sym:'BMNR', name:'BitMine Immersion Technologies'},307  {sym:'IREN', name:'Iris Energy'},308  {sym:'CRCL', name:'Circle Internet Financial'},309];310 311// Strategy type → CSS class key312const TYPE_MAP = {313  sell_put:'sp', sell_call:'sc', buy_call:'bc', buy_put:'bp',314  straddle:'st', strangle:'sg', condor:'ic',315  bull_spread:'bs', bear_spread:'ps',316};317 318let API_KEY  = '';319let running  = false;320let results  = {};   // sym → parsed data321 322// ── GATE ─────────────────────────────────────────────────────323document.getElementById('gate-key').addEventListener('keydown', e => { if(e.key==='Enter') startApp(); });324 325function startApp(){326  const k   = document.getElementById('gate-key').value.trim();327  const err = document.getElementById('gate-err');328  if(!k.startsWith('sk-ant-')){ err.textContent='⚠ Key must start with sk-ant-'; err.style.display='block'; return; }329  err.style.display='none';330  API_KEY = k;331  document.getElementById('gate').style.display='none';332  document.getElementById('app').style.display='block';333  document.getElementById('btn-refresh').disabled=false;334  initCards();335  refreshAll();336}337 338// ── INIT CARDS ────────────────────────────────────────────────339function initCards(){340  const grid = document.getElementById('cards-grid');341  grid.innerHTML='';342  TICKERS.forEach((t,i)=>{343    const d=document.createElement('div');344    d.className='tcard';345    d.id='card-'+t.sym;346    d.style.animationDelay=(i*0.08)+'s';347    d.innerHTML=loadingHTML(t);348    grid.appendChild(d);349  });350}351 352function loadingHTML(t){353  return `<div class="tcard-hdr"><div><div class="tcard-ticker">${t.sym}</div><div class="tcard-name">${t.name}</div></div></div>354<div class="card-loading"><div class="ld-spinner"></div><div class="ld-text">Searching live data…</div>355<div class="ld-steps">Fetching price &amp; options chain<br>Calculating IV Rank &amp; Greeks<br>Generating AI recommendation</div></div>`;356}357 358// ── REFRESH ALL ───────────────────────────────────────────────359async function refreshAll(){360  if(running) return;361  running=true;362  results={};363  const btn=document.getElementById('btn-refresh');364  const ico=document.getElementById('ref-icon');365  btn.disabled=true; ico.classList.add('spin');366  document.getElementById('summary-body').innerHTML=367    '<tr><td colspan="9" style="padding:18px 16px;color:var(--t3);font-style:italic;font-size:12px">⏳ Loading…</td></tr>';368 369  // Reset cards370  TICKERS.forEach(t=>{ document.getElementById('card-'+t.sym).innerHTML=loadingHTML(t); });371 372  // Run all in parallel373  await Promise.allSettled(TICKERS.map(t=>fetchAndRender(t)));374 375  // Rebuild summary after all done376  buildSummary();377 378  const now=new Date();379  const ts=now.toLocaleTimeString('en-US',{hour:'2-digit',minute:'2-digit'});380  document.getElementById('hdr-time').textContent='Updated '+ts;381  document.getElementById('summary-ts').textContent='Last updated '+ts;382 383  ico.classList.remove('spin');384  btn.disabled=false;385  running=false;386}387 388// ── FETCH + RENDER ONE TICKER ─────────────────────────────────389async function fetchAndRender(ticker){390  try{391    const d=await callClaude(ticker);392    results[ticker.sym]=d;393    renderCard(ticker,d);394  }catch(e){395    renderError(ticker,e.message);396  }397}398 399// ── CLAUDE API ────────────────────────────────────────────────400async function callClaude(ticker){401  const today=new Date().toISOString().split('T')[0];402  const dow=new Date().toLocaleDateString('en-US',{weekday:'long'});403 404  const resp=await fetch('https://api.anthropic.com/v1/messages',{405    method:'POST',406    headers:{407      'Content-Type':'application/json',408      'x-api-key':API_KEY,409      'anthropic-version':'2023-06-01',410      'anthropic-dangerous-direct-browser-access':'true',411    },412    body:JSON.stringify({413      model:'claude-sonnet-4-20250514',414      max_tokens:1800,415      tools:[{type:'web_search_20250305',name:'web_search'}],416      system:`You are a senior options trader and quantitative analyst. Today is ${dow} ${today}.417Your job: Search for LIVE current data on the given stock ticker, then produce a precise options recommendation as JSON.418RULES:4191. Always search the web first — never use stale training data for prices or IV4202. Search for: current stock price, today's % change, options IV, recent news/catalysts, upcoming earnings, current VIX4213. After gathering data, return ONLY valid JSON matching the exact schema. No markdown fences, no prose outside the JSON.4224. Include the actual source name (e.g. "Reuters", "Yahoo Finance", "Bloomberg") for any news cited.`,423      messages:[{role:'user',content:buildPrompt(ticker,today)}],424    }),425  });426 427  if(!resp.ok){428    const e=await resp.json().catch(()=>({}));429    throw new Error((e.error&&e.error.message)||'API error '+resp.status);430  }431 432  const data=await resp.json();433  // Extract text blocks (web search tool may produce mixed content blocks)434  const text=(data.content||[]).filter(b=>b.type==='text').map(b=>b.text).join('');435 436  // Robust JSON extraction437  let js=text;438  const fm=js.match(/```(?:json)?\s*([\s\S]*?)```/);439  if(fm) js=fm[1];440  const a=js.indexOf('{'), b=js.lastIndexOf('}');441  if(a!==-1&&b!==-1) js=js.slice(a,b+1);442 443  try{ return JSON.parse(js); }444  catch(e){ throw new Error('Could not parse AI response — try refreshing.'); }445}446 447// ── PROMPT ────────────────────────────────────────────────────448function buildPrompt(ticker,today){449  return `Analyse ticker: ${ticker.sym} (${ticker.name}). Today: ${today}.450 451STEP 1 — Search the web for:452• Current price and today's % change for ${ticker.sym}453• Current implied volatility (IV) and options chain activity454• Most recent news or catalyst (past 7 days) — note the SOURCE455• Next earnings date for ${ticker.sym}456• Current VIX level and US 3-month T-bill yield457 458STEP 2 — Respond with ONLY this exact JSON (no other text):459 460{461  "ticker": "${ticker.sym}",462  "company": "${ticker.name}",463  "price": <number>,464  "price_change_pct": <number e.g. 1.23>,465  "price_trend": "<BULLISH|BEARISH|NEUTRAL>",466  "vix": <number>,467  "risk_free_rate": <number e.g. 4.8>,468  "iv_estimate": <number e.g. 42.0>,469  "iv_rank": <number 0-100>,470  "iv_regime": "<HIGH_SELL_PREMIUM|LOW_BUY_OPTIONS|NEUTRAL>",471  "hv_30d": <number>,472  "rsi_estimate": <number>,473  "sma20": <number>,474  "sma50": <number>,475  "earnings_date": "<YYYY-MM-DD or Unknown>",476  "days_to_earnings": <number or null>,477  "has_liquid_options": <true|false>,478  "options_note": "<one line on liquidity>",479  "news_headline": "<most important recent news headline in one sentence>",480  "news_source": "<source name e.g. Reuters, Yahoo Finance, Bloomberg, SEC filing>",481  "news_date": "<YYYY-MM-DD or approximate>",482  "news_impact": "<BULLISH|BEARISH|NEUTRAL — how this news affects the options strategy>",483  "data_quality": "<LIVE|ESTIMATED>",484 485  "top_strategy": {486    "name": "<Sell Put|Sell Covered Call|Buy Call|Buy Put|Buy Straddle|Buy Strangle|Iron Condor|Bull Call Spread|Bear Put Spread>",487    "type_class": "<sell_put|sell_call|buy_call|buy_put|straddle|strangle|condor|bull_spread|bear_spread>",488    "direction": "<Bullish|Bearish|Neutral|Non-Directional>",489    "confidence": "<HIGH|MEDIUM|LOW>",490    "strike": "<e.g. $415>",491    "expiry": "<e.g. Apr 17 2025>",492    "dte": "<e.g. 42 DTE>",493    "entry_mid": "<e.g. $3.20>",494    "max_profit": "<e.g. $320 per contract>",495    "max_loss": "<e.g. $680 per contract>",496    "breakeven": "<e.g. $411.80 or Up: $420 / Down: $400>",497    "delta": "<e.g. -0.28>",498    "gamma": "<e.g. 0.012>",499    "theta": "<e.g. -$0.09/day>",500    "vega": "<e.g. $0.18 per 1pt IV>",501    "technical_rationale": "<2-3 sentences: the professional analysis using IV rank, trend, Greeks, VIX>",502    "plain_english": "<3-4 sentences in simple language explaining what this trade is, why it makes sense right now, and what outcome you are expecting. Avoid jargon. Write as if explaining to a smart friend who does not trade options.>",503    "risk_scenario": "<one specific event that immediately kills this trade>",504    "pass_if": "<two specific conditions under which you skip this trade today>"505  },506 507  "alternative_strategy": {508    "name": "<strategy name>",509    "type_class": "<type class>",510    "direction": "<direction>",511    "strike": "<strike>",512    "expiry": "<expiry>",513    "entry_mid": "<mid price>",514    "rationale": "<2 sentences: why this is the second best option>"515  },516 517  "strategy_scores": [518    {"name":"Sell Put","score":<0-100>},519    {"name":"Sell Call","score":<0-100>},520    {"name":"Buy Call","score":<0-100>},521    {"name":"Buy Put","score":<0-100>},522    {"name":"Buy Straddle","score":<0-100>},523    {"name":"Iron Condor","score":<0-100>},524    {"name":"Bull Spread","score":<0-100>},525    {"name":"Bear Spread","score":<0-100>}526  ]527}528 529If ${ticker.sym} has no liquid options (very small cap / newly listed), set has_liquid_options:false and adjust top_strategy to an equity-level recommendation. Always include your news source.`;530}531 532// ── BUILD SUMMARY TABLE ───────────────────────────────────────533function buildSummary(){534  const tbody=document.getElementById('summary-body');535  if(!Object.keys(results).length){ tbody.innerHTML='<tr><td colspan="9" style="padding:16px;color:var(--t3);font-size:12px">No results yet.</td></tr>'; return; }536  tbody.innerHTML='';537  TICKERS.forEach(t=>{538    const d=results[t.sym];539    if(!d){540      const tr=document.createElement('tr');541      tr.innerHTML=`<td class="sticker">${t.sym}</td><td colspan="8" style="color:var(--t3);font-size:12px;font-style:italic">Failed to load</td>`;542      tbody.appendChild(tr);543      return;544    }545    const ts=d.top_strategy||{};546    const tc=TYPE_MAP[ts.type_class]||'df';547    const chgSign=d.price_change_pct>=0?'+':'';548    const chgCls=d.price_change_pct>0?'up':d.price_change_pct<0?'dn':'fl';549    const confCls=ts.confidence==='HIGH'?'conf-high':ts.confidence==='MEDIUM'?'conf-med':'conf-low';550    const tr=document.createElement('tr');551    tr.innerHTML=`552      <td><span class="sticker">${t.sym}</span><br><span style="font-size:10px;color:var(--t3)">${t.name}</span></td>553      <td><span class="sprice">$${fmt(d.price)}</span><span class="schg ${chgCls}">${chgSign}${fmt(d.price_change_pct)}%</span></td>554      <td><span class="strategy-pill b-${tc}">${ts.name||'—'}</span></td>555      <td><span class="mono">${ts.strike||'—'}</span></td>556      <td><span class="mono" style="font-size:11px">${ts.expiry||'—'}<br><span style="color:var(--t3)">${ts.dte||''}</span></span></td>557      <td><span class="mono">${ts.entry_mid||'—'}</span></td>558      <td style="color:var(--green);font-weight:600;font-size:12px">${ts.max_profit||'—'}</td>559      <td style="color:var(--red);font-weight:600;font-size:12px">${ts.max_loss||'—'}</td>560      <td><span class="conf-badge ${confCls}">${ts.confidence||'—'}</span></td>`;561    tbody.appendChild(tr);562  });563}564 565// ── RENDER CARD ───────────────────────────────────────────────566function renderCard(ticker,d){567  const card=document.getElementById('card-'+ticker.sym);568  if(!card) return;569 570  // Update VIX in header once571  if(d.vix && document.getElementById('hdr-vix').style.display==='none'||!document.getElementById('hdr-vix').textContent){572    const vixEl=document.getElementById('hdr-vix');573    vixEl.textContent=`VIX ${fmt(d.vix)}`;574    vixEl.style.display='block';575  }576 577  const ts=d.top_strategy||{};578  const alt=d.alternative_strategy||{};579  const tc=TYPE_MAP[ts.type_class]||'df';580  const altc=TYPE_MAP[alt.type_class]||'df';581  const chgSign=d.price_change_pct>=0?'+':'';582  const chgCls=d.price_change_pct>0?'up':d.price_change_pct<0?'dn':'fl';583  const ivFill=Math.min(100,d.iv_rank||0);584  const ivColor=d.iv_rank>60?'var(--red)':d.iv_rank<35?'var(--green)':'var(--amber)';585  const regClass=d.iv_regime==='HIGH_SELL_PREMIUM'?'rt-sell':d.iv_regime==='LOW_BUY_OPTIONS'?'rt-buy':'rt-neutral';586  const regLabel=d.iv_regime==='HIGH_SELL_PREMIUM'?'Sell Premium ↑':d.iv_regime==='LOW_BUY_OPTIONS'?'Buy Options ↓':'Neutral IV';587  const trendColor=d.price_trend==='BULLISH'?'var(--green)':d.price_trend==='BEARISH'?'var(--red)':'var(--amber)';588  const dq=d.data_quality||'';589  const dqPill=dq.includes('LIVE')?590    `<span style="font-size:10px;padding:2px 7px;border-radius:4px;background:var(--green-m);color:var(--green);font-weight:700">● LIVE</span>`:591    `<span style="font-size:10px;padding:2px 7px;border-radius:4px;background:var(--amber-m);color:var(--amber);font-weight:700">◐ EST</span>`;592  const confCls=ts.confidence==='HIGH'?'conf-high':ts.confidence==='MEDIUM'?'conf-med':'conf-low';593  const scores=(d.strategy_scores||[]).sort((a,b)=>b.score-a.score);594  const newsImpactColor=d.news_impact==='BULLISH'?'var(--green)':d.news_impact==='BEARISH'?'var(--red)':'var(--t3)';595 596  card.innerHTML=`597  <!-- Header -->598  <div class="tcard-hdr">599    <div>600      <div class="tcard-ticker">${d.ticker} ${dqPill}</div>601      <div class="tcard-name">${d.company}</div>602    </div>603    <div class="tcard-price">604      <div class="price-big">$${fmt(d.price)}</div>605      <div class="price-chg ${chgCls}">${chgSign}${fmt(d.price_change_pct)}%</div>606    </div>607  </div>608 609  <!-- Stats -->610  <div class="stats-band">611    <div class="sc">612      <div class="sc-l">Trend</div>613      <div class="sc-v" style="color:${trendColor}">${d.price_trend||'—'}</div>614      <div class="sc-s">RSI ${fmt(d.rsi_estimate,0)}</div>615    </div>616    <div class="sc">617      <div class="sc-l">ATM IV</div>618      <div class="sc-v">${fmt(d.iv_estimate)}%</div>619      <div class="sc-s">HV30 ${fmt(d.hv_30d)}%</div>620    </div>621    <div class="sc">622      <div class="sc-l">Earnings</div>623      <div class="sc-v" style="font-size:12px">${d.earnings_date&&d.earnings_date!=='Unknown'?d.earnings_date:'—'}</div>624      <div class="sc-s">${d.days_to_earnings?d.days_to_earnings+'d away':''}</div>625    </div>626    <div class="sc">627      <div class="sc-l">Options</div>628      <div class="sc-v" style="font-size:12px;color:${d.has_liquid_options?'var(--green)':'var(--red)'}">629        ${d.has_liquid_options?'✓ Liquid':'✗ Thin'}630      </div>631      <div class="sc-s" style="font-size:9px">${(d.options_note||'').substring(0,28)}</div>632    </div>633  </div>634 635  <!-- IV Rank -->636  <div class="iv-bar-wrap">637    <div class="iv-bar-row">638      <span class="iv-bar-lbl">IV Rank: <strong>${fmt(d.iv_rank,0)}</strong> / 100</span>639      <span class="iv-regime-tag ${regClass}">${regLabel}</span>640    </div>641    <div class="iv-track"><div class="iv-fill" style="width:${ivFill}%;background:${ivColor}"></div></div>642  </div>643 644  <!-- News -->645  ${d.news_headline?`<div class="news-row">646    <span class="news-tag" style="color:${newsImpactColor}">News</span>647    <div>648      <div class="news-text">${esc(d.news_headline)}</div>649      <div class="news-src">📰 Source: <strong>${esc(d.news_source||'Unknown')}</strong>${d.news_date?' · '+d.news_date:''} · Impact: <span style="color:${newsImpactColor};font-weight:600">${d.news_impact||'—'}</span></div>650    </div>651  </div>`:''}652 653  <!-- Recommendation Banner -->654  <div class="rec-block">655    <div class="rec-block-title">⭐ Top Recommendation</div>656 657    <div class="rec-banner s-${tc}">658      <div class="rec-top-row">659        <div>660          <div class="rec-strat-name">${ts.name||'—'}</div>661          <div class="rec-dir">${ts.direction||''}</div>662        </div>663        <div class="rec-conf">664          <span class="conf-badge ${confCls}">${ts.confidence||'—'}</span>665          <div style="font-size:9px;color:var(--t3);margin-top:4px;text-align:right">confidence</div>666        </div>667      </div>668      <div class="rec-strike-row">669        <div class="rec-chip">670          <span class="rec-chip-l">Strike</span>671          <span class="rec-chip-v">${ts.strike||'—'}</span>672        </div>673        <div class="rec-chip">674          <span class="rec-chip-l">Expiry</span>675          <span class="rec-chip-v" style="font-size:11px">${ts.expiry||'—'}</span>676        </div>677        <div class="rec-chip">678          <span class="rec-chip-l">DTE</span>679          <span class="rec-chip-v">${ts.dte||'—'}</span>680        </div>681        <div class="rec-chip">682          <span class="rec-chip-l">Entry Mid</span>683          <span class="rec-chip-v">${ts.entry_mid||'—'}</span>684        </div>685      </div>686    </div>687 688    <!-- P&L -->689    <div class="pnl-row">690      <div class="pnl-box"><div class="pnl-l">Max Profit</div><div class="pnl-v" style="color:var(--green)">${ts.max_profit||'—'}</div></div>691      <div class="pnl-box"><div class="pnl-l">Max Loss</div><div class="pnl-v" style="color:var(--red)">${ts.max_loss||'—'}</div></div>692      <div class="pnl-box"><div class="pnl-l">Breakeven</div><div class="pnl-v" style="font-size:11px">${ts.breakeven||'—'}</div></div>693    </div>694 695    <!-- Greeks -->696    <div class="greeks-row">697      <div class="greek-box"><div class="greek-sym">Δ</div><div class="greek-val">${ts.delta||'—'}</div><div class="greek-lbl">Delta</div></div>698      <div class="greek-box"><div class="greek-sym">Γ</div><div class="greek-val">${ts.gamma||'—'}</div><div class="greek-lbl">Gamma</div></div>699      <div class="greek-box"><div class="greek-sym">θ</div><div class="greek-val">${ts.theta||'—'}</div><div class="greek-lbl">Theta/day</div></div>700      <div class="greek-box"><div class="greek-sym">ν</div><div class="greek-val">${ts.vega||'—'}</div><div class="greek-lbl">Vega/pt</div></div>701    </div>702 703    <!-- Professional rationale -->704    ${ts.technical_rationale?`<div style="font-size:12px;line-height:1.7;color:var(--t2);margin-bottom:0">${esc(ts.technical_rationale)}</div>`:''}705  </div>706 707  <!-- Plain English -->708  ${ts.plain_english?`<div class="plain-block">709    <div class="plain-title">💬 In Plain English</div>710    <div class="plain-text">${esc(ts.plain_english)}</div>711  </div>`:''}712 713  <!-- Risk -->714  ${ts.risk_scenario?`<div class="risk-block">715    <div class="risk-tag">⚠ Key Risk</div>716    <div class="risk-text">${esc(ts.risk_scenario)}</div>717  </div>`:''}718 719  <!-- Pass if -->720  ${ts.pass_if?`<div class="pass-block">721    <div class="pass-tag">🚫 Skip this trade if…</div>722    <div class="pass-text">${esc(ts.pass_if)}</div>723  </div>`:''}724 725  <!-- Alternative -->726  ${alt.name?`<div class="alt-block">727    <div class="alt-tag">🔀 Alternative Trade</div>728    <div class="alt-inner">729      <span class="strategy-pill b-${altc}" style="font-size:10px;flex-shrink:0">${alt.name}</span>730      <div class="alt-text"><strong>${alt.strike||''} ${alt.expiry||''}</strong> · Mid ${alt.entry_mid||'—'}<br>${esc(alt.rationale||'')}</div>731    </div>732  </div>`:''}733 734  <!-- Strategy Scores -->735  <div class="scores-block">736    <div class="scores-title">All Strategy Scores</div>737    ${scores.map(s=>{738      const sc=s.score||0;739      const col=sc>=70?'var(--green)':sc>=50?'var(--blue)':sc>=35?'var(--amber)':'var(--border2)';740      return `<div class="score-row">741        <span class="score-nm">${s.name}</span>742        <div class="score-tr"><div class="score-fi" style="width:${sc}%;background:${col}"></div></div>743        <span class="score-n" style="color:${col}">${sc}</span>744      </div>`;745    }).join('')}746  </div>`;747}748 749// ── RENDER ERROR ──────────────────────────────────────────────750function renderError(ticker,msg){751  const card=document.getElementById('card-'+ticker.sym);752  if(!card) return;753  card.innerHTML=`754    <div class="tcard-hdr"><div><div class="tcard-ticker">${ticker.sym}</div><div class="tcard-name">${ticker.name}</div></div></div>755    <div class="card-err">756      <div class="card-err-ico">⚠️</div>757      <div class="card-err-msg">${esc(msg)}</div>758      <button class="btn-retry" onclick="retryOne('${ticker.sym}')">↩ Retry ${ticker.sym}</button>759    </div>`;760}761 762async function retryOne(sym){763  const t=TICKERS.find(x=>x.sym===sym);764  if(!t) return;765  document.getElementById('card-'+sym).innerHTML=loadingHTML(t);766  await fetchAndRender(t);767  buildSummary();768}769 770// ── HELPERS ───────────────────────────────────────────────────771function fmt(n,dec=2){772  if(n===null||n===undefined||n==='') return '—';773  const x=parseFloat(n);774  return isNaN(x)?String(n):x.toFixed(dec);775}776function esc(s){777  return (s||'').replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;');778}779</script>780</body>781</html>782