The dashboard fingerprints sorted score dimensions alphabetically
while the ticker page rendered them in API order, so the same ticker
drew a differently-shaped polygon on each page.
New shared helper radarAxesFromDimensions() pins the axis order to the
backend's DIMENSIONS list (technical, sr_quality, sentiment,
fundamental, momentum; unknown dimensions append alphabetically) and
centralizes the label truncation. Used by the dashboard fingerprint
strip, the ticker header radar, and ScoreCard.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- The ladder target choice is lifted to the ticker page (per
direction), so selecting a target updates the candlestick overlay's
target line and zone too, with the R:R for the tooltip taken from
the ladder row.
- Price rail: the scale now always spans the entire target ladder, so
stop / entry / now hold their positions and only the target marker
moves when a different target is selected. The furthest target sits
at the right edge.
- Setup card layout: position sizing (shares / value / max loss,
details in the tooltip) and the Mark-as-taken button move to the top
right of the card header row, next to the stats they belong with -
the dangling bottom row is gone.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
selectable targets drive the rail
- Data freshness is now the very first row of the ticker panel, above
the symbol - data age is the first thing to check.
- Indicator cards: long price-level lists (pivot swing highs/lows,
volume-profile HVN/LVN) no longer clip or overwhelm. Numeric lists
are clustered into ranges (values within ~0.75% of price merge),
sorted nearest-to-price first, capped at 4 chips with a "+n more"
note; scalar values wrap instead of overflowing the card.
- Recommendation verdict: the action ("LONG (high confidence)") is set
in the display face in accent cyan with the risk level beside it;
the signal breakdown (technical/momentum/sentiment) drops to a small
muted subtitle line.
- Target ladder is open by default and selectable: clicking a row
previews that target on the price rail and updates the R:R and
probability chips, the low-probability warning, and the prefilled
target in Mark-as-taken (still overridable there). The scanner's
primary stays the default; a non-primary choice is chipped as
"custom target".
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
verdict de-dup, target picker on take
Five fixes from prod review:
1. Data freshness row moves from the panel foot to directly under the
header - data age is a first-look concern.
2. Radar fingerprint labels were clipped left ("Momentum") and right
(value digits): label padding widened to fit "momentum 100" on both
anchored sides.
3. Indicators tab: the one-at-a-time dropdown (which also clipped) is
gone; all indicators load in parallel as quiet outlined cards - EMA
cross with its colored signal, RSI/ADX with a one-line human read
(overbought / trending / ...), values formatted to 2 decimals
instead of 4, normalized score demoted to a corner note.
4. Recommendation verdict line de-duplicated: the backend reasoning
already starts with the action label, so it now replaces the
headline instead of repeating under it.
5. Mark-as-taken: the take form gains a target selector listing every
detected target with price / probability / classification (primary
preselected), and the card warns when the primary target sits below
15% probability. Why the scanner promotes such a target to primary
is a separate (backend) question.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
RecommendationPanel redesigned to match the rest of the redesign:
- Setup cards use the spatial price rail (stop -> entry -> now ->
target with live R-multiples) instead of the label/value text grid.
- One quiet chip row per card (direction, preferred marker, confidence,
R:R, target probability) replaces scattered header text.
- Position sizing is a single mono line (shares / position / max loss)
instead of a boxed 3-column mini-table; Mark-as-taken flow kept, in
the standard cyan button style.
- Full target ladder moves behind a disclosure (the primary target is
already on the rail); warnings (counter-trend, stale/invalidated
drift, earnings window, conflict flags) all kept.
- Cards are quiet outlined blocks, no glass-in-glass; the module
renders frameless inside the unified ticker panel's Analysis tab,
under the chart.
Ticker panel tabs now: Analysis, Standing, Dimensions, Indicators,
S/R Levels, Sentiment, Fundamentals - Standing and Dimensions were the
last below-the-fold sections; the whole page is now the single panel.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The previous pass kept a stack of independent glass cards (header,
recommendation, chart section, tab pills, per-tab sections), which read
as clutter. Now the page is a single casting, like the mockup:
One glass panel containing:
- header (identity, price, chips | actions + score fingerprint)
- inline hairline tab row (Analysis / Indicators / S/R Levels /
Sentiment / Fundamentals) with the chart-overlay pills riding on the
right of the row during Analysis
- tab body: Analysis = the candlestick chart; other tabs render their
panel inside via .hz-frameless, which strips the nested card chrome
(no card-in-card)
- panel foot: data freshness row (frameless now) with per-source
refresh
Below the panel, only on Analysis: the recommendation module and a
two-column Standing | Dimensions grid. Nothing removed; the standalone
Tabs bar, the separate chart card, and the duplicated section stack are
gone.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Restructures TickerDetailPage to match the Horizon mockup's ticker
drill-down while keeping every existing feature:
- Glass header card: eyebrow + big symbol/company, price with change
and freshness, chips (composite score, next earnings, top-pick /
open-trade pills) on the left; watchlist + Fetch All actions and the
score fingerprint radar on the right (hover a corner for values).
- Data freshness bar (per-source age + refresh buttons) moves to the
foot of the chart card, like the mockup's panel footer.
- Tabs extended to five: Analysis, Indicators, S/R Levels, Sentiment,
Fundamentals - sentiment and fundamentals no longer stack below the
analysis content, they are one tab away.
- ScoreCard gains showRadar prop so the fingerprint is not duplicated
in the Dimensions section.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Store an optional company name on Ticker (migration 014) and backfill it from
Alpaca's asset list in a single Trading-API call for the whole universe — no
per-ticker fetch. Runs automatically at the end of universe bootstrap and via a
manual "Backfill Names" button (admin) / POST /admin/tickers/backfill-names.
The name ships on /tickers; a shared symbol→name map (useTickerNames) lets any view
show it without its own request. Displayed subtly next to the symbol — in the global
search, the ticker header, and as a small muted line under the symbol in Top Setups
and Open Trades (no extra column, truncated so it never widens the table).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The ticker page renders the composite via the Standing matrix (ScoreCard runs with
showComposite=false), so the "Base X · sentiment +Y" line in the ScoreCard header
was never visible there. Add a compact caption beneath the matrix — "Composite 83 =
Base 78 + Sentiment 5.0" — shown only when sentiment actually moves the score, so
the composition of the number has a visible home where the number lives.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Replace the scattered score readouts with one hero: a quality (composite) x
momentum-percentile scatter that plots this ticker against the whole field and
reads out a verdict by quadrant — Strong Buy / Momentum / Accumulate / Pass. The
dashed divider is the activation gate's momentum percentile, so "above the line =
qualifies" is visible at a glance; peers are clickable. Reuses the regime-quadrant
visual language and is lazy-loaded so recharts stays out of the main ticker chunk.
- New StandingMatrix component (composite x momentum, field cloud, verdict).
- ScoreCard gains showComposite (default true); the ticker page now renders it
without the composite ring (composite lives in the matrix) under "Dimensions".
- Confidence + target probability stay in the recommendation panel (the trade).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Two read-only pills in the ticker header, beside the watchlist toggle:
- "Top Pick" when the ticker is the current #1 — the same ranking the dashboard
highlights, via a shared topPickSymbol() helper so the two stay in sync.
- "Open Trade" when an open paper trade exists on the ticker.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Finnhub's earnings calendar now supplies next_earnings_date through the
fundamentals chain; persisted on fundamental_data (migration 006) and exposed in
the fundamentals API. The recommendation panel warns when earnings fall within
the ~30-day target horizon (a report can gap price through stop/target) and
otherwise shows the next date. Informational only.
Deploy: run alembic upgrade (new fundamental_data.next_earnings_date column).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Removing a ticker did nothing because get_watchlist re-runs auto_populate on
every read, instantly re-adding any top-ranked ticker the user had just removed.
Removals are now tombstoned as a "dismissed" entry_type: auto-population skips
them, the list hides them, and a later manual add revives the row. Also exposes
an Add/Remove-watchlist toggle in the ticker detail header.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Scores never updated ("101d ago"): get_score only recomputes stale/
missing dimensions, but nothing marked them stale on new data, and there
was no scheduled scoring job.
- Fetch endpoint force-recomputes dimensions + composite.
- Scheduled scan (scan_all_tickers) refreshes scores per ticker, so
scores stay current globally, not just on manual fetch.
Granular fetch: /ingestion/fetch accepts a sources filter; the freshness
bar gets a per-row refresh button (OHLCV/Sentiment/Fundamentals fetch
that provider only — marked paid; S/R/Scores recompute for free). Header
button is now "Fetch All".
Job visibility: GET /jobs/running (any user) + sidebar live indicator
showing running scheduled jobs with progress, polled every 10s.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Triggered by MRK: entry 113 shown with no current price (actually ~119).
- Ticker header shows last close + day change % + "last close · Nd ago"
(the age reveals OHLCV collection lag — why entry looked off)
- Setup cards show Current price and entry drift; flag setups as
stale (price moved >1/3 toward target) or invalidated (past stop)
- Chart: draw only nearest support below + nearest resistance above
current price, plus a prominent "Now" price line (full S/R stays in
the S/R tab)
- Chart overlay is selectable (Auto/Long/Short/None) — only the chosen
setup's entry/stop/target render, instead of everything at once
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Add shared UI primitives: Button, Field/Input/Select, PageHeader,
Section, Callout, Tabs, Disclosure
- Replace gradient buttons with single blue-accent btn-primary
- Reserve gradient text for the brand wordmark only
- Rework Scanner page onto the glass system; collapse explainer and
glossary into a disclosure, move filters into a glass toolbar
- Restructure Ticker Detail into tabs (Analysis / Indicators / S/R)
with chart and recommendation always visible
- Align Watchlist, Rankings, Admin, Login/Register to shared primitives
- Unify stray indigo/violet/gray accents into the blue family
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>