Skip to content

Portfolio Dashboard: ingest real positions from OpenBB into Mira dashboard #105

Description

@toasterman234

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:

  • EOSEcases/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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions