What I Want
Wire my actual portfolio into Mira's dashboard. My positions live in a local OpenBB Workspace portfolio app at http://localhost:9078. Mira already has the analysis framework (portfolio construction review, position review, thesis cross-referencing) but the private/portfolio/ directory is empty. I want:
- A pipeline that pulls my holdings from the OpenBB endpoint into Mira's private state
- Thesis-to-position cross-referencing (which holdings have Mira cases already?)
- A "Portfolio" view in the Mira Case Cockpit dashboard showing holdings, exposure, concentration warnings, and coverage gaps
Context — The Data
Portfolio widget server at :9078: Schwab (8 positions, ~$29.6K) + Fidelity (20 positions, ~$27.7K) = 28 positions, ~$57.3K total.
Endpoints:
/schwab/positions, /fidelity/positions — symbol, description, units, price, market_value, open_pnl, avg_cost, day_change, 52w range, sector
/schwab/summary, /fidelity/summary — total value, P&L, position count
/schwab/sectors, /fidelity/sectors — dollar/pct allocation by sector
/schwab/beta, /fidelity/beta — per-position beta + portfolio beta
Mira case overlap: Only 2 of 28 positions have cases:
EOSE → cases/eose-2026-05/ (Fidelity: $1,287, +$982 P&L, thesis active)
LB → referenced in cases/royalty-king-four-pillars-2026-07/ (Fidelity: $4,252, +$1,282 P&L)
26 positions have no thesis coverage — these become the natural queue for future Mira research.
Notable concentration: CLM is 46% of the Schwab sleeve ($13,687). EVVTY is 21% of Fidelity ($5,844).
Context — What Mira Already Has
- ✅ Portfolio construction review loop (
loops/portfolio-construction-review-loop.md) — exposure map, concentration, duplicate bets, thesis conflicts, stale positions
- ✅ Portfolio review loop (
loops/portfolio-review-loop.md) — PM-facing multi-thesis review
- ✅ Position review loop (
loops/position-review-loop.md)
- ✅ Portfolio templates (
templates/portfolio-system/) — CSV templates for register, exposure review, construction review
- ✅ Dashboard intake actions — "Review a position" and "Review portfolio construction" already in
dashboard/choices.json
- ❌
private/portfolio/ — doesn't exist (no holdings, weights, or registers)
- ❌
private/views/view-register.csv — only 1 entry ("AI adopters")
- ❌ No portfolio view in the dashboard (board + cockpit + intake are the 3 current views)
Plan
Phase 1 — Ingest script (scripts/pull_portfolio.py)
- Reads
:9078 endpoints into Mira's private state
- Outputs under
private/portfolio/:
holdings.csv — all 28 positions with Mira-compatible fields (ticker, account, units, price, market_value, open_pnl, avg_cost, sector, date_pulled)
summary.json — per-account totals
sectors.csv — sector allocation
register.csv — Mira portfolio-register template populated
- Idempotent (safe to re-run; overwrites previous snapshot)
- Stdlib-only Python, same convention as existing
dashboard/build_data.py
Phase 2 — Cross-reference with Mira cases
build_data.py extended to read private/portfolio/ and match tickers against existing cases
- Each position gets a thesis_coverage flag:
covered / uncovered / partial
- For covered positions, link to the case slug + thesis state + stale status
- Flag concentration risks (any position > 20% of total, any sector > 40%)
- Flag stale theses that overlap with active positions
Phase 3 — Dashboard "Portfolio" view
- New fourth view in the cockpit (alongside Board, Cockpit, Intake)
- Summary bar: total portfolio value, total P&L, split by account, position count
- Holdings table: sortable (by weight, P&L, range %), with thesis-coverage column (green dot = covered, click to open that case's cockpit; gray dot = uncovered, click → intake form)
- Exposure panel: sector breakdown pie/bar (reused from
:9078 sector endpoints), beta-weighted concentration map
- Concentration warnings: automatic flag for CLM (46% Schwab), EVVTY (21% Fidelity), and any sector > 40%
- Coverage gap list: the 26 uncovered tickers with a "Start Research" button per position (pre-fills Mira intake with ticker + "from portfolio")
- Data freshness: last pull timestamp, "Refresh from OpenBB" button that calls
pull_portfolio.py
- Follow-up queue: positions whose linked thesis is stale → auto-flagged for monitoring loop
What stays unchanged
- Mira's research loops (portfolio data is input, loops don't change)
- The existing case pipeline and cockpit views
- The
:9078 portfolio-widget-server (read-only pull, never push)
- No new dependencies — same stdlib+vanilla JS pattern as the existing dashboard
What I Want
Wire my actual portfolio into Mira's dashboard. My positions live in a local OpenBB Workspace portfolio app at
http://localhost:9078. Mira already has the analysis framework (portfolio construction review, position review, thesis cross-referencing) but theprivate/portfolio/directory is empty. I want:Context — The Data
Portfolio widget server at
:9078: Schwab (8 positions, ~$29.6K) + Fidelity (20 positions, ~$27.7K) = 28 positions, ~$57.3K total.Endpoints:
/schwab/positions,/fidelity/positions— symbol, description, units, price, market_value, open_pnl, avg_cost, day_change, 52w range, sector/schwab/summary,/fidelity/summary— total value, P&L, position count/schwab/sectors,/fidelity/sectors— dollar/pct allocation by sector/schwab/beta,/fidelity/beta— per-position beta + portfolio betaMira case overlap: Only 2 of 28 positions have cases:
EOSE→cases/eose-2026-05/(Fidelity: $1,287, +$982 P&L, thesis active)LB→ referenced incases/royalty-king-four-pillars-2026-07/(Fidelity: $4,252, +$1,282 P&L)26 positions have no thesis coverage — these become the natural queue for future Mira research.
Notable concentration: CLM is 46% of the Schwab sleeve ($13,687). EVVTY is 21% of Fidelity ($5,844).
Context — What Mira Already Has
loops/portfolio-construction-review-loop.md) — exposure map, concentration, duplicate bets, thesis conflicts, stale positionsloops/portfolio-review-loop.md) — PM-facing multi-thesis reviewloops/position-review-loop.md)templates/portfolio-system/) — CSV templates for register, exposure review, construction reviewdashboard/choices.jsonprivate/portfolio/— doesn't exist (no holdings, weights, or registers)private/views/view-register.csv— only 1 entry ("AI adopters")Plan
Phase 1 — Ingest script (
scripts/pull_portfolio.py):9078endpoints into Mira's private stateprivate/portfolio/:holdings.csv— all 28 positions with Mira-compatible fields (ticker, account, units, price, market_value, open_pnl, avg_cost, sector, date_pulled)summary.json— per-account totalssectors.csv— sector allocationregister.csv— Mira portfolio-register template populateddashboard/build_data.pyPhase 2 — Cross-reference with Mira cases
build_data.pyextended to readprivate/portfolio/and match tickers against existing casescovered/uncovered/partialPhase 3 — Dashboard "Portfolio" view
:9078sector endpoints), beta-weighted concentration mappull_portfolio.pyWhat stays unchanged
:9078portfolio-widget-server (read-only pull, never push)