Files
stockautomtion/app/main.py
gerd 182c2b38e6 feat: config.yaml 기반 설정 마이그레이션 및 대시보드/종목조회 기능 추가
- config.yaml에서 직접 KIS 설정 관리 (BaseSettings 제거)
- 대시보드 KIS 계좌 잔고 실시간 연동, 로컬 DB 폴백
- 종목 조회 페이지: 시세/호가/일봉차트 (canvas) 구현
- 호가 REST API 엔드포인트 (/api/stocks/{code}/orderbook) 추가
- 토큰 캐시(.auth_cache.json) 저장/복원, 1분 재시도 제한
- KIS WebSocket 자동 연결 + 재연결 로직
- httpx 타임아웃 10초→30초, 라우터 타임아웃 핸들링 (504)
- rate limit: requests_per_second 2.0 (모의투자 초당 2건)
- 사이드바 3메뉴: 실거래 / 과거기록 / 종목조회
2026-07-17 15:25:34 +09:00

101 lines
2.9 KiB
Python

from __future__ import annotations
from contextlib import asynccontextmanager
from fastapi import FastAPI, Request
from fastapi.responses import HTMLResponse
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
from app.core.config import settings
from app.core.database import init_db
from app.core.logger import setup_logger
from app.core.auth import token_manager
from app.engine.scheduler import start_scheduler, stop_scheduler
from app.services.market_data import market_data_service
from app.services.trading import trading_service
from app.services.account import account_service
from app.services.realtime import realtime_service
from app.routers import stocks, trading, strategies, websocket, dashboard
logger = setup_logger("main", level=settings.app.log_level)
@asynccontextmanager
async def lifespan(app: FastAPI):
logger.info("=== Stock Automation 시작 ===")
logger.info("서버 모드: %s", settings.kis.server_mode)
init_db()
logger.info("데이터베이스 초기화 완료")
try:
await token_manager.get_access_token()
if token_manager.is_authenticated:
logger.info("KIS 인증 완료")
else:
logger.warning(
"KIS 인증 실패 - API 키를 확인하세요 (.env 파일). "
"UI는 표시되지만 시세 조회/매매 기능은 작동하지 않습니다."
)
except Exception as e:
logger.warning("KIS 인증 오류: %s", e)
if token_manager.is_authenticated:
start_scheduler()
try:
await realtime_service.connect()
logger.info("KIS WebSocket 연결 완료")
except Exception as e:
logger.warning("KIS WebSocket 연결 실패: %s", e)
else:
logger.info("인증 실패 - 스케줄러 미시작 (인증 후 수동 시작 가능)")
yield
logger.info("=== Stock Automation 종료 ===")
stop_scheduler()
await realtime_service.disconnect()
await market_data_service.close()
await trading_service.close()
await account_service.close()
await token_manager.close()
app = FastAPI(
title="Stock Automation",
description="한국투자증권 API 기반 자동매매 시스템",
version="0.1.0",
lifespan=lifespan,
)
app.include_router(stocks.router)
app.include_router(trading.router)
app.include_router(strategies.router)
app.include_router(websocket.router)
app.include_router(dashboard.router)
templates = Jinja2Templates(directory="app/templates")
@app.get("/", response_class=HTMLResponse)
async def index(request: Request):
return templates.TemplateResponse(request, "index.html")
@app.get("/health")
async def health():
return {"status": "ok", "mode": settings.kis.server_mode}
if __name__ == "__main__":
import uvicorn
uvicorn.run(
"app.main:app",
host=settings.app.host,
port=settings.app.port,
reload=settings.app.debug,
)