| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384 |
- // 세계 주요국 증시지수 도메인 타입 — Backend Application/Features/Api/Stocks/GetWorldIndices/Response.cs 대응
- // 직렬화 주의: 필드명 camelCase. flucRateBp = 등락률 basis point(%×100). enum 없음(전부 primitive).
- // ── GET /api/market/world-indices ──
- export interface WorldIndexRow {
- countryCode: string; // ISO2 대문자 — EXCHANGE_GEO 좌표맵 키
- name: string; // 지수명 (예: "코스피", "S&P 500")
- exchangeName: string;
- close: number;
- changeVal: number;
- flucRateBp: number; // %×100 (예: -70 = -0.70%)
- tradeDate: string; // yyyy-MM-dd
- }
- export interface WorldIndicesResponse {
- list: WorldIndexRow[];
- }
- // ── 지역(흥국 지역 필터 대응) ──
- // 'major'(주요국)는 지역 교차 큐레이션 탭 — 지리적 region 과 별개로 major 플래그로 표기.
- export type MarketRegion = 'asia'|'europe'|'america'|'mideast';
- export const REGION_LABELS: Record<'major'|MarketRegion, string> = {
- major: '주요국',
- asia: '아시아',
- america: '아메리카',
- europe: '유럽',
- mideast: '중동·아프리카'
- };
- // 지역 탭 노출 순서 (major 우선, 이후 데이터 있는 지역만 렌더)
- export const REGION_ORDER: ('major'|MarketRegion)[] = ['major', 'asia', 'america', 'europe', 'mideast'];
- // ── 국가 → 지도 좌표(위경도) + 표시명. 나라당 1개(대표 지수) 기준 ──
- // 프론트가 국가 코드로 세계지도 핀 위치를 정한다(백엔드는 좌표를 보내지 않음 — 응답 경량화).
- export interface ExchangeGeo {
- lat: number;
- lng: number;
- label: string; // 국가 표시명 (한글)
- region: MarketRegion; // 지리적 지역 탭
- major?: boolean; // 주요국 탭 포함 여부
- }
- export const EXCHANGE_GEO: Record<string, ExchangeGeo> = {
- US: { lat: 40.7, lng: -74.0, label: '미국', region: 'america', major: true },
- KR: { lat: 37.5, lng: 127.0, label: '한국', region: 'asia', major: true },
- JP: { lat: 35.7, lng: 139.7, label: '일본', region: 'asia', major: true },
- CN: { lat: 31.2, lng: 121.5, label: '중국', region: 'asia', major: true },
- HK: { lat: 22.3, lng: 114.2, label: '홍콩', region: 'asia' },
- TW: { lat: 25.0, lng: 121.6, label: '대만', region: 'asia' },
- SG: { lat: 1.35, lng: 103.8, label: '싱가포르', region: 'asia' },
- IN: { lat: 19.1, lng: 72.9, label: '인도', region: 'asia' },
- AU: { lat: -33.9, lng: 151.2, label: '호주', region: 'asia' },
- GB: { lat: 51.5, lng: -0.1, label: '영국', region: 'europe', major: true },
- DE: { lat: 50.1, lng: 8.7, label: '독일', region: 'europe', major: true },
- FR: { lat: 48.9, lng: 2.3, label: '프랑스', region: 'europe' },
- CA: { lat: 43.7, lng: -79.4, label: '캐나다', region: 'america' },
- BR: { lat: -23.5, lng: -46.6, label: '브라질', region: 'america' }
- };
- // ── 등락 상태 ──
- export type MoveDir = 'up' | 'down' | 'flat';
- export function moveDir(flucRateBp: number): MoveDir {
- if (flucRateBp > 0) {
- return 'up';
- }
- if (flucRateBp < 0) {
- return 'down';
- }
- return 'flat';
- }
- // 등락률 Bp → "+1.45%" / "-0.70%" / "0.00%"
- export function formatFlucRate(flucRateBp: number): string {
- const pct = flucRateBp / 100;
- const sign = flucRateBp > 0 ? '+' : '';
- return `${sign}${pct.toFixed(2)}%`;
- }
- // 종가 표시 — 천단위 콤마 + 소수 2자리
- export function formatIndexClose(close: number): string {
- return close.toLocaleString('ko-KR', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
- }
|