Skip to content

Correlation matrix and per-asset statistics - #16

Merged
GusFurtado merged 1 commit into
allocation-sectionfrom
correlation-assets-sections
Sep 11, 2026
Merged

GusFurtado merged 1 commit into
allocation-sectionfrom
correlation-assets-sections

Conversation

@GusFurtado

Copy link
Copy Markdown
Collaborator

Context

PR 6 of the widescreen "analytical workstation" report redesign. Stacked on #15 (targets that branch, not main).

What's here

Both sections bundled in one PR since they share the grid-row table pattern #15 already built (.mw-table/.mw-grid-row/.mw-num), and neither has any interactive state of its own — no drag, no slider — so both are plain full-rebuild-on-render sections, unlike the frontier chart or allocation's cash slider.

  • Correlation matrix — a CSS-grid matrix (not a <table>, matching the rest of the report), cell color linearly interpolated in RGB from neutral-900 to accent-600. Text stays ink-dark at every value — this ramp, unlike the earlier mobile design's, never needs a light/dark contrast threshold, since it tops out light enough that dark text stays correct throughout. The least/most-correlated-pair callout scans only the upper triangle so each pair is considered once.
  • Per-asset statistics — standalone per-asset expected return/volatility (from asset_statistics — independent of any portfolio weighting), a client-computed standalone Sharpe, and a Weight column that reads through selectedPortfolio() — so, matching the handoff, it updates live as the frontier selection is dragged, not just at the tangency default. Zero/near-zero weights dim to neutral-600 rather than being hidden, so an asset the optimizer declined stays visible.

Verification

Headless Chromium against a synthetic /api/analyze response: the matrix diagonal is 1.00 everywhere, the least/most correlated pairs match a manual scan of the input matrix, and the per-asset Weight column changes when jumping to the minimum-variance point on the frontier (confirming it tracks selection, not a fixed snapshot) — plus a full-page screenshot checked against the handoff.

🤖 Generated with Claude Code

Both bundled in one PR since they share the grid-row table pattern
PR 5 already built (.mw-table/.mw-grid-row/.mw-num), and neither has
any interactive state of its own — no drag, no slider — so both are
plain full-rebuild-on-render sections, unlike frontier/allocation.

frontend/app.js:
- correlationSectionHtml(): a CSS-grid matrix (not a <table>, matching
  the rest of the report), cell color linearly interpolated in RGB from
  neutral-900 to accent-600. Text stays ink-dark at every value — this
  ramp (unlike the mobile design's) never needs a light/dark contrast
  threshold, since it tops out light enough that dark text stays
  correct throughout. The least/most-correlated-pair callout scans only
  the upper triangle so each pair is considered once.
- assetStatsSectionHtml(): standalone per-asset expected return/
  volatility (from asset_statistics — independent of any portfolio),
  a client-computed standalone Sharpe, and the Weight column reads
  through selectedPortfolio() — so, matching the handoff, it updates
  live as the frontier selection is dragged, not just at the tangency
  default. Zero/near-zero weights dim to neutral-600 rather than being
  hidden, so an asset the optimizer declined stays visible.

Verified with headless Chromium against a synthetic /api/analyze
response: the matrix diagonal is 1.00 everywhere, the least/most
correlated pairs match a manual scan of the input matrix, and the
per-asset Weight column changes when jumping to the minimum-variance
point on the frontier (confirming it tracks selection, not a fixed
snapshot) — plus a full-page screenshot checked against the handoff.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@GusFurtado
GusFurtado merged commit 65a79f7 into allocation-section Sep 11, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant