Files
web-page-backend/stock-lab/app/main.py

96 lines
2.7 KiB
Python

import os
from fastapi import FastAPI
from apscheduler.schedulers.background import BackgroundScheduler
from .db import init_db, save_articles, get_latest_articles
from .db import init_db, save_articles, get_latest_articles
from .scraper import fetch_market_news, fetch_major_indices, fetch_overseas_news
from .kis_api import KisApi
from .analysis import AIAnalyst
from pydantic import BaseModel
app = FastAPI()
scheduler = BackgroundScheduler(timezone=os.getenv("TZ", "Asia/Seoul"))
kis = KisApi()
analyst = AIAnalyst()
@app.on_event("startup")
def on_startup():
init_db()
# 매일 아침 8시 뉴스 스크랩
scheduler.add_job(run_scraping_job, "cron", hour="8", minute="0")
# 앱 시작 시에도 한 번 실행 (데이터 없으면)
if not get_latest_articles(1):
run_scraping_job()
scheduler.start()
def run_scraping_job():
print("[StockLab] Starting news scraping...")
# 1. 국내
articles_kr = fetch_market_news()
count_kr = save_articles(articles_kr)
# 2. 해외
articles_world = fetch_overseas_news()
count_world = save_articles(articles_world)
print(f"[StockLab] Saved {count_kr} domestic, {count_world} overseas articles.")
@app.get("/health")
def health():
return {"ok": True}
@app.get("/api/stock/news")
@app.get("/api/stock/news")
def get_news(limit: int = 20, category: str = None):
"""최신 주식 뉴스 조회 (category: 'domestic' | 'overseas')"""
return get_latest_articles(limit, category)
@app.get("/api/stock/indices")
def get_indices():
"""주요 지표(KOSPI 등) 실시간 크롤링 조회"""
return fetch_major_indices()
@app.post("/api/stock/scrap")
def trigger_scrap():
"""수동 스크랩 트리거"""
run_scraping_job()
run_scraping_job()
return {"ok": True}
# --- Trading API ---
@app.get("/api/trade/balance")
def get_balance():
"""계좌 잔고 조회 (보유주식 + 예수금)"""
return kis.get_balance()
class OrderRequest(BaseModel):
code: str
qty: int
price: int = 0 # 0이면 시장가
type: str # 'buy' or 'sell'
@app.post("/api/trade/order")
def order_stock(req: OrderRequest):
"""주식 매수/매도 주문"""
if req.type not in ["buy", "sell"]:
return {"success": False, "message": "Invalid type (buy/sell)"}
return kis.order(req.code, req.qty, req.price, req.type)
@app.get("/api/stock/analyze")
def analyze_market():
"""최신 뉴스를 기반으로 AI 시장 요약"""
articles = get_latest_articles(20)
result = analyst.analyze_market_summary(articles)
return {"analysis": result, "model": analyst.model}
@app.get("/api/version")
def version():
return {"version": os.getenv("APP_VERSION", "dev")}