Commit Graph

25 Commits

Author SHA1 Message Date
ojy
2cd3d6ece8 IV Spike Scanner
Backend: GET /api/scan?symbols=SYM1,SYM2,... — for each symbol fetches
the front-expiry options chain plus 30-day realized vol and returns
{ spot, change, changePct, atmIv, hv30, ivHv, spike, expiry }. Spike flag
is on when IV/HV ≥ 1.5 or |today's % change| ≥ 3. Defaults to ~15 popular
tickers when no list is given; cap of 30 symbols/scan.

Frontend: new scanner.html page — symbol input (with "Use defaults" / "Use
watchlist" shortcuts), summary cards (count · spikes · biggest mover ·
highest IV/HV), sortable results table with spike rows highlighted, and
shortcut buttons to open each symbol on Chain or Surface.

Scanner added to all sidebars between Vol Surface and Strategy P/L.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 07:32:14 +00:00
ojy
46574c4f51 Standardize sidebar across all 7 pages
Every page now uses the same brand logo (candle chart icon) and the same
seven nav items in the same order with identical tabler-style icons:
Dashboard · Options Chain · Vol Surface · Strategy P/L · Positions ·
Tracker · Settings. Only the active item differs per page.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 07:17:40 +00:00
ojy
65cb6cc5f2 Tracker watchlist: summary cards + auto-load first symbol
Each watched symbol now appears as a small card showing live spot, ATM IV
(color-coded by level), and RR25 — fetched from /api/analytics. Click a
card to load that symbol's full IV/RR/Fly history charts; the active card
gets a blue border.

On page open: if there's a watchlist but no history loaded yet, auto-open
the first watched symbol so the page isn't empty. Refresh button re-pulls
all watchlist metrics. Empty state hints at adding symbols from the
Strategy page's "Save to Tracker" button.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 07:14:06 +00:00
ojy
d03a90312c Rename Positions row button to "P/L Chart"
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 07:09:53 +00:00
ojy
c4507ec075 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>
2026-05-13 07:08:52 +00:00
ojy
9de7f14573 Split Positions from Tracker; add Settings (commission)
Tracker is for symbol price/IV history, not positions. The "Save to
Tracker" button now adds the symbol to a watchlist (localStorage); the
Tracker page shows the watchlist as clickable chips.

New "Enter Position" button on the Strategy page posts the active legs
to /api/orders, then opens the new Positions page.

New Positions page (positions.html): lists entered positions with live
mid value, round-trip commission, gross & net P/L (Net = Gross − round-
trip commission), per-symbol filter, summary totals, close/reopen and
remove actions.

