자산군 필터
대시보드, 포지션, 거래 페이지의 헤더 우측에 공통으로 등장하는 4단 토글입니다. 어떤 자산군의 데이터를 볼지 한 번에 바꿉니다.
📸 자산군 필터 토글 (추후 자동 캡처 예정)
토글 4단
| 라벨 | 값 | 색상 (활성) | 의미 |
|---|---|---|---|
| All | all | indigo | 모든 자산군 합산 (기본값) |
| Crypto | crypto | amber | Binance / Bybit / OKX |
| US | us_equity | blue | Alpaca |
| KR | kr_equity | rose | KIS |
토글은 web/src/components/common/AssetClassFilter.tsx로 구현되어 있고, 현재 값은 페이지별 useState로 관리됩니다 (Dashboard / Positions / Trades).
컬러 코드 일관성
자산군 컬러는 UI 전반에 걸쳐 통일되어 있습니다.
| 자산군 | Tailwind 컬러 | 사용 위치 |
|---|---|---|
| Crypto | amber-500 (15% 배경 / 400 텍스트) | 필터, 배지, Settings 탭 |
| US Equity | blue-500 동일 | 동일 |
| KR Equity | rose-500 동일 | 동일 |
AssetClassBadge 컴포넌트가 이 매핑을 일괄 적용합니다.
동작 방식
토글을 클릭하면 즉시 페이지 내 모든 useQuery의 queryKey에 자산군 값이 추가되어 서버에서 새 데이터를 가져옵니다.
const [assetClass, setAssetClass] = useState<AssetClassFilterValue>('all')
const { data: summary } = useQuery({
queryKey: ['dashboard', 'summary', assetClass],
queryFn: () => getDashboardSummary(assetClass),
refetchInterval: 1000,
})
서버 측은 모든 관련 엔드포인트에서 asset_class 쿼리 파라미터를 받아 WHERE 조건으로 필터링합니다.
| 엔드포인트 | 영향 |
|---|---|
GET /api/dashboard/summary | StatsGrid 카드 합산 |
GET /api/dashboard/equity | EquityChart 곡선 |
GET /api/positions | OpenPositions / Positions 페이지 |
GET /api/trades | RecentTrades / Trades 페이지 |
GET /api/trades/stats | Trades 통계 카드 |
API 호출 예시
# 전체
curl -s -H "Authorization: Bearer $TOKEN" \
"http://localhost:8000/api/dashboard/summary?asset_class=all"
# US Equity만
curl -s -H "Authorization: Bearer $TOKEN" \
"http://localhost:8000/api/dashboard/summary?asset_class=us_equity"
# KR Equity만
curl -s -H "Authorization: Bearer $TOKEN" \
"http://localhost:8000/api/dashboard/summary?asset_class=kr_equity"
asset_class=all인 경우 서버는 쿼리 파라미터를 무시하고 legacy 응답을 그대로 반환합니다.
자주 묻는 질문
Q. 필터를 바꾸면 빈 화면이 나옵니다.
A. 해당 자산군에 거래/포지션이 0건이면 정상입니다. 다른 자산군으로 바꿔보거나 Equity 페이지에서 분석을 시작하세요.
Q. URL에 자산군 상태가 저장됩니까?
A. 현재는 컴포넌트 상태로만 보관되어 새로고침 시 all로 초기화됩니다. 추후 query string 동기화를 검토 중입니다.
Q. 같은 페이지의 모든 카드가 같이 바뀌나요?
A. 네. Dashboard 페이지의 4개 useQuery 모두 동일한 assetClass를 share하므로 동시에 갱신됩니다.