diff --git a/CLAUDE.md b/CLAUDE.md
index dd35849..3828027 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -16,7 +16,7 @@
| `/blog` | `Blog` | 마크다운 기반 블로그 |
| `/lotto` | `Lotto` | 로또 추천/통계 |
| `/stock` | `Stock` | 주식 뉴스/지수 |
-| `/stock/trade` | `StockTrade` | 주식 트레이딩 |
+| `/stock/trade` | `StockTrade` | 주식 트레이딩 (포트폴리오·리포트·어드바이저·보유종목 인텔·관심종목 5탭) |
| `/stock/screener` | `Screener` | 노드 기반 강세주 스크리너 (폼 ↔ n8n 스타일 캔버스 모드 토글, 점수 노드 7 + 위생 게이트 + ATR 포지션 사이저) |
| `/realestate` | `Subscription` | 청약 자격·일정 관리
• **프로필 탭**: 자치구 5티어 분류(드래그&드롭, PC 전용 / 모바일 read-only), 매칭 임계값 슬라이더, 텔레그램 알림 토글
• **카드/매칭 결과**: district 뱃지 + 5티어(S/A/B/C/D) 뱃지 표시
• **상세 모달**: 매칭 분석 섹션 (점수 + 사유 + 신청 자격) |
| `/realestate/property` | `RealEstate` | 관심 단지 정보 |
@@ -102,6 +102,10 @@ proxy: {
| 스크리너 | POST | `/api/stock/screener/snapshot/refresh` |
| 스크리너 | GET | `/api/stock/screener/runs?limit=N` |
| 스크리너 | GET | `/api/stock/screener/runs/:id` |
+| 관심종목 | GET | `/api/stock/watchlist` — { watchlist: [{ ticker, name, note, params, added_at }] } |
+| 관심종목 | POST | `/api/stock/watchlist` — body: { ticker, name?, note? } |
+| 관심종목 | DELETE | `/api/stock/watchlist/:ticker` |
+| 매매 시그널 | GET | `/api/stock/trade-alerts?days=N` — { alerts: [{ id, ticker, name, kind, condition, price, detail, fired_at }] } |
| 포트폴리오 | GET/POST | `/api/portfolio` |
| 포트폴리오 | PUT/DELETE | `/api/portfolio/:id` |
| 예수금 | PUT | `/api/portfolio/cash` — body: `{ broker, cash }` |
diff --git a/src/pages/stock/StockTrade.jsx b/src/pages/stock/StockTrade.jsx
index e751d72..17d53a0 100644
--- a/src/pages/stock/StockTrade.jsx
+++ b/src/pages/stock/StockTrade.jsx
@@ -6,7 +6,7 @@ import SwipeableView from '../../components/SwipeableView';
import {
formatNumber, formatPercent,
toNumeric, profitColorClass,
- TAB_PORTFOLIO, TAB_REPORT, TAB_ADVISOR, TAB_HOLDINGS_INTEL,
+ TAB_PORTFOLIO, TAB_REPORT, TAB_ADVISOR, TAB_HOLDINGS_INTEL, TAB_WATCHLIST,
} from './stockUtils';
/* ── hooks ──────────────────────────────────────────────────────── */
@@ -17,12 +17,14 @@ import useAssetHistory from './hooks/useAssetHistory';
import useMarketContext from './hooks/useMarketContext';
import useReportData from './hooks/useReportData';
import useAdvisor from './hooks/useAdvisor';
+import useWatchlist from './hooks/useWatchlist';
/* ── tab components ─────────────────────────────────────────────── */
import PortfolioTab from './components/PortfolioTab';
import ReportTab from './components/ReportTab';
import AdvisorTab from './components/AdvisorTab';
import HoldingsIntelTab from './components/HoldingsIntelTab';
+import WatchlistTab from './components/WatchlistTab';
import SellHistoryDrawer from './components/SellHistoryDrawer';
/* ── component ───────────────────────────────────────────────────── */
@@ -31,8 +33,8 @@ const StockTrade = () => {
const [activeTab, setActiveTab] = React.useState(TAB_REPORT);
const isMobile = useIsMobile();
- const TAB_ORDER = [TAB_PORTFOLIO, TAB_REPORT, TAB_ADVISOR, TAB_HOLDINGS_INTEL];
- const tabLabels = ['포트폴리오', '리포트', '어드바이저', '보유종목 인텔'];
+ const TAB_ORDER = [TAB_PORTFOLIO, TAB_REPORT, TAB_ADVISOR, TAB_HOLDINGS_INTEL, TAB_WATCHLIST];
+ const tabLabels = ['포트폴리오', '리포트', '어드바이저', '보유종목 인텔', '관심종목'];
const tabIndex = TAB_ORDER.indexOf(activeTab);
const handleTabChange = useCallback((idx) => setActiveTab(TAB_ORDER[idx]), []); // eslint-disable-line react-hooks/exhaustive-deps
@@ -62,6 +64,7 @@ const StockTrade = () => {
totalAssets: pf.totalAssets,
marketCtx,
});
+ const wl = useWatchlist();
/* ── sell history filter derived ─────────────────────────────── */
const sellHistoryBrokers = useMemo(() => {
@@ -169,7 +172,9 @@ const StockTrade = () => {
?
: tabId === TAB_ADVISOR
?
- : ,
+ : tabId === TAB_HOLDINGS_INTEL
+ ?
+ : ,
}))}
activeIndex={tabIndex}
onTabChange={handleTabChange}
@@ -182,6 +187,7 @@ const StockTrade = () => {
{ id: TAB_REPORT, icon: '📊', label: '리포트', sub: '분석·AI코치' },
{ id: TAB_ADVISOR, icon: '🧠', label: 'AI 어드바이저', sub: 'Gemini Pro', className: 'stock-main-tab--advisor' },
{ id: TAB_HOLDINGS_INTEL, icon: '🔍', label: '보유종목 인텔', sub: '신호·이슈', className: 'stock-main-tab--holdings-intel' },
+ { id: TAB_WATCHLIST, icon: '⭐', label: '관심종목', sub: '관리·시그널', badge: wl.items.length || null },
].map(({ id, icon, label, sub, badge, className: cls }) => (