New Settings page (settings.html) configures the commission used on
Positions. Defaults to Interactive Brokers Fixed / IBKR Lite: $0.65
per contract, $1.00 minimum per order
(https://www.interactivebrokers.com/en/pricing/commissions-options.php).
Per-leg vs per-order toggle for complex orders.

Sidebar nav now: Dashboard · Options Chain · Vol Surface · Strategy P/L
· Positions · Tracker · Settings.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 07:04:52 +00:00
ojy
c1520d7962 Tracked orders — persist strategy positions in SQLite
Backend:
- New orders table (symbol, name, legs_json, entry_cost, created_at,
  closed_at, status, note) sharing the snapshots.db
- Endpoints:
  POST   /api/orders          save a position
  GET    /api/orders?symbol=  list (most recent first)
  GET    /api/orders/:id      single
  PATCH  /api/orders/:id      { status:'open'|'closed', note? }
  DELETE /api/orders/:id      remove

Strategy page:
- "Save to Tracker" button posts the currently-active legs (with name,
  net cost, side, qty, entry, IV, lock) as an order

Tracker page:
- New "Tracked Orders" section above the IV history charts: lists each
  saved position for the current symbol with strategy name, leg summary,
  entered cost, current value, P/L $ and %, opened date, status, and
  Close/Reopen + Remove actions. Live P/L uses /api/chain mids for each
  unique leg expiry.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 06:54:40 +00:00
ojy
58f898b47d Master expiry control — link all legs to one date
The Expiry column header now has a master expiry selector with a 🔓/🔒
toggle. Locking it snaps every leg to the most common expiry, then any
change to the master propagates to all legs (each re-priced from its new
expiry's chain). Per-leg expiry selects are disabled while locked.
Lock resets when switching symbols or clearing.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 06:46:49 +00:00
ojy
0b546ebf41 Show DTE badge in the strategy page title strip
Adds a blue "23 DTE" badge next to the strategy name in the header (or
"14 / 42 DTE" when active legs span multiple expiries — calendar/diagonal).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 05:30:55 +00:00
ojy
283100c453 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>
2026-05-13 05:27:29 +00:00
ojy
dbf7c8e9d2 Editable expiry per leg — fetches the new chain on demand
The Expiry cell is now a dropdown of available expiries for that leg's
symbol (fetched from /api/expirations on page open / symbol switch /
Reload). Picking a different expiry pulls that expiry's chain on-demand
(cached), finds the same strike (or the closest available) for the leg's
type, and updates entry price, IV and mark. Lock clears since it's a new
contract.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 05:13:25 +00:00
ojy
d5d347e0fb Replace drag-pan with ‹ / › buttons in the chart header
Removed click-and-drag panning; the chart header now has ‹ and › buttons
that shift the price window left/right by ~40% of the current half-width
per click. Fit still re-centres and resets zoom.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 05:06:46 +00:00
ojy
03afae3d04 Drag-to-pan the P/L chart price range
Hold the left mouse button on the chart and drag left/right to slide the
underlying-price window; the curve is re-sampled as you drag so it always
extends to the edges. Fit / switching symbols / clear-all re-centre and
reset zoom.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 05:03:49 +00:00
ojy
6ffde10391 Editable strike in legs — re-prices from loaded chain
The Strike cell becomes a dropdown of available strikes (for that leg's
symbol+expiry+type) drawn from the cached chain — seeded from chain.html's
last-loaded chain (localStorage) and refreshed by the strategy page's own
per-expiry chain fetch on open / Reload. Picking a new strike updates the
leg's entry price, IV and mark from that contract and clears the lock.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 05:00:34 +00:00
ojy
957558fc76 Fix unreadable chart annotation labels
Spot / break-even / zero-line labels now use solid high-contrast badges
(dark text on yellow, white text on blue, light text on dark) with padding
and a border instead of transparent/low-contrast backgrounds.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 04:52:47 +00:00
ojy
6ecc69df99 Add price-range zoom controls to the P/L chart
−/+ buttons (with a ±% readout) and a Fit button in the chart header widen
or narrow the underlying-price window the curve is sampled over, so you can
inspect a tight range around spot or zoom out to see the full payoff shape.
Bumped sampling density to 221 points.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 04:49:23 +00:00
ojy
703c305cf1 Multi-symbol strategy baskets + symbol picker
The store now keeps one basket per symbol (v2 schema, auto-migrates v1).
Adding a leg from a different symbol no longer wipes the basket — it creates
that symbol's basket and makes it active. The Strategy page shows a symbol
picker at the top (when >1 symbol is saved) to switch between them; switching
auto-fetches that symbol's live marks. "Clear all" clears only the current
symbol's legs; new StrategyStore.clearAll() wipes everything.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 04:47:16 +00:00
ojy
e0cbd798b6 Auto-fetch live marks on strategy page open
On opening the Strategy page, automatically pull the current spot, each leg's
live mid (Mark column) and IV — without touching entry prices. The Reload
button still re-prices unlocked legs to the current mark. Clarified the legs
table hint.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 04:38:07 +00:00
ojy
5348bf643a Round leg prices to 2 decimals everywhere
Entry price, mark and strike are now rounded to 2dp on add, on edit, on
market reload, and on load (self-heals legacy entries) — fixes display of
float artifacts like "15.000000001". Also persist the leg's locked/currentMark
fields in the store.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 04:28:21 +00:00
ojy
9219220270 Add per-leg entry-price lock + market Reload button
- Each leg has a 🔓/🔒 toggle next to its entry price; locked = entry stays
  fixed (your fill), unlocked = entry re-prices to the current mark on Reload
- New "Mark" column shows each leg's current market mid (with delta vs entry)
- "Refresh spot" button replaced by "Reload": re-fetches spot, plus each leg's
  current mark and IV from the live chain (per unique expiry), re-pricing
  unlocked legs and refreshing IVs used by the T+0 curve
- reload() no longer resets the days-to-expiry slider on edits

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 04:22:59 +00:00
ojy
fb773869b9 Move legs table to bottom; per-leg show/hide in chart
- Legs table now sits below the P/L chart and stats
- Each leg row has a leftmost "Show" checkbox; unchecked legs are excluded
  from the chart, stats, breakevens and net Greeks (and dimmed in the table),
  so you can isolate or build up a strategy incrementally
- All derived values (chart, netCost, maxDTE/minDTE, strategy name, stats)
  now operate on the active (checked) legs only

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 04:17:07 +00:00
ojy
57473ec271 Sharpen P/L extrema & curve at strike kinks
Evaluate the expiration P/L at the exact strike prices (and sample bounds),
not just on the coarse grid — so max profit / max loss are exact for
piecewise payoffs (butterfly peak now $800 not ~$679) and the chart renders
sharp vertices for butterflies, condors, etc.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 04:12:16 +00:00
ojy
2ebc0eeb20 Fix expiration P/L curve in strategy analyzer
- Use exact (not floored) days-to-earliest-expiry so the "Expiration P/L"
  curve uses true intrinsic value — long call/put now show a flat loss floor
  at -premium, a sharp kink at the strike, and the correct breakeven, instead
  of a soft-cornered curve with ~1 day of residual time value
- Clamp the y-axis when one tail is unbounded so the loss floor stays visible
  instead of being squished to a sliver by the runaway profit/loss tail
- Slightly tighter default x-window; denser sampling (161 pts)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 04:07:26 +00:00
ojy
3109df842d Add strategy P/L analyzer + view-state persistence
- New strategy.html: thinkorswim-style P/L diagram (expiration + T+N curves
  via Black-Scholes, days-to-expiry slider, net debit/credit, max profit/loss
  with unbounded detection, breakevens, net Greeks, auto-detected strategy name)
- chain.html: per-row Buy/Sell buttons add legs to a localStorage basket;
  basket badge in toolbar; auto-scroll to ATM row on load
- Persist per-page view state (symbol, expiry, loaded data, charts) across
  navigation via viewstate-store.js for chain/surface/tracker/dashboard
- New assets: blackscholes.js (frontend BS port), strategy-store.js, viewstate-store.js
- Strategy P/L nav link added to all sidebars

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 04:01:57 +00:00
ojy
d08c2230a8 Initial commit — options pricing dashboard
Full-stack options analytics app: IV surface, Greeks, skew metrics,
vol term structure. Yahoo Finance data with Black-Scholes IV computation
and historical vol fallback for after-hours data.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 03:22:23 +00:00