feat: company names for tickers (Alpaca backfill + subtle display)
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>
This commit is contained in:
@@ -4,6 +4,7 @@ import { useActivation } from '../hooks/useActivation';
|
||||
import { useTrades } from '../hooks/useTrades';
|
||||
import { useWatchlist } from '../hooks/useWatchlist';
|
||||
import { usePaperTrades } from '../hooks/usePaperTrades';
|
||||
import { useTickerNames } from '../hooks/useTickers';
|
||||
import { useMarketRegime } from '../hooks/useMarketRegime';
|
||||
import { regimeColor, regimeDot, regimeHeadline } from '../lib/regime';
|
||||
import { Callout } from '../components/ui/Callout';
|
||||
@@ -62,6 +63,7 @@ function DirectionTag({ direction }: { direction: string }) {
|
||||
export default function DashboardPage() {
|
||||
const trades = useTrades();
|
||||
const watchlist = useWatchlist();
|
||||
const tickerNames = useTickerNames();
|
||||
const activation = useActivation();
|
||||
const openTrades = usePaperTrades('open');
|
||||
const regime = useMarketRegime();
|
||||
@@ -237,6 +239,11 @@ export default function DashboardPage() {
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
{tickerNames.get(setup.symbol.toUpperCase()) && (
|
||||
<div className="max-w-[160px] truncate text-[11px] text-gray-500">
|
||||
{tickerNames.get(setup.symbol.toUpperCase())}
|
||||
</div>
|
||||
)}
|
||||
</td>
|
||||
<td className="px-4 py-3"><DirectionTag direction={setup.direction} /></td>
|
||||
<td className="num px-4 py-3 text-right text-gray-200">{formatPrice(setup.entry_price)}</td>
|
||||
|
||||
@@ -10,6 +10,7 @@ import { topPickSymbol, qualifiesSetup } from '../lib/qualification';
|
||||
import type { FetchSelector } from '../api/ingestion';
|
||||
import { CandlestickChart } from '../components/charts/CandlestickChart';
|
||||
import { ScoreCard } from '../components/ui/ScoreCard';
|
||||
import { useTickerNames } from '../hooks/useTickers';
|
||||
import { SkeletonCard } from '../components/ui/Skeleton';
|
||||
import { SentimentPanel } from '../components/ticker/SentimentPanel';
|
||||
import { FundamentalsPanel } from '../components/ticker/FundamentalsPanel';
|
||||
@@ -120,6 +121,7 @@ function DataFreshnessBar({
|
||||
|
||||
export default function TickerDetailPage() {
|
||||
const { symbol = '' } = useParams<{ symbol: string }>();
|
||||
const companyName = useTickerNames().get(symbol.toUpperCase());
|
||||
const { ohlcv, scores, srLevels, sentiment, fundamentals, trades } = useTickerDetail(symbol);
|
||||
const ingestion = useFetchSymbolData();
|
||||
const watchlist = useWatchlist();
|
||||
@@ -274,6 +276,9 @@ export default function TickerDetailPage() {
|
||||
<div className="flex flex-wrap items-center justify-between gap-4">
|
||||
<div className="flex items-baseline gap-4">
|
||||
<h1 className="text-3xl font-semibold text-gray-100">{symbol.toUpperCase()}</h1>
|
||||
{companyName && (
|
||||
<span className="max-w-[240px] truncate text-sm text-gray-500">{companyName}</span>
|
||||
)}
|
||||
{priceInfo && (
|
||||
<div className="flex items-baseline gap-2">
|
||||
<span className="num text-2xl font-semibold text-gray-100">{formatPrice(priceInfo.price)}</span>
|
||||
|
||||
Reference in New Issue
Block a user