The main dashboard shows the total portfolio summary at the top with aggregate statistics across all services, followed by individual service cards. Each service card displays position counts, cost, value, current P&L, and closed P&L.
Key elements: - Total Portfolio summary with position counts, cost, value, current P&L, and closed P&L - Current P&L Breakdown showing taxable vs non-taxable - Closed P&L Breakdown showing taxable vs non-taxable - Collapsible Closed P&L Chart - Service cards with individual metrics and “Add Service” button
The service detail view shows the trade entry form at the top and position cards below. The toggle switches between Open and Closed positions. Position cards show symbol, spread type, cost, value,
Expanding a service shows all positions grouped by Open and Closed status. Each position shows the symbol, leg count, cost basis, current value/mark, and P&L.
Key elements: - Service summary statistics - Add Trade form with Thinkorswim paste input - Position number selector (existing or new) - Trade date picker - Open/Closed Positions toggle - Position cards in a responsive grid
Clicking a position card expands it to show full details including trade history, mark-to-market section, and action buttons. The taxable
Clicking a position expands it to show individual legs with detailed trade history, add trade functionality, mark-to-market controls, and Schwab account integration.
Key elements: - Close/Delete buttons for position management - Taxable checkbox for tax tracking - Mark-to-Market section with current mark and set mark button - Net Position showing current leg quantities - Individual trade cards with full details (action, legs, strikes, expirations, price)
The closed positions view shows positions that have been closed, with “Days Held” instead of DTE. Expanded positions show the full trade
The Closed section shows positions that have been fully closed out, with realized P&L and tax status tracking.
Key elements: - Closed Positions toggle selected - Position cards showing closed status - Opened/Closed dates displayed - Days Held metric (instead of DTE) - Reopen/Delete buttons for closed positions - Full trade history in expanded view
The settings panel handles Google account authentication and cloud sync. Data can be synced to Google Sheets for backup and cross-device
The Settings dialog provides Google Sheets sync configuration, Schwab integration management, and data import/export functionality.
Key elements: - Google Account sign in/out - Cloud Sync toggle with spreadsheet name and last sync time - Sync Now and Refresh from Cloud buttons - Direct link to open spreadsheet in Google Sheets - Export/Import for local data backup
A "Service" represents a trading advisory or strategy you're following (e.g., "Alpha Picks", "My Strategy"). Each service contains its own portfolio of positions. You can also rename a service by clicking its title, and tag each one with a Trader Effort (High / Medium / Low) so the summary tables can sort or group by how much attention each strategy demands.
Each service card on the main page has a small note icon (next to the trash icon) that opens an editable description for that service. Use it to record what the service trades, its strategy, risk approach, entry/exit rules — anything you want to remember the next time you revisit it. The icon turns blue when a description is set, and hovering shows the text as a tooltip.
The description is persisted everywhere your data goes:
description column on the
services sheet (existing sheets pick the column up on the next sync)The main dashboard top banner shows app-wide totals plus two new at-a-glance tiles:
Below the banner, the Total Portfolio card shows:
Each service is listed below the totals with the same per-service stats, plus a small Trader Effort badge. See the Reports & Analysis section for the expandable charts and cross-service comparison tables.
The easiest way to add trades is to copy the trade string from Thinkorswim:
Every trade string you've ever pasted into a service is kept in a per-service History log accessed from the History button next to the trade input. Useful for re-pasting an earlier fill onto a new position, or for auditing what was actually entered.
When Schwab is connected and you open a new position, the position's notes are pre-filled with
Open/Close VIX X/ SPX Y/ using the live VIX and SPX quotes. When you close the position,
the matching VIX…/ and SPX…/ tokens are auto-completed with the
closing values, so you have a record of regime conditions at both ends of the trade.
closeDate is missing or invalid by setting it to the position's latest trade date.The app parses trade strings in this format:
BUY +2 VERTICAL SPY 100 17 JAN 25 600/605 CALL @2.50
Components:
BUY or SELL - Action+2 - Quantity (positive for buy, negative for sell)VERTICAL - Spread typeSPY - Underlying symbol100 - Multiplier (100 for standard options)17 JAN 25 - Expiration date600/605 - Strike pricesCALL - Option type@2.50 - Price per contractThe dashboard has two collapsible sections under the Total Portfolio card and per-service expansion areas with the same content scoped to one service.
Toggle Closed P&L Chart to expand a chart of realized P&L over time. Controls let you switch between:
The chart shows the trade-average P&L, average days-in-trade (DIT), and trade count for the selected period at the top. The same chart is available on each service detail page, scoped to that service.
Below the Closed P&L Chart toggle is the Service Performance Summary: a sortable table that compares every service for the selected period. Columns include Service, Trader Effort, Win Rate, Won, Avg Win %, Lost, Avg Loss %, Avg DIT, Total Invested, Total P&L, ROI, and Avg Annual ROI. Click any column header to sort. A "Total" row at the bottom pools all services.
Beneath the table you'll see a High Water Mark for cash deployed in open positions line. This is the peak concurrent capital deployment during the period (computed via a sweep-line over each position's open interval), plus the matching ROI and annualized ROI based on total P&L. The same row appears on each service detail page, scoped to that service.
A second collapsible section shows the same table as the Service Performance Summary but folds in every currently open position alongside the closed ones. Open positions contribute their unrealized P&L (mark + trade P&L), days-held = today − openDate, and are bucketed into the win/loss split by the sign of their current P&L. Useful for "where am I right now, not just what's settled" decisions.
Either Service Summary table can be reorganized by Group by Effort. When active, rows are sorted first by Trader Effort (toggleable High→Low / Low→High), and any other column you click becomes a secondary sort within each Effort bucket. Toggle it off to return to plain single-column sorting.
On each service detail page, click Show Strategy Breakdown to see Win Rate, Avg P&L, and Total P&L grouped by spread type (Vertical, Iron Condor, Butterfly, Custom, etc.) for the selected period.
The Day P&L and Week P&L tiles in the top banner are clickable. Each opens a modal that lists every closed position contributing to that total — grouped by service with a per-service subtotal, with columns for Closed date, DIT, Underlying, Type (structure), and P&L. A grand total appears at the bottom.
The Print PDF button on the main page expands the Closed P&L Chart and All Positions Service Summary, then opens the browser print dialog so you can save the entire dashboard to PDF. The print stylesheet hides UI chrome (sort controls, toggles, the app header) and avoids splitting tables across pages.
On each service detail page, the Export Trades button drops a small menu with
Open / Closed / All. Picking one downloads a JSON file (<service>-trades-<scope>-<date>.json)
of just that service's trades — one entry per position with positions, marks, dates, and full
trade history nested. Designed for handing off to Claude (or another AI) for analysis, not for
re-import.
The Position Analyzer is a Black-Scholes scenario tool for any open position. It requires Schwab integration so it can pull a live option chain and per-leg quotes. To open it, click the chart icon next to a position on the service page.
r, and continuous dividend yield q. Changes to
r and per-symbol q are persisted across sessions.
Different broker analytics tools use slightly different inputs. To force the analyzer's per-leg
delta to match what Thinkorswim displays, type the position's ToS delta into the
ToS Δ field next to the summary header and click Calibrate.
The app bisects on r until our computed delta lands on yours, re-implying σ from
each leg's mark at every candidate rate. The new r is persisted so subsequent loads
of any position pick up the calibrated value.
Two top-bar tabs cover non-options activity in your taxable Schwab accounts:
Both pages only show accounts you have explicitly marked Taxable in Settings → Schwab Integration. If no account is marked taxable, both pages surface a yellow "no taxable accounts configured" notice.
You can optionally sync your data to Google Sheets for backup and cross-device access.
Connect your Schwab account to automatically fetch real-time Net Liquidation values for your positions. This helps you track the current market value without manually entering marks.
By default, accounts show as "MARGIN ****1234". In Settings → Schwab Integration you can set per-account properties:
/ (futures options) are auto-flagged when a position is marked
taxable, since they receive 60/40 long/short tax treatment in the US.When Schwab is connected, the live SPX and VIX prices (with today's high / low) appear in the top banner of both the main page and every service page. These same quotes feed the VIX/SPX auto-fill in position notes when you open and close positions.
The app automatically handles these symbol variations:
| Your Position | Schwab Returns | Status |
|---|---|---|
| SPX | $SPX | ✓ Auto-matched |
| SPXW | SPX | ✓ Auto-matched |
| RUTW | RUT | ✓ Auto-matched |
| NDXW / NDXP | NDX | ✓ Auto-matched |
This is a client-side web application - all processing happens in your browser:
┌─────────────────────────────────────────────────────────────────┐
│ YOUR BROWSER │
│ ┌─────────────┐ ┌──────────────┐ ┌────────────┐ │
│ │ React App │ │ localStorage │ │ OAuth │ │
│ │ (all logic) │←→│ (JSON data) │ │ Tokens │ │
│ └─────────────┘ └──────────────┘ └─────┬──────┘ │
└───────────────────────────────────────────┼─────────────────────┘
↑ │
│ static files │ API calls
↓ ↓
┌─────────────┐ ┌───────────────────────┐
│ Vercel │ │ Google Sheets API │
│ (host) │ │ Schwab Trader API │
└─────────────┘ └───────────────────────┘
By default, your data is stored in your browser's localStorage:
When you could lose data:
The Schwab integration is designed with security as a top priority. Here's how it works and why your data is safe.
The app uses OAuth 2.0 with PKCE (Proof Key for Code Exchange), the industry standard for secure authentication:
| Feature | Benefit |
|---|---|
| OAuth 2.0 + PKCE | Your Schwab password is never seen or stored by the app |
| Read-Only Access | The app can only VIEW your positions, never place trades or move money |
| Token Stored Locally | Your access token stays in your browser, not on our servers |
| Serverless Token Exchange | API credentials are kept secure on the server, never exposed to browsers |
| Revocable Access | You can disconnect at any time via Settings or your Schwab account |
| No Data Storage | Position data is fetched on-demand and cached temporarily in your browser only |
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Your Browser │ │ Vercel Server │ │ Schwab API │
│ (Frontend) │ │ (Serverless) │ │ (External) │
└────────┬────────┘ └────────┬────────┘ └────────┬────────┘
│ │ │
│ 1. Click Sign In │ │
│───────────────────────────────────────────────▶│
│ │ Redirect to Schwab │
│ │ │
│ 2. User logs in & approves │
│◀───────────────────────────────────────────────│
│ Redirect with auth code │
│ │ │
│ 3. Send auth code │ │
│───────────────────────▶│ │
│ │ 4. Exchange for tokens │
│ │───────────────────────▶│
│ │◀───────────────────────│
│ 5. Return tokens │ Access + Refresh │
│◀───────────────────────│ │
│ │ │
│ 6. Fetch positions (with token) │
│───────────────────────────────────────────────▶│
│◀───────────────────────────────────────────────│
│ Position data │
Key Point: The Schwab API credentials (Client ID and Secret) are stored securely on the Vercel server as environment variables. They are NEVER sent to or accessible from your browser. The browser only receives temporary access tokens after you authenticate.
Click the version number next to the dashboard title (e.g. v2.26) to open an
in-app changelog showing every release since v1.0 and what shipped in each.
Toggle dark mode from the user menu. The app is fully themed (charts, modals, tables); the choice is saved per browser.
Both the dashboard and each service page have a period selector (Last 30 Days / Current Year / Previous Year / All Time) that drives the Closed P&L number, the Service Performance Summary, and the Closed P&L Chart together. Default is Current Year.
For positions not linked to Schwab (or when you want to override), set a "mark" manually:
Your data is stored locally in your browser. To ensure you don't lose it:
Options Trade Tracker — Help last updated May 2026 (covers v2.28) · Privacy Policy