diff --git a/backend/app/api/markets.py b/backend/app/api/markets.py index 55965ce..5a0eedf 100644 --- a/backend/app/api/markets.py +++ b/backend/app/api/markets.py @@ -4,10 +4,11 @@ GET /api/markets/movers ?market=KOSPI|KOSDAQ|ALL (기본 ALL) ?limit=10 (각 카테고리 별 상위 N) -응답 (3 카테고리): - - gainers: 등락률 상위 (전일종가 대비 상승%) - - losers : 등락률 하위 (하락%) - - volume : 거래량 상위 (당일 volume) +응답 (4 카테고리): + - gainers : 등락률 상위 (전일종가 대비 상승%) + - losers : 등락률 하위 (하락%) + - by_volume : 거래량 상위 (당일 volume) + - by_trading_value: 거래대금 상위 (close × volume, 원 단위) ohlcv_daily 에서 가장 최근 2 거래일을 잡아 비교한다. 데이터가 한 종목당 2 일치 이상 없을 때는 그 종목은 자연 누락된다. @@ -64,7 +65,8 @@ def _movers_sql(where_market: str) -> str: CASE WHEN p.close1 > 0 THEN (l.close0 - p.close1) / p.close1 * 100 ELSE NULL - END AS pct_change + END AS pct_change, + (l.close0 * l.volume0) AS trading_value FROM symb s JOIN latest l ON l.code = s.code JOIN prev p ON p.code = s.code @@ -97,6 +99,10 @@ def movers( text(base_sql + " ORDER BY volume DESC NULLS LAST LIMIT :lim"), params, ).all() + by_trading_value = conn.execute( + text(base_sql + " ORDER BY trading_value DESC NULLS LAST LIMIT :lim"), + params, + ).all() def _row(r) -> dict: return { @@ -107,6 +113,7 @@ def movers( "prev_close": float(r[4]) if r[4] is not None else None, "volume": int(r[5]) if r[5] is not None else None, "pct_change": float(r[6]) if r[6] is not None else None, + "trading_value": float(r[7]) if r[7] is not None else None, } return { @@ -115,6 +122,7 @@ def movers( "gainers": [_row(r) for r in gainers], "losers": [_row(r) for r in losers], "by_volume": [_row(r) for r in by_volume], + "by_trading_value": [_row(r) for r in by_trading_value], } diff --git a/web/components/MarketsOverview.tsx b/web/components/MarketsOverview.tsx index 495ca79..eabcb15 100644 --- a/web/components/MarketsOverview.tsx +++ b/web/components/MarketsOverview.tsx @@ -1,7 +1,8 @@ "use client"; -// 시장 overview: 등락 상위 / 등락 하위 / 거래량 상위 3 컬럼. +// 시장 overview: 등락 상위 / 등락 하위 / 거래대금 상위 / 거래량 상위 4 컬럼. // /api/markets/movers 응답을 그대로 표 형태로 렌더. +// 거래대금 = close × volume, 단위 억원. 토스 톤의 핵심 랭킹. import Link from "next/link"; import { useEffect, useState } from "react"; @@ -41,7 +42,10 @@ export function MarketsOverview() { // 아직 ohlcv_daily 가 비어 있으면 모든 리스트가 빈 배열로 옴 — 안내만. const empty = - !data.gainers.length && !data.losers.length && !data.by_volume.length; + !data.gainers.length && + !data.losers.length && + !data.by_volume.length && + !data.by_trading_value.length; if (empty) return (