환경

  • FastAPI/Python 3.11
  • Docker-Compose
  • Next.js 15/React 19/TypeScript
  • Lightweight Charts (캔들차트)

 KIS API 인프라 (infrastructure/kis/)

  • auth.py: OAuth 토큰 발급/갱신/취소, 10분 이내 만료 시 자동 갱신
  • client.py: 시장 데이터 조회하는 클래스

데이터 종류

- 현재가 (get_current_price)
- 호가 (get_orderbook)
- 체결 (get_executions)
- 캔들 (get_candles)
- 업종별 시세 (get_sector_prices)

도메인 모델 (core/models/)

  • auth.py: TokenInfo 모델(토큰 정보 및 만료 확인)
  • stock.py: 주식 데이터 모델

API 라우트 (api/routes/)

  • health.py: 헬스체크, KIS 연결 상태 확인
  • stocks.py: 주식 시장 데이터 REST API
- /api/v1/stocks/{stock_code}/price - 현재가
- /api/v1/stocks/{stock_code}/orderbook - 호가
- /api/v1/stocks/{stock_code}/executions - 체결
- /api/v1/stocks/{stock_code}/candles - 캔들
- /api/v1/stocks/sectors/prices - 업종 시세

프론트엔드 구조

  src/
  ├── app/                  # Next.js App Router 페이지
  │   ├── layout.tsx        # 루트 레이아웃 (QueryProvider 적용)
  │   ├── page.tsx          # 홈페이지 - 관심종목 테이블
  │   └── stocks/[code]/    # 종목 상세 - 차트, 호가창, 체결내역
  ├── components/
  │   ├── ui/               # shadcn/ui 기본 컴포넌트
  │   ├── stock/            # StockChart, OrderBook, ArrangementBadge
  │   └── watchlist/        # WatchlistTable
  ├── hooks/
  │   └── useStocks.ts      # React Query 훅 (가격, 캔들, 호가, 체결)
  ├── lib/
  │   ├── api/              # Axios 클라이언트 및 API 함수
  │   ├── stores/           # Zustand 관심종목 스토어
  │   └── utils/            # 지표 계산 (SMA, 정배열/역배열)
  └── providers/            # TanStack Query Provider

프론트엔드

프론트엔드는 React Query를 사용하여 백엔드 API를 호출한다. 장중에는 30초 폴링으로 데이터를 갱신하며, Rate Limit 문제 방지를 위해 API 호출 시 시차를 두어 요청한다.

  • useStockPrice: 현재가 조회 (0ms 후 호출)
  • useOrderBook: 호가 조회 (300ms 후 호출)
  • useExecutions: 체결내역 조회 (600ms 후 호출)
  • useStockCandles: 캔들 데이터 조회 (900ms 후 호출)

구현된 기능

  • 관심종목 검색/등록/삭제 (Zustand + LocalStorage 영속화)
  • 캔들차트 (일/주/월봉 + 1/3/5/10/30분봉)
  • 이동평균선 오버레이 (MA5/20/60/120/240, 토글 가능)
  • 정배열/역배열 배지 표시
  • 10단계 호가창 (매수/매도잔량 바 시각화)
  • 실시간 체결내역 테이블


Docker & DB

현재 실행 중인 도커 컨테이너를 정리하면 다음과 같다.

서비스포트상태
trade-app (FastAPI)8000✅ healthy
trade-redis6379✅ healthy
trade-timescaledb5432✅ healthy

시계열 데이터베이스를 처음 써보는데, 이는 주가의 관련 데이터들이 모두 시간과 크게 연관되어 있는 데이터이기 때문이다.

다음으로는 API 엔드포인트이다. {code}는 종목의 번호이다.

API엔드포인트예시
현재가 조회GET /api/v1/stocks/{code}/price/stocks/005930/price
호가 조회GET /api/v1/stocks/{code}/orderbook/stocks/005930/orderbook
체결가 조회GET /api/v1/stocks/{code}/executions/stocks/005930/executions?count=10
캔들 데이터GET /api/v1/stocks/{code}/candles/stocks/005930/candles?period=D&count=30
업종 시세GET /api/v1/stocks/sectors/pricesKODEX 200 ETF 기준

Swagger 문서

http://localhost:8000/docs 에서 API 명세를 확인할 수 있도록 하였다.

주요 파일

  주요 파일

  backend/src/
  ├── main.py                          # FastAPI 앱
  ├── config/settings.py               # 환경설정
  ├── core/models/                     # Pydantic 모델
  │   ├── auth.py
  │   └── stock.py
  ├── infrastructure/kis/              # KIS API 연동
  │   ├── auth.py                      # OAuth 인증
  │   └── client.py                    # API 클라이언트
  └── api/routes/                      # REST 엔드포인트
      ├── health.py
      └── stocks.py